Skip to content

Commit 7a1d75c

Browse files
author
Andy
authored
getEditsForFileRename: Don't update unrelated import (#24961)
* getEditsForFileRename: Don't update unrelated import * Importing source file moved if it's the old path *or* new path
1 parent 4a7a550 commit 7a1d75c

File tree

2 files changed

+24
-7
lines changed

2 files changed

+24
-7
lines changed

src/services/getEditsForFileRename.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,16 @@ namespace ts {
103103
preferences: UserPreferences,
104104
): void {
105105
for (const sourceFile of program.getSourceFiles()) {
106-
const newImportFromPath = oldToNew(sourceFile.fileName) || sourceFile.fileName;
106+
const newFromOld = oldToNew(sourceFile.fileName);
107+
const newImportFromPath = newFromOld !== undefined ? newFromOld : sourceFile.fileName;
107108
const newImportFromDirectory = getDirectoryPath(newImportFromPath);
108109

109110
const oldFromNew: string | undefined = newToOld(sourceFile.fileName);
110111
const oldImportFromPath: string = oldFromNew || sourceFile.fileName;
111112
const oldImportFromDirectory = getDirectoryPath(oldImportFromPath);
112113

114+
const importingSourceFileMoved = newFromOld !== undefined || oldFromNew !== undefined;
115+
113116
updateImportsWorker(sourceFile, changeTracker,
114117
referenceText => {
115118
if (!pathIsRelative(referenceText)) return undefined;
@@ -123,7 +126,10 @@ namespace ts {
123126
// TODO:GH#18217
124127
? getSourceFileToImportFromResolved(resolveModuleName(importLiteral.text, oldImportFromPath, program.getCompilerOptions(), host as ModuleResolutionHost), oldToNew, program)
125128
: getSourceFileToImport(importLiteral, sourceFile, program, host, oldToNew);
126-
return toImport === undefined ? undefined : moduleSpecifiers.getModuleSpecifier(program.getCompilerOptions(), sourceFile, newImportFromPath, toImport, host, preferences);
129+
// If neither the importing source file nor the imported file moved, do nothing.
130+
return toImport === undefined || !toImport.updated && !importingSourceFileMoved
131+
? undefined
132+
: moduleSpecifiers.getModuleSpecifier(program.getCompilerOptions(), sourceFile, newImportFromPath, toImport.newFileName, host, preferences);
127133
});
128134
}
129135
}
@@ -135,12 +141,18 @@ namespace ts {
135141
return ensurePathIsNonModuleName(combineNormal(pathA, pathB));
136142
}
137143

138-
function getSourceFileToImport(importLiteral: StringLiteralLike, importingSourceFile: SourceFile, program: Program, host: LanguageServiceHost, oldToNew: PathUpdater): string | undefined {
144+
interface ToImport {
145+
readonly newFileName: string;
146+
/** True if the imported file was renamed. */
147+
readonly updated: boolean;
148+
}
149+
function getSourceFileToImport(importLiteral: StringLiteralLike, importingSourceFile: SourceFile, program: Program, host: LanguageServiceHost, oldToNew: PathUpdater): ToImport | undefined {
139150
const symbol = program.getTypeChecker().getSymbolAtLocation(importLiteral);
140151
if (symbol) {
141152
if (symbol.declarations.some(d => isAmbientModule(d))) return undefined; // No need to update if it's an ambient module
142153
const oldFileName = find(symbol.declarations, isSourceFile)!.fileName;
143-
return oldToNew(oldFileName) || oldFileName;
154+
const newFileName = oldToNew(oldFileName);
155+
return newFileName === undefined ? { newFileName: oldFileName, updated: false } : { newFileName, updated: true };
144156
}
145157
else {
146158
const resolved = host.resolveModuleNames
@@ -150,14 +162,15 @@ namespace ts {
150162
}
151163
}
152164

153-
function getSourceFileToImportFromResolved(resolved: ResolvedModuleWithFailedLookupLocations | undefined, oldToNew: PathUpdater, program: Program): string | undefined {
165+
function getSourceFileToImportFromResolved(resolved: ResolvedModuleWithFailedLookupLocations | undefined, oldToNew: PathUpdater, program: Program): ToImport | undefined {
154166
return resolved && (
155167
(resolved.resolvedModule && getIfInProgram(resolved.resolvedModule.resolvedFileName)) || firstDefined(resolved.failedLookupLocations, getIfInProgram));
156168

157-
function getIfInProgram(oldLocation: string): string | undefined {
169+
function getIfInProgram(oldLocation: string): ToImport | undefined {
158170
const newLocation = oldToNew(oldLocation);
171+
159172
return program.getSourceFile(oldLocation) || newLocation !== undefined && program.getSourceFile(newLocation)
160-
? newLocation || oldLocation
173+
? newLocation !== undefined ? { newFileName: newLocation, updated: true } : { newFileName: oldLocation, updated: false }
161174
: undefined;
162175
}
163176
}

tests/cases/fourslash/getEditsForFileRename.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
/////// <reference path="../old.ts" />
1515
////import old from "../old";
1616

17+
// @Filename: /unrelated.ts
18+
// Don't update an unrelated import
19+
////import { x } from "././src/./foo/./a";
20+
1721
// @Filename: /src/new.ts
1822
////
1923

0 commit comments

Comments
 (0)