From ee7d0e21dad5ea53be7170e06a8636a19c0d8d6d Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 13 Sep 2018 15:49:42 -0700 Subject: [PATCH] getEditsForFileRename: Don't resolve to `a.js` when `a.ts` is moved (#27081) --- src/services/getEditsForFileRename.ts | 22 +++++++++++++------ ...tEditsForFileRename_notAffectedByJsFile.ts | 18 +++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 tests/cases/fourslash/getEditsForFileRename_notAffectedByJsFile.ts diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 07c3eb7ad22..a18fab4766f 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -196,15 +196,23 @@ namespace ts { } function getSourceFileToImportFromResolved(resolved: ResolvedModuleWithFailedLookupLocations | undefined, oldToNew: PathUpdater, host: LanguageServiceHost): ToImport | undefined { - return resolved && ( - (resolved.resolvedModule && getIfExists(resolved.resolvedModule.resolvedFileName)) || firstDefined(resolved.failedLookupLocations, getIfExists)); + // Search through all locations looking for a moved file, and only then test already existing files. + // This is because if `a.ts` is compiled to `a.js` and `a.ts` is moved, we don't want to resolve anything to `a.js`, but to `a.ts`'s new location. + return tryEach(tryGetNewFile) || tryEach(tryGetOldFile); - function getIfExists(oldLocation: string): ToImport | undefined { - const newLocation = oldToNew(oldLocation); + function tryEach(cb: (oldFileName: string) => ToImport | undefined): ToImport | undefined { + return resolved && ( + (resolved.resolvedModule && cb(resolved.resolvedModule.resolvedFileName)) || firstDefined(resolved.failedLookupLocations, cb)); + } - return host.fileExists!(oldLocation) || newLocation !== undefined && host.fileExists!(newLocation) // TODO: GH#18217 - ? newLocation !== undefined ? { newFileName: newLocation, updated: true } : { newFileName: oldLocation, updated: false } - : undefined; + function tryGetNewFile(oldFileName: string): ToImport | undefined { + const newFileName = oldToNew(oldFileName); + return newFileName !== undefined && host.fileExists!(newFileName) ? { newFileName, updated: true } : undefined; // TODO: GH#18217 + } + + function tryGetOldFile(oldFileName: string): ToImport | undefined { + const newFileName = oldToNew(oldFileName); + return host.fileExists!(oldFileName) ? newFileName !== undefined ? { newFileName, updated: true } : { newFileName: oldFileName, updated: false } : undefined; // TODO: GH#18217 } } diff --git a/tests/cases/fourslash/getEditsForFileRename_notAffectedByJsFile.ts b/tests/cases/fourslash/getEditsForFileRename_notAffectedByJsFile.ts new file mode 100644 index 00000000000..f1b1497f2ef --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_notAffectedByJsFile.ts @@ -0,0 +1,18 @@ +/// + +// @Filename: /a.ts +////export const x = 0; + +// @Filename: /a.js +////exports.x = 0; + +// @Filename: /b.ts +////import { x } from "./a"; + +verify.getEditsForFileRename({ + oldPath: "/a.ts", + newPath: "/a2.ts", + newFileContents: { + "/b.ts": 'import { x } from "./a2";', + }, +});