Sort the paths for module specifier by closeness to importing file path

Fixes #32970
This commit is contained in:
Sheetal Nandi 2019-09-23 13:15:40 -07:00
parent 2d62050b8f
commit c67c68e149
2 changed files with 47 additions and 3 deletions

View File

@ -186,6 +186,18 @@ namespace ts.moduleSpecifiers {
return result;
}
function numberOfDirectorySeparators(str: string) {
const match = str.match(/\//g);
return match ? match.length : 0;
}
function comparePathsByNumberOfDirectrorySeparators(a: string, b: string) {
return compareValues(
numberOfDirectorySeparators(a),
numberOfDirectorySeparators(b)
);
}
/**
* Looks for existing imports that use symlinks to this module.
* Symlinks will be returned first so they are preferred over the real path.
@ -214,7 +226,32 @@ namespace ts.moduleSpecifiers {
}
});
result.push(...targets);
return result;
if (result.length < 2) return result;
// Sort by paths closest to importing file Name directory
const allFileNames = arrayToMap(result, identity, getCanonicalFileName);
const sortedPaths: string[] = [];
for (
let directory = getDirectoryPath(toPath(importingFileName, cwd, getCanonicalFileName));
allFileNames.size !== 0;
directory = getDirectoryPath(directory)
) {
const directoryStart = ensureTrailingDirectorySeparator(directory);
let pathsInDirectory: string[] | undefined;
allFileNames.forEach((canonicalFileName, fileName) => {
if (startsWith(canonicalFileName, directoryStart)) {
(pathsInDirectory || (pathsInDirectory = [])).push(fileName);
allFileNames.delete(fileName);
}
});
if (pathsInDirectory) {
if (pathsInDirectory.length > 1) {
pathsInDirectory.sort(comparePathsByNumberOfDirectrorySeparators);
}
sortedPaths.push(...pathsInDirectory);
}
}
return sortedPaths;
}
function tryGetModuleNameFromAmbientModule(moduleSymbol: Symbol): string | undefined {

View File

@ -1,13 +1,20 @@
//// [/lib/initial-buildOutput.txt]
/lib/tsc -p plugin-one --listFiles
plugin-one/action.ts(4,14): error TS2742: The inferred type of 'actions' cannot be named without a reference to 'plugin-two/node_modules/typescript-fsa'. This is likely not portable. A type annotation is necessary.
/lib/lib.d.ts
/plugin-one/node_modules/typescript-fsa/index.d.ts
/plugin-one/action.ts
/plugin-two/node_modules/typescript-fsa/index.d.ts -> /plugin-one/node_modules/typescript-fsa/index.d.ts
/plugin-two/index.d.ts
/plugin-one/index.ts
exitCode:: 1
exitCode:: 0
//// [/plugin-one/action.d.ts]
export declare const actions: {
featureOne: import("typescript-fsa").ActionCreator<{
route: string;
}>;
};
//// [/plugin-one/action.js]