Skip to content

Commit 304d45d

Browse files
author
Andy
authored
Canonicalize path before calling startsWith (#25364)
* Canonicalize path before calling `startsWith` * More specific type for sourceDirectory, and add fourslash test * Update API (#24966)
1 parent e8d64a9 commit 304d45d

File tree

5 files changed

+29
-10
lines changed

5 files changed

+29
-10
lines changed

src/compiler/moduleSpecifiers.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ts.moduleSpecifiers {
99
export function getModuleSpecifier(
1010
compilerOptions: CompilerOptions,
1111
importingSourceFile: SourceFile,
12-
importingSourceFileName: string,
12+
importingSourceFileName: Path,
1313
toFileName: string,
1414
host: ModuleSpecifierResolutionHost,
1515
files: ReadonlyArray<SourceFile>,
@@ -48,10 +48,10 @@ namespace ts.moduleSpecifiers {
4848
readonly moduleResolutionKind: ModuleResolutionKind;
4949
readonly addJsExtension: boolean;
5050
readonly getCanonicalFileName: GetCanonicalFileName;
51-
readonly sourceDirectory: string;
51+
readonly sourceDirectory: Path;
5252
}
5353
// importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path
54-
function getInfo(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: string, host: ModuleSpecifierResolutionHost): Info {
54+
function getInfo(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Info {
5555
const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions);
5656
const addJsExtension = usesJsExtensionOnImports(importingSourceFile);
5757
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true);
@@ -271,7 +271,7 @@ namespace ts.moduleSpecifiers {
271271
moduleFileName: string,
272272
host: ModuleSpecifierResolutionHost,
273273
getCanonicalFileName: (file: string) => string,
274-
sourceDirectory: string,
274+
sourceDirectory: Path,
275275
): string | undefined {
276276
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
277277
// nothing to do here
@@ -290,7 +290,7 @@ namespace ts.moduleSpecifiers {
290290
const moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName);
291291
// Get a path that's relative to node_modules or the importing file's path
292292
// if node_modules folder is in this folder or any of its parent folders, no need to keep it.
293-
if (!startsWith(sourceDirectory, moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex))) return undefined;
293+
if (!startsWith(sourceDirectory, getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex)))) return undefined;
294294
// If the module was found in @types, get the actual Node package name
295295
return getPackageNameFromAtTypesDirectory(moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1));
296296

src/harness/harnessLanguageService.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ namespace Harness.LanguageService {
155155
this.vfs.mkdirpSync(ts.getDirectoryPath(newPath));
156156
this.vfs.renameSync(oldPath, newPath);
157157

158-
const updater = ts.getPathUpdater(oldPath, newPath, ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false));
158+
const updater = ts.getPathUpdater(oldPath, newPath, ts.createGetCanonicalFileName(this.useCaseSensitiveFileNames()));
159159
this.scriptInfos.forEach((scriptInfo, key) => {
160160
const newFileName = updater(key);
161161
if (newFileName !== undefined) {
@@ -189,6 +189,10 @@ namespace Harness.LanguageService {
189189
assert.isOk(script);
190190
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
191191
}
192+
193+
useCaseSensitiveFileNames() {
194+
return !this.vfs.ignoreCase;
195+
}
192196
}
193197

194198
/// Native adapter
@@ -251,7 +255,6 @@ namespace Harness.LanguageService {
251255
return 0;
252256
}
253257

254-
255258
log = ts.noop;
256259
trace = ts.noop;
257260
error = ts.noop;

src/services/getEditsForFileRename.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ namespace ts {
104104
): void {
105105
const allFiles = program.getSourceFiles();
106106
for (const sourceFile of allFiles) {
107-
const newFromOld = oldToNew(sourceFile.fileName);
108-
const newImportFromPath = newFromOld !== undefined ? newFromOld : sourceFile.fileName;
107+
const newFromOld = oldToNew(sourceFile.path) as Path;
108+
const newImportFromPath = newFromOld !== undefined ? newFromOld : sourceFile.path;
109109
const newImportFromDirectory = getDirectoryPath(newImportFromPath);
110110

111111
const oldFromNew: string | undefined = newToOld(sourceFile.fileName);

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9278,7 +9278,7 @@ declare namespace ts.moduleSpecifiers {
92789278
interface ModuleSpecifierPreferences {
92799279
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
92809280
}
9281-
function getModuleSpecifier(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: string, toFileName: string, host: ModuleSpecifierResolutionHost, files: ReadonlyArray<SourceFile>, preferences?: ModuleSpecifierPreferences): string;
9281+
function getModuleSpecifier(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, toFileName: string, host: ModuleSpecifierResolutionHost, files: ReadonlyArray<SourceFile>, preferences?: ModuleSpecifierPreferences): string;
92829282
function getModuleSpecifiers(moduleSymbol: Symbol, compilerOptions: CompilerOptions, importingSourceFile: SourceFile, host: ModuleSpecifierResolutionHost, files: ReadonlyArray<SourceFile>, preferences: ModuleSpecifierPreferences): ReadonlyArray<ReadonlyArray<string>>;
92839283
}
92849284
declare namespace ts {
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: /howNow/node_modules/brownCow/index.d.ts
4+
////export const foo: number;
5+
6+
// @Filename: /howNow/a.ts
7+
////foo;
8+
9+
// Before fixing this bug, we compared a canonicalized `hownow` to a non-canonicalized `howNow`.
10+
11+
goTo.file("/howNow/a.ts");
12+
verify.importFixAtPosition([
13+
`import { foo } from "brownCow";
14+
15+
foo;`,
16+
]);

0 commit comments

Comments
 (0)