mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-06 20:14:01 -06:00
fix symlink tag, support arbitrary (ie, directory) links via @link
Introduce indirect symlink lookup to specifier deriver Use fileset, move exec vfs path resolution :shakes fist: Apply files symlink relative to dirname Use directory function
This commit is contained in:
parent
14da064754
commit
97c3c6056d
@ -4093,7 +4093,14 @@ namespace ts {
|
||||
}
|
||||
else {
|
||||
const contextFile = getSourceFileOfNode(getOriginalNode(context!.enclosingDeclaration))!;
|
||||
return `"${file.moduleName || moduleSpecifiers.getModuleSpecifier(compilerOptions, contextFile, contextFile.path, file.path, context!.tracker.moduleResolverHost!)}"`;
|
||||
return `"${file.moduleName || moduleSpecifiers.getModuleSpecifiers(
|
||||
symbol,
|
||||
compilerOptions,
|
||||
contextFile,
|
||||
context!.tracker.moduleResolverHost!,
|
||||
context!.tracker.moduleResolverHost!.getSourceFiles!(),
|
||||
{ importModuleSpecifierPreference: "non-relative" }
|
||||
)[0]}"`;
|
||||
}
|
||||
}
|
||||
const declaration = symbol.declarations[0];
|
||||
|
||||
@ -15,17 +15,20 @@ namespace ts.moduleSpecifiers {
|
||||
// For each symlink/original for a module, returns a list of ways to import that file.
|
||||
export function getModuleSpecifiers(
|
||||
moduleSymbol: Symbol,
|
||||
program: Program,
|
||||
compilerOptions: CompilerOptions,
|
||||
importingSourceFile: SourceFile,
|
||||
host: ModuleSpecifierResolutionHost,
|
||||
files: ReadonlyArray<SourceFile>,
|
||||
preferences: ModuleSpecifierPreferences,
|
||||
): ReadonlyArray<ReadonlyArray<string>> {
|
||||
const ambient = tryGetModuleNameFromAmbientModule(moduleSymbol);
|
||||
if (ambient) return [[ambient]];
|
||||
|
||||
const compilerOptions = program.getCompilerOptions();
|
||||
const info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.fileName, host);
|
||||
const modulePaths = getAllModulePaths(program, getSourceFileOfNode(moduleSymbol.valueDeclaration));
|
||||
const info = getInfo(compilerOptions, importingSourceFile, importingSourceFile.path, host);
|
||||
if (!files) {
|
||||
return Debug.fail("Files list must be present to resolve symlinks in specifier resolution");
|
||||
}
|
||||
const modulePaths = getAllModulePaths(files, getSourceFileOfNode(moduleSymbol.valueDeclaration), info.getCanonicalFileName, host);
|
||||
|
||||
const global = mapDefined(modulePaths, moduleFileName => getGlobalModuleSpecifier(moduleFileName, info, host, compilerOptions));
|
||||
return global.length ? global.map(g => [g]) : modulePaths.map(moduleFileName =>
|
||||
@ -130,15 +133,57 @@ namespace ts.moduleSpecifiers {
|
||||
return firstDefined(imports, ({ text }) => pathIsRelative(text) ? fileExtensionIs(text, Extension.Js) : undefined) || false;
|
||||
}
|
||||
|
||||
function discoverProbableSymlinks(files: ReadonlyArray<SourceFile>) {
|
||||
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) {
|
||||
for (const [resolvedPath, originalPath] of symlinks) {
|
||||
const resolvedParts = getPathComponents(resolvedPath);
|
||||
const originalParts = getPathComponents(originalPath);
|
||||
while (resolvedParts[resolvedParts.length - 1] === originalParts[originalParts.length - 1]) {
|
||||
resolvedParts.pop();
|
||||
originalParts.pop();
|
||||
}
|
||||
result.set(getPathFromPathComponents(originalParts), getPathFromPathComponents(resolvedParts));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAllModulePathsUsingIndirectSymlinks(files: ReadonlyArray<SourceFile>, target: string, getCanonicalFileName: (file: string) => string, host: ModuleSpecifierResolutionHost) {
|
||||
const links = discoverProbableSymlinks(files);
|
||||
const paths = arrayFrom(links.keys());
|
||||
let options: string[] | undefined;
|
||||
for (const path of paths) {
|
||||
const resolved = links.get(path)!;
|
||||
if (startsWith(target, resolved + "/")) {
|
||||
const relative = getRelativePathFromDirectory(resolved, target, getCanonicalFileName);
|
||||
const option = resolvePath(path, relative);
|
||||
if (!host.fileExists || host.fileExists(option)) {
|
||||
if (!options) options = [];
|
||||
options.push(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
return options;
|
||||
}
|
||||
return [resolvedtarget];
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a existing imports that use symlinks to this module.
|
||||
* Only if no symlink is available, the real path will be used.
|
||||
*/
|
||||
function getAllModulePaths(program: Program, { fileName }: SourceFile): ReadonlyArray<string> {
|
||||
const symlinks = mapDefined(program.getSourceFiles(), sf =>
|
||||
function getAllModulePaths(files: ReadonlyArray<SourceFile>, { fileName }: SourceFile, getCanonicalFileName: (file: string) => string, host: ModuleSpecifierResolutionHost): ReadonlyArray<string> {
|
||||
const symlinks = mapDefined(files, sf =>
|
||||
sf.resolvedModules && firstDefinedIterator(sf.resolvedModules.values(), res =>
|
||||
res && res.resolvedFileName === fileName ? res.originalPath : undefined));
|
||||
return symlinks.length === 0 ? [fileName] : symlinks;
|
||||
return symlinks.length === 0 ? getAllModulePathsUsingIndirectSymlinks(files, fileName, getCanonicalFileName, host) : symlinks;
|
||||
}
|
||||
|
||||
function getRelativePathNParents(relativePath: string): number {
|
||||
|
||||
@ -5284,6 +5284,7 @@ namespace ts {
|
||||
useCaseSensitiveFileNames?(): boolean;
|
||||
fileExists?(path: string): boolean;
|
||||
readFile?(path: string): string | undefined;
|
||||
getSourceFiles?(): ReadonlyArray<SourceFile>; // Used for cached resolutions to find symlinks without traversing the fs (again)
|
||||
}
|
||||
|
||||
/** @deprecated See comment on SymbolWriter */
|
||||
|
||||
@ -187,7 +187,9 @@ class CompilerTest {
|
||||
this.otherFiles,
|
||||
this.harnessSettings,
|
||||
/*options*/ tsConfigOptions,
|
||||
/*currentDirectory*/ this.harnessSettings.currentDirectory);
|
||||
/*currentDirectory*/ this.harnessSettings.currentDirectory,
|
||||
testCaseContent.symlinks
|
||||
);
|
||||
|
||||
this.options = this.result.options;
|
||||
}
|
||||
|
||||
@ -1138,6 +1138,7 @@ namespace Harness {
|
||||
{ name: "noImplicitReferences", type: "boolean" },
|
||||
{ name: "currentDirectory", type: "string" },
|
||||
{ name: "symlink", type: "string" },
|
||||
{ name: "link", type: "string" },
|
||||
// Emitted js baseline will print full paths for every output file
|
||||
{ name: "fullEmitPaths", type: "boolean" }
|
||||
];
|
||||
@ -1209,7 +1210,9 @@ namespace Harness {
|
||||
harnessSettings: TestCaseParser.CompilerSettings,
|
||||
compilerOptions: ts.CompilerOptions,
|
||||
// Current directory is needed for rwcRunner to be able to use currentDirectory defined in json file
|
||||
currentDirectory: string): compiler.CompilationResult {
|
||||
currentDirectory: string | undefined,
|
||||
symlinks?: vfs.FileSet
|
||||
): compiler.CompilationResult {
|
||||
const options: ts.CompilerOptions & HarnessOptions = compilerOptions ? ts.cloneCompilerOptions(compilerOptions) : { noResolve: false };
|
||||
options.target = options.target || ts.ScriptTarget.ES3;
|
||||
options.newLine = options.newLine || ts.NewLineKind.CarriageReturnLineFeed;
|
||||
@ -1246,6 +1249,9 @@ namespace Harness {
|
||||
|
||||
const docs = inputFiles.concat(otherFiles).map(documents.TextDocument.fromTestFile);
|
||||
const fs = vfs.createFromFileSystem(IO, !useCaseSensitiveFileNames, { documents: docs, cwd: currentDirectory });
|
||||
if (symlinks) {
|
||||
fs.apply(symlinks);
|
||||
}
|
||||
const host = new fakes.CompilerHost(fs, options);
|
||||
return compiler.compileFiles(host, programFileNames, options);
|
||||
}
|
||||
@ -1858,6 +1864,7 @@ namespace Harness {
|
||||
|
||||
// Regex for parsing options in the format "@Alpha: Value of any sort"
|
||||
const optionRegex = /^[\/]{2}\s*@(\w+)\s*:\s*([^\r\n]*)/gm; // multiple matches on multiple lines
|
||||
const linkRegex = /^[\/]{2}\s*@link\s*:\s*([^\r\n]*)\s*->\s*([^\r\n]*)/gm; // multiple matches on multiple lines
|
||||
|
||||
export function extractCompilerSettings(content: string): CompilerSettings {
|
||||
const opts: CompilerSettings = {};
|
||||
@ -1875,8 +1882,9 @@ namespace Harness {
|
||||
export interface TestCaseContent {
|
||||
settings: CompilerSettings;
|
||||
testUnitData: TestUnitData[];
|
||||
tsConfig: ts.ParsedCommandLine;
|
||||
tsConfigFileUnitData: TestUnitData;
|
||||
tsConfig: ts.ParsedCommandLine | undefined;
|
||||
tsConfigFileUnitData: TestUnitData | undefined;
|
||||
symlinks?: vfs.FileSet;
|
||||
}
|
||||
|
||||
/** Given a test file containing // @FileName directives, return an array of named units of code to be added to an existing compiler instance */
|
||||
@ -1891,10 +1899,16 @@ namespace Harness {
|
||||
let currentFileOptions: any = {};
|
||||
let currentFileName: any;
|
||||
let refs: string[] = [];
|
||||
let symlinks: vfs.FileSet | undefined;
|
||||
|
||||
for (const line of lines) {
|
||||
const testMetaData = optionRegex.exec(line);
|
||||
if (testMetaData) {
|
||||
let testMetaData: RegExpExecArray | null;
|
||||
const linkMetaData = linkRegex.exec(line);
|
||||
if (linkMetaData) {
|
||||
if (!symlinks) symlinks = {};
|
||||
symlinks[linkMetaData[2].trim()] = new vfs.Symlink(linkMetaData[1].trim());
|
||||
}
|
||||
else if (testMetaData = optionRegex.exec(line)) {
|
||||
// Comment line, check for global/file @options and record them
|
||||
optionRegex.lastIndex = 0;
|
||||
const metaDataName = testMetaData[1].toLowerCase();
|
||||
@ -1983,7 +1997,7 @@ namespace Harness {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return { settings, testUnitData, tsConfig, tsConfigFileUnitData };
|
||||
return { settings, testUnitData, tsConfig, tsConfigFileUnitData, symlinks };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -883,7 +883,7 @@ namespace vfs {
|
||||
if (this.stringComparer(vpath.dirname(path), path) === 0) {
|
||||
throw new TypeError("Roots cannot be symbolic links.");
|
||||
}
|
||||
this.symlinkSync(entry.symlink, path);
|
||||
this.symlinkSync(vpath.resolve(dirname, entry.symlink), path);
|
||||
this._applyFileExtendedOptions(path, entry);
|
||||
}
|
||||
else if (entry instanceof Link) {
|
||||
@ -1050,8 +1050,7 @@ namespace vfs {
|
||||
if (symlink) {
|
||||
for (const link of symlink.split(",").map(link => link.trim())) {
|
||||
fs.mkdirpSync(vpath.dirname(link));
|
||||
fs.symlinkSync(document.file, link);
|
||||
fs.filemeta(link).set("document", document);
|
||||
fs.symlinkSync(vpath.resolve(fs.cwd(), document.file), link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -237,7 +237,7 @@ namespace ts.codefix {
|
||||
preferences: UserPreferences,
|
||||
): ReadonlyArray<NewImportInfo> {
|
||||
const choicesForEachExportingModule = flatMap<SymbolExportInfo, NewImportInfo[]>(moduleSymbols, ({ moduleSymbol, importKind }) => {
|
||||
const modulePathsGroups = moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program, sourceFile, host, preferences);
|
||||
const modulePathsGroups = moduleSpecifiers.getModuleSpecifiers(moduleSymbol, program.getCompilerOptions(), sourceFile, host, program.getSourceFiles(), preferences);
|
||||
return modulePathsGroups.map(group => group.map(moduleSpecifier => ({ moduleSpecifier, importKind })));
|
||||
});
|
||||
// Sort to keep the shortest paths first, but keep [relativePath, importRelativeToBaseUrl] groups together
|
||||
|
||||
@ -0,0 +1,116 @@
|
||||
//// [tests/cases/compiler/symbolLinkDeclarationEmitModuleNames.ts] ////
|
||||
|
||||
//// [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
|
||||
//// [value-promise.ts]
|
||||
export type Constructor<T> = (...args: any[]) => T;
|
||||
//// [bindingkey.ts]
|
||||
import { Constructor } from "@loopback/context"
|
||||
export class BindingKey<T> {
|
||||
readonly __type: T;
|
||||
static create<T extends Constructor<any>>(ctor: T) {
|
||||
return new BindingKey<T>();
|
||||
}
|
||||
}
|
||||
|
||||
//// [index.ts]
|
||||
export * from "./src/value-promise";
|
||||
export * from "./src/bindingkey";
|
||||
|
||||
|
||||
//// [value-promise.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
//// [bindingkey.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var BindingKey = /** @class */ (function () {
|
||||
function BindingKey() {
|
||||
}
|
||||
BindingKey.create = function (ctor) {
|
||||
return new BindingKey();
|
||||
};
|
||||
return BindingKey;
|
||||
}());
|
||||
exports.BindingKey = BindingKey;
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
function __export(m) {
|
||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||
}
|
||||
exports.__esModule = true;
|
||||
__export(require("./src/bindingkey"));
|
||||
//// [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
|
||||
|
||||
|
||||
//// [value-promise.d.ts]
|
||||
export declare type Constructor<T> = (...args: any[]) => T;
|
||||
//// [bindingkey.d.ts]
|
||||
import { Constructor } from "@loopback/context";
|
||||
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.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/context/src/bindingkey.d.ts(1,29): error TS2307: Cannot find module '@loopback/context'.
|
||||
tests/cases/compiler/monorepo/core/src/application.d.ts(1,29): error TS2307: Cannot find module '@loopback/context'.
|
||||
tests/cases/compiler/monorepo/core/src/usage.d.ts(1,28): error TS2307: Cannot find module '@loopback/context'.
|
||||
tests/cases/compiler/monorepo/core/src/usage.d.ts(2,51): error TS2307: Cannot find module '@loopback/context/src/value-promise'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/monorepo/core/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/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'.
|
||||
|
||||
==== /.src/tests/cases/compiler/monorepo/context/src/value-promise.d.ts (0 errors) ====
|
||||
export declare type Constructor<T> = (...args: any[]) => T;
|
||||
|
||||
==== /.src/tests/cases/compiler/monorepo/context/src/bindingkey.d.ts (1 errors) ====
|
||||
import { Constructor } from "@loopback/context";
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2307: Cannot find module '@loopback/context'.
|
||||
export declare class BindingKey<T> {
|
||||
readonly __type: T;
|
||||
static create<T extends Constructor<any>>(ctor: T): BindingKey<T>;
|
||||
}
|
||||
|
||||
==== /.src/tests/cases/compiler/monorepo/context/index.d.ts (0 errors) ====
|
||||
export * from "./src/value-promise";
|
||||
export * from "./src/bindingkey";
|
||||
|
||||
@ -0,0 +1,59 @@
|
||||
=== 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.ts, 2, 21))
|
||||
>BindingKey : Symbol(BindingKey, Decl(usage.ts, 1, 8))
|
||||
>create : Symbol(BindingKey.create, Decl(bindingkey.ts, 2, 21))
|
||||
>ControllerClass : Symbol(ControllerClass, Decl(usage.ts, 0, 8))
|
||||
|
||||
=== tests/cases/compiler/monorepo/context/src/value-promise.ts ===
|
||||
export type Constructor<T> = (...args: any[]) => T;
|
||||
>Constructor : Symbol(Constructor, Decl(value-promise.ts, 0, 0))
|
||||
>T : Symbol(T, Decl(value-promise.ts, 0, 24))
|
||||
>args : Symbol(args, Decl(value-promise.ts, 0, 30))
|
||||
>T : Symbol(T, Decl(value-promise.ts, 0, 24))
|
||||
|
||||
=== tests/cases/compiler/monorepo/context/src/bindingkey.ts ===
|
||||
import { Constructor } from "@loopback/context"
|
||||
>Constructor : Symbol(Constructor, Decl(bindingkey.ts, 0, 8))
|
||||
|
||||
export class BindingKey<T> {
|
||||
>BindingKey : Symbol(BindingKey, Decl(bindingkey.ts, 0, 47))
|
||||
>T : Symbol(T, Decl(bindingkey.ts, 1, 24))
|
||||
|
||||
readonly __type: T;
|
||||
>__type : Symbol(BindingKey.__type, Decl(bindingkey.ts, 1, 28))
|
||||
>T : Symbol(T, Decl(bindingkey.ts, 1, 24))
|
||||
|
||||
static create<T extends Constructor<any>>(ctor: T) {
|
||||
>create : Symbol(BindingKey.create, Decl(bindingkey.ts, 2, 21))
|
||||
>T : Symbol(T, Decl(bindingkey.ts, 3, 16))
|
||||
>Constructor : Symbol(Constructor, Decl(bindingkey.ts, 0, 8))
|
||||
>ctor : Symbol(ctor, Decl(bindingkey.ts, 3, 44))
|
||||
>T : Symbol(T, Decl(bindingkey.ts, 3, 16))
|
||||
|
||||
return new BindingKey<T>();
|
||||
>BindingKey : Symbol(BindingKey, Decl(bindingkey.ts, 0, 47))
|
||||
>T : Symbol(T, Decl(bindingkey.ts, 3, 16))
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/monorepo/context/index.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.
|
||||
@ -0,0 +1,63 @@
|
||||
=== 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
|
||||
|
||||
=== tests/cases/compiler/monorepo/context/src/value-promise.ts ===
|
||||
export type Constructor<T> = (...args: any[]) => T;
|
||||
>Constructor : Constructor<T>
|
||||
>T : T
|
||||
>args : any[]
|
||||
>T : T
|
||||
|
||||
=== tests/cases/compiler/monorepo/context/src/bindingkey.ts ===
|
||||
import { Constructor } from "@loopback/context"
|
||||
>Constructor : any
|
||||
|
||||
export class BindingKey<T> {
|
||||
>BindingKey : BindingKey<T>
|
||||
>T : T
|
||||
|
||||
readonly __type: T;
|
||||
>__type : T
|
||||
>T : T
|
||||
|
||||
static create<T extends Constructor<any>>(ctor: T) {
|
||||
>create : <T extends Constructor<any>>(ctor: T) => BindingKey<T>
|
||||
>T : T
|
||||
>Constructor : Constructor<T>
|
||||
>ctor : T
|
||||
>T : T
|
||||
|
||||
return new BindingKey<T>();
|
||||
>new BindingKey<T>() : BindingKey<T>
|
||||
>BindingKey : typeof BindingKey
|
||||
>T : T
|
||||
}
|
||||
}
|
||||
|
||||
=== tests/cases/compiler/monorepo/context/index.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.
|
||||
25
tests/cases/compiler/symbolLinkDeclarationEmitModuleNames.ts
Normal file
25
tests/cases/compiler/symbolLinkDeclarationEmitModuleNames.ts
Normal file
@ -0,0 +1,25 @@
|
||||
// @declaration: true
|
||||
// @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
|
||||
// @filename: monorepo/context/src/value-promise.ts
|
||||
export type Constructor<T> = (...args: any[]) => T;
|
||||
// @filename: monorepo/context/src/bindingkey.ts
|
||||
import { Constructor } from "@loopback/context"
|
||||
export class BindingKey<T> {
|
||||
readonly __type: T;
|
||||
static create<T extends Constructor<any>>(ctor: T) {
|
||||
return new BindingKey<T>();
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: monorepo/context/index.ts
|
||||
export * from "./src/value-promise";
|
||||
export * from "./src/bindingkey";
|
||||
|
||||
// @link: tests/cases/compiler/monorepo/context -> tests/cases/compiler/monorepo/core/node_modules/@loopback/context
|
||||
Loading…
x
Reference in New Issue
Block a user