Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Canonicalize path before calling startsWith #25364

Merged
3 commits merged into from
Jul 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/compiler/moduleSpecifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace ts.moduleSpecifiers {
export function getModuleSpecifier(
compilerOptions: CompilerOptions,
importingSourceFile: SourceFile,
importingSourceFileName: string,
importingSourceFileName: Path,
toFileName: string,
host: ModuleSpecifierResolutionHost,
files: ReadonlyArray<SourceFile>,
Expand Down Expand Up @@ -49,10 +49,10 @@ namespace ts.moduleSpecifiers {
readonly moduleResolutionKind: ModuleResolutionKind;
readonly addJsExtension: boolean;
readonly getCanonicalFileName: GetCanonicalFileName;
readonly sourceDirectory: string;
readonly sourceDirectory: Path;
}
// importingSourceFileName is separate because getEditsForFileRename may need to specify an updated path
function getInfo(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: string, host: ModuleSpecifierResolutionHost): Info {
function getInfo(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, host: ModuleSpecifierResolutionHost): Info {
const moduleResolutionKind = getEmitModuleResolutionKind(compilerOptions);
const addJsExtension = usesJsExtensionOnImports(importingSourceFile);
const getCanonicalFileName = createGetCanonicalFileName(host.useCaseSensitiveFileNames ? host.useCaseSensitiveFileNames() : true);
Expand Down Expand Up @@ -271,7 +271,7 @@ namespace ts.moduleSpecifiers {
moduleFileName: string,
host: ModuleSpecifierResolutionHost,
getCanonicalFileName: (file: string) => string,
sourceDirectory: string,
sourceDirectory: Path,
): string | undefined {
if (getEmitModuleResolutionKind(options) !== ModuleResolutionKind.NodeJs) {
// nothing to do here
Expand All @@ -290,7 +290,7 @@ namespace ts.moduleSpecifiers {
const moduleSpecifier = getDirectoryOrExtensionlessFileName(moduleFileName);
// Get a path that's relative to node_modules or the importing file's path
// if node_modules folder is in this folder or any of its parent folders, no need to keep it.
if (!startsWith(sourceDirectory, moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex))) return undefined;
if (!startsWith(sourceDirectory, getCanonicalFileName(moduleSpecifier.substring(0, parts.topLevelNodeModulesIndex)))) return undefined;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dont you need to do getCanonicalFileName for sourceDirectory as well?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That comes from importingSourceFile.path which should already be canonicalized.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. Good that you changed the type there so its easy to catch in future. Thanks.

// If the module was found in @types, get the actual Node package name
return getPackageNameFromAtTypesDirectory(moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1));

Expand Down
7 changes: 5 additions & 2 deletions src/harness/harnessLanguageService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ namespace Harness.LanguageService {
this.vfs.mkdirpSync(ts.getDirectoryPath(newPath));
this.vfs.renameSync(oldPath, newPath);

const updater = ts.getPathUpdater(oldPath, newPath, ts.createGetCanonicalFileName(/*useCaseSensitiveFileNames*/ false));
const updater = ts.getPathUpdater(oldPath, newPath, ts.createGetCanonicalFileName(this.useCaseSensitiveFileNames()));
this.scriptInfos.forEach((scriptInfo, key) => {
const newFileName = updater(key);
if (newFileName !== undefined) {
Expand Down Expand Up @@ -189,6 +189,10 @@ namespace Harness.LanguageService {
assert.isOk(script);
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
}

useCaseSensitiveFileNames() {
return !this.vfs.ignoreCase;
}
}

/// Native adapter
Expand Down Expand Up @@ -251,7 +255,6 @@ namespace Harness.LanguageService {
return 0;
}


log = ts.noop;
trace = ts.noop;
error = ts.noop;
Expand Down
4 changes: 2 additions & 2 deletions src/services/getEditsForFileRename.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,8 @@ namespace ts {
): void {
const allFiles = program.getSourceFiles();
for (const sourceFile of allFiles) {
const newFromOld = oldToNew(sourceFile.fileName);
const newImportFromPath = newFromOld !== undefined ? newFromOld : sourceFile.fileName;
const newFromOld = oldToNew(sourceFile.path) as Path;
const newImportFromPath = newFromOld !== undefined ? newFromOld : sourceFile.path;
const newImportFromDirectory = getDirectoryPath(newImportFromPath);

const oldFromNew: string | undefined = newToOld(sourceFile.fileName);
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9290,7 +9290,7 @@ declare namespace ts.moduleSpecifiers {
interface ModuleSpecifierPreferences {
readonly importModuleSpecifierPreference?: "relative" | "non-relative";
}
function getModuleSpecifier(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: string, toFileName: string, host: ModuleSpecifierResolutionHost, files: ReadonlyArray<SourceFile>, preferences?: ModuleSpecifierPreferences): string;
function getModuleSpecifier(compilerOptions: CompilerOptions, importingSourceFile: SourceFile, importingSourceFileName: Path, toFileName: string, host: ModuleSpecifierResolutionHost, files: ReadonlyArray<SourceFile>, preferences?: ModuleSpecifierPreferences): string;
function getModuleSpecifiers(moduleSymbol: Symbol, compilerOptions: CompilerOptions, importingSourceFile: SourceFile, host: ModuleSpecifierResolutionHost, files: ReadonlyArray<SourceFile>, preferences: ModuleSpecifierPreferences): ReadonlyArray<ReadonlyArray<string>>;
}
declare namespace ts {
Expand Down
16 changes: 16 additions & 0 deletions tests/cases/fourslash/importNameCodeFix_getCanonicalFileName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/// <reference path="fourslash.ts" />

// @Filename: /howNow/node_modules/brownCow/index.d.ts
////export const foo: number;

// @Filename: /howNow/a.ts
////foo;

// Before fixing this bug, we compared a canonicalized `hownow` to a non-canonicalized `howNow`.

goTo.file("/howNow/a.ts");
verify.importFixAtPosition([
`import { foo } from "brownCow";

foo;`,
]);