Skip to content

Commit a770688

Browse files
authored
Handle combinations of rootdir and outdir when calculating paths (#24941)
1 parent 3261473 commit a770688

5 files changed

+243
-9
lines changed

src/compiler/moduleSpecifiers.ts

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,16 @@ namespace ts.moduleSpecifiers {
133133
return firstDefined(imports, ({ text }) => pathIsRelative(text) ? fileExtensionIs(text, Extension.Js) : undefined) || false;
134134
}
135135

136-
function discoverProbableSymlinks(files: ReadonlyArray<SourceFile>) {
136+
function discoverProbableSymlinks(files: ReadonlyArray<SourceFile>, getCanonicalFileName: (file: string) => string, host: ModuleSpecifierResolutionHost) {
137137
const symlinks = mapDefined(files, sf =>
138138
sf.resolvedModules && firstDefinedIterator(sf.resolvedModules.values(), res =>
139139
res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined));
140140
const result = createMap<string>();
141141
if (symlinks) {
142+
const currentDirectory = host.getCurrentDirectory ? host.getCurrentDirectory() : "";
142143
for (const [resolvedPath, originalPath] of symlinks) {
143-
const resolvedParts = getPathComponents(resolvedPath);
144-
const originalParts = getPathComponents(originalPath);
144+
const resolvedParts = getPathComponents(toPath(resolvedPath, currentDirectory, getCanonicalFileName));
145+
const originalParts = getPathComponents(toPath(originalPath, currentDirectory, getCanonicalFileName));
145146
while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) {
146147
resolvedParts.pop();
147148
originalParts.pop();
@@ -153,12 +154,13 @@ namespace ts.moduleSpecifiers {
153154
}
154155

155156
function getAllModulePathsUsingIndirectSymlinks(files: ReadonlyArray<SourceFile>, target: string, getCanonicalFileName: (file: string) => string, host: ModuleSpecifierResolutionHost) {
156-
const links = discoverProbableSymlinks(files);
157+
const links = discoverProbableSymlinks(files, getCanonicalFileName, host);
157158
const paths = arrayFrom(links.keys());
158159
let options: string[] | undefined;
160+
const compareStrings = (!host.useCaseSensitiveFileNames || host.useCaseSensitiveFileNames()) ? compareStringsCaseSensitive : compareStringsCaseInsensitive;
159161
for (const path of paths) {
160162
const resolved = links.get(path)!;
161-
if (startsWith(target, resolved + "/")) {
163+
if (compareStrings(target.slice(0, resolved.length + 1), resolved + "/") === Comparison.EqualTo) {
162164
const relative = getRelativePathFromDirectory(resolved, target, getCanonicalFileName);
163165
const option = resolvePath(path, relative);
164166
if (!host.fileExists || host.fileExists(option)) {
@@ -167,12 +169,11 @@ namespace ts.moduleSpecifiers {
167169
}
168170
}
169171
}
170-
const resolvedtarget = host.getCurrentDirectory ? resolvePath(host.getCurrentDirectory(), target) : target;
171172
if (options) {
172-
options.push(resolvedtarget); // Since these are speculative, we also include the original resolved name as a possibility
173+
options.push(target); // Since these are speculative, we also include the original resolved name as a possibility
173174
return options;
174175
}
175-
return [resolvedtarget];
176+
return [target];
176177
}
177178

178179
/**
@@ -183,7 +184,7 @@ namespace ts.moduleSpecifiers {
183184
const symlinks = mapDefined(files, sf =>
184185
sf.resolvedModules && firstDefinedIterator(sf.resolvedModules.values(), res =>
185186
res && res.resolvedFileName === fileName ? res.originalPath : undefined));
186-
return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, fileName, getCanonicalFileName, host) : symlinks;
187+
return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, getNormalizedAbsolutePath(fileName, host.getCurrentDirectory ? host.getCurrentDirectory() : ""), getCanonicalFileName, host) : symlinks;
187188
}
188189

189190
function getRelativePathNParents(relativePath: string): number {
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
//// [tests/cases/compiler/symbolLinkDeclarationEmitModuleNamesRootDir.ts] ////
2+
3+
//// [value-promise.d.ts]
4+
export type Constructor<T> = (...args: any[]) => T;
5+
//// [bindingkey.d.ts]
6+
import { Constructor } from "./value-promise"
7+
export declare class BindingKey<T> {
8+
readonly __type: T;
9+
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
10+
}
11+
12+
//// [index.d.ts]
13+
export * from "./src/value-promise";
14+
export * from "./src/bindingkey";
15+
16+
//// [application.ts]
17+
import { Constructor } from "@loopback/context";
18+
export type ControllerClass = Constructor<any>;
19+
20+
//// [usage.ts]
21+
import { ControllerClass } from './application';
22+
import { BindingKey } from '@loopback/context';
23+
24+
export const CONTROLLER_CLASS = BindingKey.create<ControllerClass>(null as any); // line in question
25+
26+
27+
//// [application.js]
28+
"use strict";
29+
exports.__esModule = true;
30+
//// [usage.js]
31+
"use strict";
32+
exports.__esModule = true;
33+
var context_1 = require("@loopback/context");
34+
exports.CONTROLLER_CLASS = context_1.BindingKey.create(null); // line in question
35+
36+
37+
//// [application.d.ts]
38+
import { Constructor } from "@loopback/context";
39+
export declare type ControllerClass = Constructor<any>;
40+
//// [usage.d.ts]
41+
import { BindingKey } from '@loopback/context';
42+
export declare const CONTROLLER_CLASS: BindingKey<import("@loopback/context/src/value-promise").Constructor<any>>;
43+
44+
45+
//// [DtsFileErrors]
46+
47+
48+
tests/cases/compiler/monorepo/core/dist/src/application.d.ts(1,29): error TS2307: Cannot find module '@loopback/context'.
49+
tests/cases/compiler/monorepo/core/dist/src/usage.d.ts(1,28): error TS2307: Cannot find module '@loopback/context'.
50+
tests/cases/compiler/monorepo/core/dist/src/usage.d.ts(2,51): error TS2307: Cannot find module '@loopback/context/src/value-promise'.
51+
52+
53+
==== tests/cases/compiler/monorepo/core/tsconfig.json (0 errors) ====
54+
{
55+
"compilerOptions": {
56+
"rootDir": ".",
57+
"declaration": true,
58+
"outDir": "./dist"
59+
}
60+
}
61+
==== tests/cases/compiler/monorepo/context/src/value-promise.d.ts (0 errors) ====
62+
export type Constructor<T> = (...args: any[]) => T;
63+
==== tests/cases/compiler/monorepo/context/src/bindingkey.d.ts (0 errors) ====
64+
import { Constructor } from "./value-promise"
65+
export declare class BindingKey<T> {
66+
readonly __type: T;
67+
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
68+
}
69+
70+
==== tests/cases/compiler/monorepo/context/index.d.ts (0 errors) ====
71+
export * from "./src/value-promise";
72+
export * from "./src/bindingkey";
73+
74+
==== tests/cases/compiler/monorepo/core/dist/src/application.d.ts (1 errors) ====
75+
import { Constructor } from "@loopback/context";
76+
~~~~~~~~~~~~~~~~~~~
77+
!!! error TS2307: Cannot find module '@loopback/context'.
78+
export declare type ControllerClass = Constructor<any>;
79+
80+
==== tests/cases/compiler/monorepo/core/dist/src/usage.d.ts (2 errors) ====
81+
import { BindingKey } from '@loopback/context';
82+
~~~~~~~~~~~~~~~~~~~
83+
!!! error TS2307: Cannot find module '@loopback/context'.
84+
export declare const CONTROLLER_CLASS: BindingKey<import("@loopback/context/src/value-promise").Constructor<any>>;
85+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
86+
!!! error TS2307: Cannot find module '@loopback/context/src/value-promise'.
87+
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
=== tests/cases/compiler/monorepo/context/src/value-promise.d.ts ===
2+
export type Constructor<T> = (...args: any[]) => T;
3+
>Constructor : Symbol(Constructor, Decl(value-promise.d.ts, 0, 0))
4+
>T : Symbol(T, Decl(value-promise.d.ts, 0, 24))
5+
>args : Symbol(args, Decl(value-promise.d.ts, 0, 30))
6+
>T : Symbol(T, Decl(value-promise.d.ts, 0, 24))
7+
8+
=== tests/cases/compiler/monorepo/context/src/bindingkey.d.ts ===
9+
import { Constructor } from "./value-promise"
10+
>Constructor : Symbol(Constructor, Decl(bindingkey.d.ts, 0, 8))
11+
12+
export declare class BindingKey<T> {
13+
>BindingKey : Symbol(BindingKey, Decl(bindingkey.d.ts, 0, 45))
14+
>T : Symbol(T, Decl(bindingkey.d.ts, 1, 32))
15+
16+
readonly __type: T;
17+
>__type : Symbol(BindingKey.__type, Decl(bindingkey.d.ts, 1, 36))
18+
>T : Symbol(T, Decl(bindingkey.d.ts, 1, 32))
19+
20+
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
21+
>create : Symbol(BindingKey.create, Decl(bindingkey.d.ts, 2, 21))
22+
>T : Symbol(T, Decl(bindingkey.d.ts, 3, 16))
23+
>Constructor : Symbol(Constructor, Decl(bindingkey.d.ts, 0, 8))
24+
>ctor : Symbol(ctor, Decl(bindingkey.d.ts, 3, 44))
25+
>T : Symbol(T, Decl(bindingkey.d.ts, 3, 16))
26+
>BindingKey : Symbol(BindingKey, Decl(bindingkey.d.ts, 0, 45))
27+
>T : Symbol(T, Decl(bindingkey.d.ts, 3, 16))
28+
}
29+
30+
=== tests/cases/compiler/monorepo/context/index.d.ts ===
31+
export * from "./src/value-promise";
32+
No type information for this code.export * from "./src/bindingkey";
33+
No type information for this code.
34+
No type information for this code.=== tests/cases/compiler/monorepo/core/src/application.ts ===
35+
import { Constructor } from "@loopback/context";
36+
>Constructor : Symbol(Constructor, Decl(application.ts, 0, 8))
37+
38+
export type ControllerClass = Constructor<any>;
39+
>ControllerClass : Symbol(ControllerClass, Decl(application.ts, 0, 48))
40+
>Constructor : Symbol(Constructor, Decl(application.ts, 0, 8))
41+
42+
=== tests/cases/compiler/monorepo/core/src/usage.ts ===
43+
import { ControllerClass } from './application';
44+
>ControllerClass : Symbol(ControllerClass, Decl(usage.ts, 0, 8))
45+
46+
import { BindingKey } from '@loopback/context';
47+
>BindingKey : Symbol(BindingKey, Decl(usage.ts, 1, 8))
48+
49+
export const CONTROLLER_CLASS = BindingKey.create<ControllerClass>(null as any); // line in question
50+
>CONTROLLER_CLASS : Symbol(CONTROLLER_CLASS, Decl(usage.ts, 3, 12))
51+
>BindingKey.create : Symbol(BindingKey.create, Decl(bindingkey.d.ts, 2, 21))
52+
>BindingKey : Symbol(BindingKey, Decl(usage.ts, 1, 8))
53+
>create : Symbol(BindingKey.create, Decl(bindingkey.d.ts, 2, 21))
54+
>ControllerClass : Symbol(ControllerClass, Decl(usage.ts, 0, 8))
55+
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=== tests/cases/compiler/monorepo/context/src/value-promise.d.ts ===
2+
export type Constructor<T> = (...args: any[]) => T;
3+
>Constructor : Constructor<T>
4+
>T : T
5+
>args : any[]
6+
>T : T
7+
8+
=== tests/cases/compiler/monorepo/context/src/bindingkey.d.ts ===
9+
import { Constructor } from "./value-promise"
10+
>Constructor : any
11+
12+
export declare class BindingKey<T> {
13+
>BindingKey : BindingKey<T>
14+
>T : T
15+
16+
readonly __type: T;
17+
>__type : T
18+
>T : T
19+
20+
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
21+
>create : <T extends Constructor<any>>(ctor: T) => BindingKey<T>
22+
>T : T
23+
>Constructor : Constructor<T>
24+
>ctor : T
25+
>T : T
26+
>BindingKey : BindingKey<T>
27+
>T : T
28+
}
29+
30+
=== tests/cases/compiler/monorepo/context/index.d.ts ===
31+
export * from "./src/value-promise";
32+
No type information for this code.export * from "./src/bindingkey";
33+
No type information for this code.
34+
No type information for this code.=== tests/cases/compiler/monorepo/core/src/application.ts ===
35+
import { Constructor } from "@loopback/context";
36+
>Constructor : any
37+
38+
export type ControllerClass = Constructor<any>;
39+
>ControllerClass : Constructor<any>
40+
>Constructor : Constructor<T>
41+
42+
=== tests/cases/compiler/monorepo/core/src/usage.ts ===
43+
import { ControllerClass } from './application';
44+
>ControllerClass : any
45+
46+
import { BindingKey } from '@loopback/context';
47+
>BindingKey : typeof BindingKey
48+
49+
export const CONTROLLER_CLASS = BindingKey.create<ControllerClass>(null as any); // line in question
50+
>CONTROLLER_CLASS : BindingKey<import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>>
51+
>BindingKey.create<ControllerClass>(null as any) : BindingKey<import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>>
52+
>BindingKey.create : <T extends import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>>(ctor: T) => BindingKey<T>
53+
>BindingKey : typeof BindingKey
54+
>create : <T extends import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>>(ctor: T) => BindingKey<T>
55+
>ControllerClass : import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>
56+
>null as any : any
57+
>null : null
58+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// @currentDirectory: monorepo/core
2+
// @filename: monorepo/context/src/value-promise.d.ts
3+
export type Constructor<T> = (...args: any[]) => T;
4+
// @filename: monorepo/context/src/bindingkey.d.ts
5+
import { Constructor } from "./value-promise"
6+
export declare class BindingKey<T> {
7+
readonly __type: T;
8+
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
9+
}
10+
11+
// @filename: monorepo/context/index.d.ts
12+
export * from "./src/value-promise";
13+
export * from "./src/bindingkey";
14+
15+
// @filename: monorepo/core/tsconfig.json
16+
{
17+
"compilerOptions": {
18+
"rootDir": ".",
19+
"declaration": true,
20+
"outDir": "./dist"
21+
}
22+
}
23+
// @filename: monorepo/core/src/application.ts
24+
import { Constructor } from "@loopback/context";
25+
export type ControllerClass = Constructor<any>;
26+
27+
// @filename: monorepo/core/src/usage.ts
28+
import { ControllerClass } from './application';
29+
import { BindingKey } from '@loopback/context';
30+
31+
export const CONTROLLER_CLASS = BindingKey.create<ControllerClass>(null as any); // line in question
32+
33+
// @link: tests/cases/compiler/monorepo/context -> tests/cases/compiler/monorepo/core/node_modules/@loopback/context

0 commit comments

Comments
 (0)