Skip to content

Commit 2dcac53

Browse files
author
Andy Hanson
committed
Avoid a symlinked package globally importing itself (fixes another case of #26044)
1 parent d9b285c commit 2dcac53

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

src/compiler/moduleSpecifiers.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ namespace ts.moduleSpecifiers {
1717
redirectTargetsMap: RedirectTargetsMap,
1818
): string {
1919
const info = getInfo(compilerOptions, importingSourceFile, importingSourceFileName, host);
20-
const modulePaths = getAllModulePaths(files, toFileName, info.getCanonicalFileName, host, redirectTargetsMap);
20+
const modulePaths = getAllModulePaths(files, importingSourceFileName, toFileName, info.getCanonicalFileName, host, redirectTargetsMap);
2121
return firstDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions)) ||
2222
first(getLocalModuleSpecifiers(toFileName, info, compilerOptions, preferences));
2323
}
@@ -40,7 +40,7 @@ namespace ts.moduleSpecifiers {
4040
return Debug.fail("Files list must be present to resolve symlinks in specifier resolution");
4141
}
4242
const moduleSourceFile = getSourceFileOfNode(moduleSymbol.valueDeclaration);
43-
const modulePaths = getAllModulePaths(files, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap);
43+
const modulePaths = getAllModulePaths(files, importingSourceFile.path, moduleSourceFile.fileName, info.getCanonicalFileName, host, redirectTargetsMap);
4444

4545
const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions));
4646
return global.length ? global.map(g => [g]) : modulePaths.map(moduleFileName =>
@@ -176,7 +176,7 @@ namespace ts.moduleSpecifiers {
176176
* Looks for existing imports that use symlinks to this module.
177177
* Symlinks will be returned first so they are preferred over the real path.
178178
*/
179-
function getAllModulePaths(files: ReadonlyArray<SourceFile>, importedFileName: string, getCanonicalFileName: (file: string) => string, host: ModuleSpecifierResolutionHost, redirectTargetsMap: RedirectTargetsMap): ReadonlyArray<string> {
179+
function getAllModulePaths(files: ReadonlyArray<SourceFile>, importingFileName: string, importedFileName: string, getCanonicalFileName: GetCanonicalFileName, host: ModuleSpecifierResolutionHost, redirectTargetsMap: RedirectTargetsMap): ReadonlyArray<string> {
180180
const redirects = redirectTargetsMap.get(importedFileName);
181181
const importedFileNames = redirects ? [...redirects, importedFileName] : [importedFileName];
182182
const cwd = host.getCurrentDirectory ? host.getCurrentDirectory() : "";
@@ -186,6 +186,10 @@ namespace ts.moduleSpecifiers {
186186
const result: string[] = [];
187187
const compareStrings = (!host.useCaseSensitiveFileNames || host.useCaseSensitiveFileNames()) ? compareStringsCaseSensitive : compareStringsCaseInsensitive;
188188
links.forEach((resolved, path) => {
189+
if (startsWithDirectory(importingFileName, resolved, getCanonicalFileName)) {
190+
return; // Don't want to a package to globally import from itself
191+
}
192+
189193
const target = targets.find(t => compareStrings(t.slice(0, resolved.length + 1), resolved + "/") === Comparison.EqualTo);
190194
if (target === undefined) return;
191195

src/compiler/utilities.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7157,6 +7157,12 @@ namespace ts {
71577157
return path.slice(0, Math.max(rootLength, path.lastIndexOf(directorySeparator)));
71587158
}
71597159

7160+
export function startsWithDirectory(fileName: string, directoryName: string, getCanonicalFileName: GetCanonicalFileName): boolean {
7161+
const canonicalFileName = getCanonicalFileName(fileName);
7162+
const canonicalDirectoryName = getCanonicalFileName(directoryName);
7163+
return startsWith(canonicalFileName, canonicalDirectoryName + "/") || startsWith(canonicalFileName, canonicalDirectoryName + "\\");
7164+
}
7165+
71607166
export function isUrl(path: string) {
71617167
return getEncodedRootLength(path) < 0;
71627168
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: /packages/a/test.ts
4+
// @Symlink: /node_modules/a/test.ts
5+
////x;
6+
7+
// @Filename: /packages/a/utils.ts
8+
// @Symlink: /node_modules/a/utils.ts
9+
////import {} from "a/utils";
10+
////export const x = 0;
11+
12+
goTo.file("/packages/a/test.ts");
13+
verify.importFixAtPosition([
14+
`import { x } from "./utils";
15+
16+
x;`,
17+
]);

0 commit comments

Comments
 (0)