Canonicalize path before calling startsWith (#25364)

* Canonicalize path before calling `startsWith`

* More specific type for sourceDirectory, and add fourslash test

* Update API (#24966)
This commit is contained in:
Andy 2018-07-03 11:23:19 -07:00 committed by GitHub
parent e8d64a9c7c
commit 304d45d833
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 10 deletions

View file

@ -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>,
@ -48,10 +48,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);
@ -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
@ -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;
// If the module was found in @types, get the actual Node package name
return getPackageNameFromAtTypesDirectory(moduleSpecifier.substring(parts.topLevelPackageNameIndex + 1));

View file

@ -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) {
@ -189,6 +189,10 @@ namespace Harness.LanguageService {
assert.isOk(script);
return ts.computeLineAndCharacterOfPosition(script.getLineMap(), position);
}
useCaseSensitiveFileNames() {
return !this.vfs.ignoreCase;
}
}
/// Native adapter
@ -251,7 +255,6 @@ namespace Harness.LanguageService {
return 0;
}
log = ts.noop;
trace = ts.noop;
error = ts.noop;

View file

@ -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);

View file

@ -9278,7 +9278,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 {

View file

@ -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;`,
]);