Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle combinations of rootdir and outdir when calculating paths #24941

Merged
merged 1 commit into from
Jun 14, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions src/compiler/moduleSpecifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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)) {
Expand All @@ -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];
}

/**
Expand All @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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'.

Original file line number Diff line number Diff line change
@@ -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))

Original file line number Diff line number Diff line change
@@ -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

Original file line number Diff line number Diff line change
@@ -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