feat(ivy): ngcc - map functions as well as classes from source to typings (#27326)
To support updating `ModuleWithProviders` calls, we need to be able to map exported functions between source and typings files, as well as classes. PR Close #27326
This commit is contained in:
parent
99d0e27587
commit
cfb8c17511
|
@ -52,7 +52,7 @@ export class PrivateDeclarationsAnalyzer {
|
||||||
return Array.from(privateDeclarations.keys()).map(id => {
|
return Array.from(privateDeclarations.keys()).map(id => {
|
||||||
const from = id.getSourceFile().fileName;
|
const from = id.getSourceFile().fileName;
|
||||||
const declaration = privateDeclarations.get(id) !;
|
const declaration = privateDeclarations.get(id) !;
|
||||||
const dtsDeclaration = this.host.getDtsDeclarationOfClass(declaration.node);
|
const dtsDeclaration = this.host.getDtsDeclaration(declaration.node);
|
||||||
const dtsFrom = dtsDeclaration && dtsDeclaration.getSourceFile().fileName;
|
const dtsFrom = dtsDeclaration && dtsDeclaration.getSourceFile().fileName;
|
||||||
return {identifier: id.text, from, dtsFrom};
|
return {identifier: id.text, from, dtsFrom};
|
||||||
});
|
});
|
||||||
|
|
|
@ -49,10 +49,10 @@ export const CONSTRUCTOR_PARAMS = 'ctorParameters' as ts.__String;
|
||||||
* a static method called `ctorParameters`.
|
* a static method called `ctorParameters`.
|
||||||
*/
|
*/
|
||||||
export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements NgccReflectionHost {
|
export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements NgccReflectionHost {
|
||||||
protected dtsClassMap: Map<string, ts.ClassDeclaration>|null;
|
protected dtsDeclarationMap: Map<string, ts.Declaration>|null;
|
||||||
constructor(protected isCore: boolean, checker: ts.TypeChecker, dts?: BundleProgram|null) {
|
constructor(protected isCore: boolean, checker: ts.TypeChecker, dts?: BundleProgram|null) {
|
||||||
super(checker);
|
super(checker);
|
||||||
this.dtsClassMap = dts && this.computeDtsClassMap(dts.path, dts.program) || null;
|
this.dtsDeclarationMap = dts && this.computeDtsDeclarationMap(dts.path, dts.program) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -327,15 +327,15 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||||
* is not a class or has an unknown number of type parameters.
|
* is not a class or has an unknown number of type parameters.
|
||||||
*/
|
*/
|
||||||
getGenericArityOfClass(clazz: ts.Declaration): number|null {
|
getGenericArityOfClass(clazz: ts.Declaration): number|null {
|
||||||
const dtsClass = this.getDtsDeclarationOfClass(clazz);
|
const dtsDeclaration = this.getDtsDeclaration(clazz);
|
||||||
if (dtsClass) {
|
if (dtsDeclaration && ts.isClassDeclaration(dtsDeclaration)) {
|
||||||
return dtsClass.typeParameters ? dtsClass.typeParameters.length : 0;
|
return dtsDeclaration.typeParameters ? dtsDeclaration.typeParameters.length : 0;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take an exported declaration of a class (maybe downleveled to a variable) and look up the
|
* Take an exported declaration of a class (maybe down-leveled to a variable) and look up the
|
||||||
* declaration of its type in a separate .d.ts tree.
|
* declaration of its type in a separate .d.ts tree.
|
||||||
*
|
*
|
||||||
* This function is allowed to return `null` if the current compilation unit does not have a
|
* This function is allowed to return `null` if the current compilation unit does not have a
|
||||||
|
@ -346,20 +346,17 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||||
* Note that the `ts.ClassDeclaration` returned from this function may not be from the same
|
* Note that the `ts.ClassDeclaration` returned from this function may not be from the same
|
||||||
* `ts.Program` as the input declaration.
|
* `ts.Program` as the input declaration.
|
||||||
*/
|
*/
|
||||||
getDtsDeclarationOfClass(declaration: ts.Declaration): ts.ClassDeclaration|null {
|
getDtsDeclaration(declaration: ts.Declaration): ts.Declaration|null {
|
||||||
if (this.dtsClassMap) {
|
if (!this.dtsDeclarationMap) {
|
||||||
if (ts.isClassDeclaration(declaration)) {
|
return null;
|
||||||
if (!declaration.name || !ts.isIdentifier(declaration.name)) {
|
|
||||||
throw new Error(
|
|
||||||
`Cannot get the dts file for a class declaration that has no indetifier: ${declaration.getText()} in ${declaration.getSourceFile().fileName}`);
|
|
||||||
}
|
|
||||||
return this.dtsClassMap.get(declaration.name.text) || null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return null;
|
if (!isNamedDeclaration(declaration)) {
|
||||||
|
throw new Error(
|
||||||
|
`Cannot get the dts file for a declaration that has no name: ${declaration.getText()} in ${declaration.getSourceFile().fileName}`);
|
||||||
|
}
|
||||||
|
return this.dtsDeclarationMap.get(declaration.name.text) || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////// Protected Helpers /////////////
|
///////////// Protected Helpers /////////////
|
||||||
|
|
||||||
protected getDecoratorsOfSymbol(symbol: ts.Symbol): Decorator[]|null {
|
protected getDecoratorsOfSymbol(symbol: ts.Symbol): Decorator[]|null {
|
||||||
|
@ -738,7 +735,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!name) {
|
if (!name) {
|
||||||
if (isNamedDeclaration(node) && node.name && ts.isIdentifier(node.name)) {
|
if (isNamedDeclaration(node)) {
|
||||||
name = node.name.text;
|
name = node.name.text;
|
||||||
nameNode = node.name;
|
nameNode = node.name;
|
||||||
} else {
|
} else {
|
||||||
|
@ -846,8 +843,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the parameter type and decorators for a class where the information is stored on
|
* Get the parameter type and decorators for a class where the information is stored via
|
||||||
* in calls to `__decorate` helpers.
|
* calls to `__decorate` helpers.
|
||||||
*
|
*
|
||||||
* Reflect over the helpers to find the decorators and types about each of
|
* Reflect over the helpers to find the decorators and types about each of
|
||||||
* the class's constructor parameters.
|
* the class's constructor parameters.
|
||||||
|
@ -1002,9 +999,9 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||||
* @param dtsProgram The program containing all the typings files.
|
* @param dtsProgram The program containing all the typings files.
|
||||||
* @returns a map of class names to class declarations.
|
* @returns a map of class names to class declarations.
|
||||||
*/
|
*/
|
||||||
protected computeDtsClassMap(dtsRootFileName: string, dtsProgram: ts.Program):
|
protected computeDtsDeclarationMap(dtsRootFileName: string, dtsProgram: ts.Program):
|
||||||
Map<string, ts.ClassDeclaration> {
|
Map<string, ts.Declaration> {
|
||||||
const dtsClassMap = new Map<string, ts.ClassDeclaration>();
|
const dtsDeclarationMap = new Map<string, ts.Declaration>();
|
||||||
const checker = dtsProgram.getTypeChecker();
|
const checker = dtsProgram.getTypeChecker();
|
||||||
|
|
||||||
// First add all the classes that are publicly exported from the entry-point
|
// First add all the classes that are publicly exported from the entry-point
|
||||||
|
@ -1012,13 +1009,13 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||||
if (!rootFile) {
|
if (!rootFile) {
|
||||||
throw new Error(`The given file ${dtsRootFileName} is not part of the typings program.`);
|
throw new Error(`The given file ${dtsRootFileName} is not part of the typings program.`);
|
||||||
}
|
}
|
||||||
collectExportedClasses(checker, dtsClassMap, rootFile);
|
collectExportedDeclarations(checker, dtsDeclarationMap, rootFile);
|
||||||
|
|
||||||
// Now add any additional classes that are exported from individual dts files,
|
// Now add any additional classes that are exported from individual dts files,
|
||||||
// but are not publicly exported from the entry-point.
|
// but are not publicly exported from the entry-point.
|
||||||
dtsProgram.getSourceFiles().forEach(
|
dtsProgram.getSourceFiles().forEach(
|
||||||
sourceFile => { collectExportedClasses(checker, dtsClassMap, sourceFile); });
|
sourceFile => { collectExportedDeclarations(checker, dtsDeclarationMap, sourceFile); });
|
||||||
return dtsClassMap;
|
return dtsDeclarationMap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1129,8 +1126,10 @@ function isThisAssignment(node: ts.Declaration): node is ts.BinaryExpression&
|
||||||
node.left.expression.kind === ts.SyntaxKind.ThisKeyword;
|
node.left.expression.kind === ts.SyntaxKind.ThisKeyword;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isNamedDeclaration(node: ts.Declaration): node is ts.NamedDeclaration {
|
function isNamedDeclaration(node: ts.Declaration): node is ts.NamedDeclaration&
|
||||||
return !!(node as any).name;
|
{name: ts.Identifier} {
|
||||||
|
const anyNode: any = node;
|
||||||
|
return !!anyNode.name && ts.isIdentifier(anyNode.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1153,13 +1152,11 @@ function getFarLeftIdentifier(propertyAccess: ts.PropertyAccessExpression): ts.I
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search a source file for exported classes, storing them in the provided `dtsClassMap`.
|
* Collect mappings between exported declarations in a source file and its associated
|
||||||
* @param checker The typechecker for the source program.
|
* declaration in the typings program.
|
||||||
* @param dtsClassMap The map in which to store the collected exported classes.
|
|
||||||
* @param srcFile The source file to search for exported classes.
|
|
||||||
*/
|
*/
|
||||||
function collectExportedClasses(
|
function collectExportedDeclarations(
|
||||||
checker: ts.TypeChecker, dtsClassMap: Map<string, ts.ClassDeclaration>,
|
checker: ts.TypeChecker, dtsDeclarationMap: Map<string, ts.Declaration>,
|
||||||
srcFile: ts.SourceFile): void {
|
srcFile: ts.SourceFile): void {
|
||||||
const srcModule = srcFile && checker.getSymbolAtLocation(srcFile);
|
const srcModule = srcFile && checker.getSymbolAtLocation(srcFile);
|
||||||
const moduleExports = srcModule && checker.getExportsOfModule(srcModule);
|
const moduleExports = srcModule && checker.getExportsOfModule(srcModule);
|
||||||
|
@ -1170,8 +1167,8 @@ function collectExportedClasses(
|
||||||
}
|
}
|
||||||
const declaration = exportedSymbol.valueDeclaration;
|
const declaration = exportedSymbol.valueDeclaration;
|
||||||
const name = exportedSymbol.name;
|
const name = exportedSymbol.name;
|
||||||
if (declaration && ts.isClassDeclaration(declaration) && !dtsClassMap.has(name)) {
|
if (declaration && !dtsDeclarationMap.has(name)) {
|
||||||
dtsClassMap.set(name, declaration);
|
dtsDeclarationMap.set(name, declaration);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -307,7 +307,7 @@ export abstract class Renderer {
|
||||||
const dtsMap = new Map<ts.SourceFile, DtsClassInfo[]>();
|
const dtsMap = new Map<ts.SourceFile, DtsClassInfo[]>();
|
||||||
analyses.forEach(compiledFile => {
|
analyses.forEach(compiledFile => {
|
||||||
compiledFile.compiledClasses.forEach(compiledClass => {
|
compiledFile.compiledClasses.forEach(compiledClass => {
|
||||||
const dtsDeclaration = this.host.getDtsDeclarationOfClass(compiledClass.declaration);
|
const dtsDeclaration = this.host.getDtsDeclaration(compiledClass.declaration);
|
||||||
if (dtsDeclaration) {
|
if (dtsDeclaration) {
|
||||||
const dtsFile = dtsDeclaration.getSourceFile();
|
const dtsFile = dtsDeclaration.getSourceFile();
|
||||||
const classes = dtsMap.get(dtsFile) || [];
|
const classes = dtsMap.get(dtsFile) || [];
|
||||||
|
|
|
@ -453,6 +453,7 @@ const TYPINGS_SRC_FILES = [
|
||||||
},
|
},
|
||||||
{name: '/src/class1.js', contents: 'export class Class1 {}\nexport class MissingClass1 {}'},
|
{name: '/src/class1.js', contents: 'export class Class1 {}\nexport class MissingClass1 {}'},
|
||||||
{name: '/src/class2.js', contents: 'export class Class2 {}'},
|
{name: '/src/class2.js', contents: 'export class Class2 {}'},
|
||||||
|
{name: '/src/func1.js', contents: 'export function mooFn() {}'},
|
||||||
{name: '/src/internal.js', contents: 'export class InternalClass {}\nexport class Class2 {}'},
|
{name: '/src/internal.js', contents: 'export class InternalClass {}\nexport class Class2 {}'},
|
||||||
{name: '/src/missing-class.js', contents: 'export class MissingClass2 {}'}, {
|
{name: '/src/missing-class.js', contents: 'export class MissingClass2 {}'}, {
|
||||||
name: '/src/flat-file.js',
|
name: '/src/flat-file.js',
|
||||||
|
@ -476,6 +477,7 @@ const TYPINGS_DTS_FILES = [
|
||||||
contents:
|
contents:
|
||||||
`export declare class Class2 {}\nexport declare interface SomeInterface {}\nexport {Class3 as xClass3} from './class3';`
|
`export declare class Class2 {}\nexport declare interface SomeInterface {}\nexport {Class3 as xClass3} from './class3';`
|
||||||
},
|
},
|
||||||
|
{name: '/typings/func1.d.ts', contents: 'export declare function mooFn(): void;'},
|
||||||
{
|
{
|
||||||
name: '/typings/internal.d.ts',
|
name: '/typings/internal.d.ts',
|
||||||
contents: `export declare class InternalClass {}\nexport declare class Class2 {}`
|
contents: `export declare class InternalClass {}\nexport declare class Class2 {}`
|
||||||
|
@ -1286,10 +1288,20 @@ describe('Fesm2015ReflectionHost', () => {
|
||||||
const class1 = getDeclaration(srcProgram, '/src/class1.js', 'Class1', ts.isClassDeclaration);
|
const class1 = getDeclaration(srcProgram, '/src/class1.js', 'Class1', ts.isClassDeclaration);
|
||||||
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
||||||
|
|
||||||
const dtsDeclaration = host.getDtsDeclarationOfClass(class1);
|
const dtsDeclaration = host.getDtsDeclaration(class1);
|
||||||
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/class1.d.ts');
|
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/class1.d.ts');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should find the dts declaration for exported functions', () => {
|
||||||
|
const srcProgram = makeTestProgram(...TYPINGS_SRC_FILES);
|
||||||
|
const dtsProgram = makeTestBundleProgram(TYPINGS_DTS_FILES);
|
||||||
|
const mooFn = getDeclaration(srcProgram, '/src/func1.js', 'mooFn', ts.isFunctionDeclaration);
|
||||||
|
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dtsProgram);
|
||||||
|
|
||||||
|
const dtsDeclaration = host.getDtsDeclaration(mooFn);
|
||||||
|
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/func1.d.ts');
|
||||||
|
});
|
||||||
|
|
||||||
it('should return null if there is no matching class in the matching dts file', () => {
|
it('should return null if there is no matching class in the matching dts file', () => {
|
||||||
const srcProgram = makeTestProgram(...TYPINGS_SRC_FILES);
|
const srcProgram = makeTestProgram(...TYPINGS_SRC_FILES);
|
||||||
const dts = makeTestBundleProgram(TYPINGS_DTS_FILES);
|
const dts = makeTestBundleProgram(TYPINGS_DTS_FILES);
|
||||||
|
@ -1297,7 +1309,7 @@ describe('Fesm2015ReflectionHost', () => {
|
||||||
getDeclaration(srcProgram, '/src/class1.js', 'MissingClass1', ts.isClassDeclaration);
|
getDeclaration(srcProgram, '/src/class1.js', 'MissingClass1', ts.isClassDeclaration);
|
||||||
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
||||||
|
|
||||||
expect(host.getDtsDeclarationOfClass(missingClass)).toBe(null);
|
expect(host.getDtsDeclaration(missingClass)).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return null if there is no matching dts file', () => {
|
it('should return null if there is no matching dts file', () => {
|
||||||
|
@ -1307,7 +1319,7 @@ describe('Fesm2015ReflectionHost', () => {
|
||||||
srcProgram, '/src/missing-class.js', 'MissingClass2', ts.isClassDeclaration);
|
srcProgram, '/src/missing-class.js', 'MissingClass2', ts.isClassDeclaration);
|
||||||
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
||||||
|
|
||||||
expect(host.getDtsDeclarationOfClass(missingClass)).toBe(null);
|
expect(host.getDtsDeclaration(missingClass)).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should find the dts file that contains a matching class declaration, even if the source files do not match',
|
it('should find the dts file that contains a matching class declaration, even if the source files do not match',
|
||||||
|
@ -1318,7 +1330,7 @@ describe('Fesm2015ReflectionHost', () => {
|
||||||
getDeclaration(srcProgram, '/src/flat-file.js', 'Class1', ts.isClassDeclaration);
|
getDeclaration(srcProgram, '/src/flat-file.js', 'Class1', ts.isClassDeclaration);
|
||||||
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
||||||
|
|
||||||
const dtsDeclaration = host.getDtsDeclarationOfClass(class1);
|
const dtsDeclaration = host.getDtsDeclaration(class1);
|
||||||
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/class1.d.ts');
|
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/class1.d.ts');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1329,7 +1341,7 @@ describe('Fesm2015ReflectionHost', () => {
|
||||||
getDeclaration(srcProgram, '/src/flat-file.js', 'Class3', ts.isClassDeclaration);
|
getDeclaration(srcProgram, '/src/flat-file.js', 'Class3', ts.isClassDeclaration);
|
||||||
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
||||||
|
|
||||||
const dtsDeclaration = host.getDtsDeclarationOfClass(class3);
|
const dtsDeclaration = host.getDtsDeclaration(class3);
|
||||||
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/class3.d.ts');
|
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/class3.d.ts');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1341,7 +1353,7 @@ describe('Fesm2015ReflectionHost', () => {
|
||||||
getDeclaration(srcProgram, '/src/internal.js', 'InternalClass', ts.isClassDeclaration);
|
getDeclaration(srcProgram, '/src/internal.js', 'InternalClass', ts.isClassDeclaration);
|
||||||
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
||||||
|
|
||||||
const dtsDeclaration = host.getDtsDeclarationOfClass(internalClass);
|
const dtsDeclaration = host.getDtsDeclaration(internalClass);
|
||||||
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/internal.d.ts');
|
expect(dtsDeclaration !.getSourceFile().fileName).toEqual('/typings/internal.d.ts');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1355,10 +1367,10 @@ describe('Fesm2015ReflectionHost', () => {
|
||||||
getDeclaration(srcProgram, '/src/internal.js', 'Class2', ts.isClassDeclaration);
|
getDeclaration(srcProgram, '/src/internal.js', 'Class2', ts.isClassDeclaration);
|
||||||
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
const host = new Esm2015ReflectionHost(false, srcProgram.getTypeChecker(), dts);
|
||||||
|
|
||||||
const class2DtsDeclaration = host.getDtsDeclarationOfClass(class2);
|
const class2DtsDeclaration = host.getDtsDeclaration(class2);
|
||||||
expect(class2DtsDeclaration !.getSourceFile().fileName).toEqual('/typings/class2.d.ts');
|
expect(class2DtsDeclaration !.getSourceFile().fileName).toEqual('/typings/class2.d.ts');
|
||||||
|
|
||||||
const internalClass2DtsDeclaration = host.getDtsDeclarationOfClass(internalClass2);
|
const internalClass2DtsDeclaration = host.getDtsDeclaration(internalClass2);
|
||||||
expect(internalClass2DtsDeclaration !.getSourceFile().fileName)
|
expect(internalClass2DtsDeclaration !.getSourceFile().fileName)
|
||||||
.toEqual('/typings/class2.d.ts');
|
.toEqual('/typings/class2.d.ts');
|
||||||
});
|
});
|
||||||
|
|
|
@ -109,7 +109,7 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
|
||||||
const valueContext = node.getSourceFile();
|
const valueContext = node.getSourceFile();
|
||||||
|
|
||||||
let typeContext = valueContext;
|
let typeContext = valueContext;
|
||||||
const typeNode = this.reflector.getDtsDeclarationOfClass(node);
|
const typeNode = this.reflector.getDtsDeclaration(node);
|
||||||
if (typeNode !== null) {
|
if (typeNode !== null) {
|
||||||
typeContext = typeNode.getSourceFile();
|
typeContext = typeNode.getSourceFile();
|
||||||
}
|
}
|
||||||
|
@ -183,8 +183,8 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
|
||||||
return toR3Reference(valueRef, valueRef, valueContext, valueContext);
|
return toR3Reference(valueRef, valueRef, valueContext, valueContext);
|
||||||
} else {
|
} else {
|
||||||
let typeRef = valueRef;
|
let typeRef = valueRef;
|
||||||
let typeNode = this.reflector.getDtsDeclarationOfClass(typeRef.node);
|
let typeNode = this.reflector.getDtsDeclaration(typeRef.node);
|
||||||
if (typeNode !== null) {
|
if (typeNode !== null && ts.isClassDeclaration(typeNode)) {
|
||||||
typeRef = new ResolvedReference(typeNode, typeNode.name !);
|
typeRef = new ResolvedReference(typeNode, typeNode.name !);
|
||||||
}
|
}
|
||||||
return toR3Reference(valueRef, typeRef, valueContext, typeContext);
|
return toR3Reference(valueRef, typeRef, valueContext, typeContext);
|
||||||
|
|
|
@ -448,7 +448,7 @@ export interface ReflectionHost {
|
||||||
getVariableValue(declaration: ts.VariableDeclaration): ts.Expression|null;
|
getVariableValue(declaration: ts.VariableDeclaration): ts.Expression|null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Take an exported declaration of a class (maybe downleveled to a variable) and look up the
|
* Take an exported declaration (maybe a class down-leveled to a variable) and look up the
|
||||||
* declaration of its type in a separate .d.ts tree.
|
* declaration of its type in a separate .d.ts tree.
|
||||||
*
|
*
|
||||||
* This function is allowed to return `null` if the current compilation unit does not have a
|
* This function is allowed to return `null` if the current compilation unit does not have a
|
||||||
|
@ -456,8 +456,8 @@ export interface ReflectionHost {
|
||||||
* are produced only during the emit of such a compilation. When compiling .js code, however,
|
* are produced only during the emit of such a compilation. When compiling .js code, however,
|
||||||
* there is frequently a parallel .d.ts tree which this method exposes.
|
* there is frequently a parallel .d.ts tree which this method exposes.
|
||||||
*
|
*
|
||||||
* Note that the `ts.ClassDeclaration` returned from this function may not be from the same
|
* Note that the `ts.Declaration` returned from this function may not be from the same
|
||||||
* `ts.Program` as the input declaration.
|
* `ts.Program` as the input declaration.
|
||||||
*/
|
*/
|
||||||
getDtsDeclarationOfClass(declaration: ts.Declaration): ts.ClassDeclaration|null;
|
getDtsDeclaration(declaration: ts.Declaration): ts.Declaration|null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ export class TypeScriptReflectionHost implements ReflectionHost {
|
||||||
return declaration.initializer || null;
|
return declaration.initializer || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDtsDeclarationOfClass(_: ts.Declaration): ts.ClassDeclaration|null { return null; }
|
getDtsDeclaration(_: ts.Declaration): ts.Declaration|null { return null; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve a `ts.Symbol` to its declaration, keeping track of the `viaModule` along the way.
|
* Resolve a `ts.Symbol` to its declaration, keeping track of the `viaModule` along the way.
|
||||||
|
|
Loading…
Reference in New Issue