Handle combinations of rootdir and outdir when calculating paths (#24941)

This commit is contained in:
Wesley Wigham
2018-06-14 11:07:46 -07:00
committed by GitHub
parent 3261473a9b
commit a77068827d
5 changed files with 243 additions and 9 deletions

View File

@@ -133,15 +133,16 @@ namespace ts.moduleSpecifiers {
return firstDefined(imports, ({ text }) => pathIsRelative(text) ? fileExtensionIs(text, Extension.Js) : undefined) || false;
}
function discoverProbableSymlinks(files: ReadonlyArray<SourceFile>) {
function discoverProbableSymlinks(files: ReadonlyArray<SourceFile>, getCanonicalFileName: (file: string) => string, host: ModuleSpecifierResolutionHost) {
const symlinks = mapDefined(files, sf =>
sf.resolvedModules && firstDefinedIterator(sf.resolvedModules.values(), res =>
res && res.originalPath && res.resolvedFileName !== res.originalPath ? [res.resolvedFileName, res.originalPath] : undefined));
const result = createMap<string>();
if (symlinks) {
const currentDirectory = host.getCurrentDirectory ? host.getCurrentDirectory() : "";
for (const [resolvedPath, originalPath] of symlinks) {
const resolvedParts = getPathComponents(resolvedPath);
const originalParts = getPathComponents(originalPath);
const resolvedParts = getPathComponents(toPath(resolvedPath, currentDirectory, getCanonicalFileName));
const originalParts = getPathComponents(toPath(originalPath, currentDirectory, getCanonicalFileName));
while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) {
resolvedParts.pop();
originalParts.pop();
@@ -153,12 +154,13 @@ namespace ts.moduleSpecifiers {
}
function getAllModulePathsUsingIndirectSymlinks(files: ReadonlyArray<SourceFile>, target: string, getCanonicalFileName: (file: string) => string, host: ModuleSpecifierResolutionHost) {
const links = discoverProbableSymlinks(files);
const links = discoverProbableSymlinks(files, getCanonicalFileName, host);
const paths = arrayFrom(links.keys());
let options: string[] | undefined;
const compareStrings = (!host.useCaseSensitiveFileNames || host.useCaseSensitiveFileNames()) ? compareStringsCaseSensitive : compareStringsCaseInsensitive;
for (const path of paths) {
const resolved = links.get(path)!;
if (startsWith(target, resolved + "/")) {
if (compareStrings(target.slice(0, resolved.length + 1), resolved + "/") === Comparison.EqualTo) {
const relative = getRelativePathFromDirectory(resolved, target, getCanonicalFileName);
const option = resolvePath(path, relative);
if (!host.fileExists || host.fileExists(option)) {
@@ -167,12 +169,11 @@ namespace ts.moduleSpecifiers {
}
}
}
const resolvedtarget = host.getCurrentDirectory ? resolvePath(host.getCurrentDirectory(), target) : target;
if (options) {
options.push(resolvedtarget); // Since these are speculative, we also include the original resolved name as a possibility
options.push(target); // Since these are speculative, we also include the original resolved name as a possibility
return options;
}
return [resolvedtarget];
return [target];
}
/**
@@ -183,7 +184,7 @@ namespace ts.moduleSpecifiers {
const symlinks = mapDefined(files, sf =>
sf.resolvedModules && firstDefinedIterator(sf.resolvedModules.values(), res =>
res && res.resolvedFileName === fileName ? res.originalPath : undefined));
return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, fileName, getCanonicalFileName, host) : symlinks;
return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, getNormalizedAbsolutePath(fileName, host.getCurrentDirectory ? host.getCurrentDirectory() : ""), getCanonicalFileName, host) : symlinks;
}
function getRelativePathNParents(relativePath: string): number {

View File

@@ -0,0 +1,87 @@
//// [tests/cases/compiler/symbolLinkDeclarationEmitModuleNamesRootDir.ts] ////
//// [value-promise.d.ts]
export type Constructor<T> = (...args: any[]) => T;
//// [bindingkey.d.ts]
import { Constructor } from "./value-promise"
export declare class BindingKey<T> {
readonly __type: T;
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
}
//// [index.d.ts]
export * from "./src/value-promise";
export * from "./src/bindingkey";
//// [application.ts]
import { Constructor } from "@loopback/context";
export type ControllerClass = Constructor<any>;
//// [usage.ts]
import { ControllerClass } from './application';
import { BindingKey } from '@loopback/context';
export const CONTROLLER_CLASS = BindingKey.create<ControllerClass>(null as any); // line in question
//// [application.js]
"use strict";
exports.__esModule = true;
//// [usage.js]
"use strict";
exports.__esModule = true;
var context_1 = require("@loopback/context");
exports.CONTROLLER_CLASS = context_1.BindingKey.create(null); // line in question
//// [application.d.ts]
import { Constructor } from "@loopback/context";
export declare type ControllerClass = Constructor<any>;
//// [usage.d.ts]
import { BindingKey } from '@loopback/context';
export declare const CONTROLLER_CLASS: BindingKey<import("@loopback/context/src/value-promise").Constructor<any>>;
//// [DtsFileErrors]
tests/cases/compiler/monorepo/core/dist/src/application.d.ts(1,29): error TS2307: Cannot find module '@loopback/context'.
tests/cases/compiler/monorepo/core/dist/src/usage.d.ts(1,28): error TS2307: Cannot find module '@loopback/context'.
tests/cases/compiler/monorepo/core/dist/src/usage.d.ts(2,51): error TS2307: Cannot find module '@loopback/context/src/value-promise'.
==== tests/cases/compiler/monorepo/core/tsconfig.json (0 errors) ====
{
"compilerOptions": {
"rootDir": ".",
"declaration": true,
"outDir": "./dist"
}
}
==== tests/cases/compiler/monorepo/context/src/value-promise.d.ts (0 errors) ====
export type Constructor<T> = (...args: any[]) => T;
==== tests/cases/compiler/monorepo/context/src/bindingkey.d.ts (0 errors) ====
import { Constructor } from "./value-promise"
export declare class BindingKey<T> {
readonly __type: T;
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
}
==== tests/cases/compiler/monorepo/context/index.d.ts (0 errors) ====
export * from "./src/value-promise";
export * from "./src/bindingkey";
==== tests/cases/compiler/monorepo/core/dist/src/application.d.ts (1 errors) ====
import { Constructor } from "@loopback/context";
~~~~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module '@loopback/context'.
export declare type ControllerClass = Constructor<any>;
==== tests/cases/compiler/monorepo/core/dist/src/usage.d.ts (2 errors) ====
import { BindingKey } from '@loopback/context';
~~~~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module '@loopback/context'.
export declare const CONTROLLER_CLASS: BindingKey<import("@loopback/context/src/value-promise").Constructor<any>>;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2307: Cannot find module '@loopback/context/src/value-promise'.

View File

@@ -0,0 +1,55 @@
=== tests/cases/compiler/monorepo/context/src/value-promise.d.ts ===
export type Constructor<T> = (...args: any[]) => T;
>Constructor : Symbol(Constructor, Decl(value-promise.d.ts, 0, 0))
>T : Symbol(T, Decl(value-promise.d.ts, 0, 24))
>args : Symbol(args, Decl(value-promise.d.ts, 0, 30))
>T : Symbol(T, Decl(value-promise.d.ts, 0, 24))
=== tests/cases/compiler/monorepo/context/src/bindingkey.d.ts ===
import { Constructor } from "./value-promise"
>Constructor : Symbol(Constructor, Decl(bindingkey.d.ts, 0, 8))
export declare class BindingKey<T> {
>BindingKey : Symbol(BindingKey, Decl(bindingkey.d.ts, 0, 45))
>T : Symbol(T, Decl(bindingkey.d.ts, 1, 32))
readonly __type: T;
>__type : Symbol(BindingKey.__type, Decl(bindingkey.d.ts, 1, 36))
>T : Symbol(T, Decl(bindingkey.d.ts, 1, 32))
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
>create : Symbol(BindingKey.create, Decl(bindingkey.d.ts, 2, 21))
>T : Symbol(T, Decl(bindingkey.d.ts, 3, 16))
>Constructor : Symbol(Constructor, Decl(bindingkey.d.ts, 0, 8))
>ctor : Symbol(ctor, Decl(bindingkey.d.ts, 3, 44))
>T : Symbol(T, Decl(bindingkey.d.ts, 3, 16))
>BindingKey : Symbol(BindingKey, Decl(bindingkey.d.ts, 0, 45))
>T : Symbol(T, Decl(bindingkey.d.ts, 3, 16))
}
=== tests/cases/compiler/monorepo/context/index.d.ts ===
export * from "./src/value-promise";
No type information for this code.export * from "./src/bindingkey";
No type information for this code.
No type information for this code.=== tests/cases/compiler/monorepo/core/src/application.ts ===
import { Constructor } from "@loopback/context";
>Constructor : Symbol(Constructor, Decl(application.ts, 0, 8))
export type ControllerClass = Constructor<any>;
>ControllerClass : Symbol(ControllerClass, Decl(application.ts, 0, 48))
>Constructor : Symbol(Constructor, Decl(application.ts, 0, 8))
=== tests/cases/compiler/monorepo/core/src/usage.ts ===
import { ControllerClass } from './application';
>ControllerClass : Symbol(ControllerClass, Decl(usage.ts, 0, 8))
import { BindingKey } from '@loopback/context';
>BindingKey : Symbol(BindingKey, Decl(usage.ts, 1, 8))
export const CONTROLLER_CLASS = BindingKey.create<ControllerClass>(null as any); // line in question
>CONTROLLER_CLASS : Symbol(CONTROLLER_CLASS, Decl(usage.ts, 3, 12))
>BindingKey.create : Symbol(BindingKey.create, Decl(bindingkey.d.ts, 2, 21))
>BindingKey : Symbol(BindingKey, Decl(usage.ts, 1, 8))
>create : Symbol(BindingKey.create, Decl(bindingkey.d.ts, 2, 21))
>ControllerClass : Symbol(ControllerClass, Decl(usage.ts, 0, 8))

View File

@@ -0,0 +1,58 @@
=== tests/cases/compiler/monorepo/context/src/value-promise.d.ts ===
export type Constructor<T> = (...args: any[]) => T;
>Constructor : Constructor<T>
>T : T
>args : any[]
>T : T
=== tests/cases/compiler/monorepo/context/src/bindingkey.d.ts ===
import { Constructor } from "./value-promise"
>Constructor : any
export declare class BindingKey<T> {
>BindingKey : BindingKey<T>
>T : T
readonly __type: T;
>__type : T
>T : T
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
>create : <T extends Constructor<any>>(ctor: T) => BindingKey<T>
>T : T
>Constructor : Constructor<T>
>ctor : T
>T : T
>BindingKey : BindingKey<T>
>T : T
}
=== tests/cases/compiler/monorepo/context/index.d.ts ===
export * from "./src/value-promise";
No type information for this code.export * from "./src/bindingkey";
No type information for this code.
No type information for this code.=== tests/cases/compiler/monorepo/core/src/application.ts ===
import { Constructor } from "@loopback/context";
>Constructor : any
export type ControllerClass = Constructor<any>;
>ControllerClass : Constructor<any>
>Constructor : Constructor<T>
=== tests/cases/compiler/monorepo/core/src/usage.ts ===
import { ControllerClass } from './application';
>ControllerClass : any
import { BindingKey } from '@loopback/context';
>BindingKey : typeof BindingKey
export const CONTROLLER_CLASS = BindingKey.create<ControllerClass>(null as any); // line in question
>CONTROLLER_CLASS : BindingKey<import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>>
>BindingKey.create<ControllerClass>(null as any) : BindingKey<import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>>
>BindingKey.create : <T extends import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>>(ctor: T) => BindingKey<T>
>BindingKey : typeof BindingKey
>create : <T extends import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>>(ctor: T) => BindingKey<T>
>ControllerClass : import("tests/cases/compiler/monorepo/context/src/value-promise").Constructor<any>
>null as any : any
>null : null

View File

@@ -0,0 +1,33 @@
// @currentDirectory: monorepo/core
// @filename: monorepo/context/src/value-promise.d.ts
export type Constructor<T> = (...args: any[]) => T;
// @filename: monorepo/context/src/bindingkey.d.ts
import { Constructor } from "./value-promise"
export declare class BindingKey<T> {
readonly __type: T;
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
}
// @filename: monorepo/context/index.d.ts
export * from "./src/value-promise";
export * from "./src/bindingkey";
// @filename: monorepo/core/tsconfig.json
{
"compilerOptions": {
"rootDir": ".",
"declaration": true,
"outDir": "./dist"
}
}
// @filename: monorepo/core/src/application.ts
import { Constructor } from "@loopback/context";
export type ControllerClass = Constructor<any>;
// @filename: monorepo/core/src/usage.ts
import { ControllerClass } from './application';
import { BindingKey } from '@loopback/context';
export const CONTROLLER_CLASS = BindingKey.create<ControllerClass>(null as any); // line in question
// @link: tests/cases/compiler/monorepo/context -> tests/cases/compiler/monorepo/core/node_modules/@loopback/context