From 77ec756960eeaa2931a05cc4f6a3a66e3578320d Mon Sep 17 00:00:00 2001 From: Eli Barzilay Date: Wed, 20 Nov 2019 09:34:17 -0500 Subject: [PATCH] Make `getSourceFileToImportFromResolved` prefer files in `program.getSourceFiles()` Fixes #30550 --- src/services/getEditsForFileRename.ts | 19 ++++++++++++++----- .../getEditsForFileRename_js_simple.ts | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 tests/cases/fourslash/getEditsForFileRename_js_simple.ts diff --git a/src/services/getEditsForFileRename.ts b/src/services/getEditsForFileRename.ts index 9ab8410f51a..ffce22e3a30 100644 --- a/src/services/getEditsForFileRename.ts +++ b/src/services/getEditsForFileRename.ts @@ -151,7 +151,8 @@ namespace ts { const toImport = oldFromNew !== undefined // If we're at the new location (file was already renamed), need to redo module resolution starting from the old location. // TODO:GH#18217 - ? getSourceFileToImportFromResolved(resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host as ModuleResolutionHost), oldToNew) + ? getSourceFileToImportFromResolved(resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host as ModuleResolutionHost), + oldToNew, allFiles) : getSourceFileToImport(importedModuleSymbol, importLiteral, sourceFile, program, host, oldToNew); // Need an update if the imported file moved, or the importing file moved and was using a relative path. @@ -192,11 +193,11 @@ namespace ts { const resolved = host.resolveModuleNames ? host.getResolvedModuleWithFailedLookupLocationsFromCache && host.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName) : program.getResolvedModuleWithFailedLookupLocationsFromCache(importLiteral.text, importingSourceFile.fileName); - return getSourceFileToImportFromResolved(resolved, oldToNew); + return getSourceFileToImportFromResolved(resolved, oldToNew, program.getSourceFiles()); } } - function getSourceFileToImportFromResolved(resolved: ResolvedModuleWithFailedLookupLocations | undefined, oldToNew: PathUpdater): ToImport | undefined { + function getSourceFileToImportFromResolved(resolved: ResolvedModuleWithFailedLookupLocations | undefined, oldToNew: PathUpdater, sourceFiles: readonly SourceFile[]): ToImport | undefined { // 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. if (!resolved) return undefined; @@ -207,13 +208,21 @@ namespace ts { if (result) return result; } - // Then failed lookups except package.json since we dont want to touch them (only included ts/js files) - const result = forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJson); + // Then failed lookups that are in the list of sources + const result = forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJsonExisting) + // Then failed lookups except package.json since we dont want to touch them (only included ts/js files) + || forEach(resolved.failedLookupLocations, tryChangeWithIgnoringPackageJson); if (result) return result; // If nothing changed, then result is resolved module file thats not updated return resolved.resolvedModule && { newFileName: resolved.resolvedModule.resolvedFileName, updated: false }; + function tryChangeWithIgnoringPackageJsonExisting(oldFileName: string) { + const newFileName = oldToNew(oldFileName); + return newFileName && find(sourceFiles, src => src.fileName === newFileName) + ? tryChangeWithIgnoringPackageJson(oldFileName) : undefined; + } + function tryChangeWithIgnoringPackageJson(oldFileName: string) { return !endsWith(oldFileName, "/package.json") ? tryChange(oldFileName) : undefined; } diff --git a/tests/cases/fourslash/getEditsForFileRename_js_simple.ts b/tests/cases/fourslash/getEditsForFileRename_js_simple.ts new file mode 100644 index 00000000000..bd962fce7fb --- /dev/null +++ b/tests/cases/fourslash/getEditsForFileRename_js_simple.ts @@ -0,0 +1,17 @@ +/// + +// @allowJs: true + +// @Filename: /a.js +////import b from "./b.js"; + +// @Filename: /b.js +////module.exports = 1; + +verify.getEditsForFileRename({ + oldPath: "/b.js", + newPath: "/c.js", + newFileContents: { + "/a.js": `import b from "./c.js";`, + }, +});