Previously the `ConcreteDeclaration` and `InlineDeclaration` had different properties for the underlying node type. And the `InlineDeclaration` did not store a value that represented its declaration. It turns out that a natural declaration node for an inline type is the expression. For example in UMD/CommonJS this would be the `exports.<name>` property access node. So this expression is now used for the `node` of `InlineDeclaration` types and the `expression` property is dropped. To support this the codebase has been refactored to use a new `DeclarationNode` type which is a union of `ts.Declaration|ts.Expression` instead of `ts.Declaration` throughout. PR Close #38959 PR Close #39272
This commit is contained in:

committed by
atscott

parent
6acf117386
commit
26988f0d62
@ -10,7 +10,7 @@ import * as ts from 'typescript';
|
||||
import {ReferencesRegistry} from '../../../src/ngtsc/annotations';
|
||||
import {Reference} from '../../../src/ngtsc/imports';
|
||||
import {PartialEvaluator} from '../../../src/ngtsc/partial_evaluator';
|
||||
import {ClassDeclaration, isNamedClassDeclaration, isNamedVariableDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {ClassDeclaration, DeclarationNode, isNamedClassDeclaration, isNamedVariableDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {NgccReflectionHost} from '../host/ngcc_host';
|
||||
import {hasNameIdentifier, isDefined} from '../utils';
|
||||
|
||||
@ -30,7 +30,7 @@ export interface ModuleWithProvidersInfo {
|
||||
/**
|
||||
* Declaration of the containing class (if this is a method)
|
||||
*/
|
||||
container: ts.Declaration|null;
|
||||
container: DeclarationNode|null;
|
||||
/**
|
||||
* The declaration of the class that the `ngModule` property on the `ModuleWithProviders` object
|
||||
* refers to.
|
||||
@ -125,7 +125,7 @@ export class ModuleWithProvidersAnalyzer {
|
||||
*/
|
||||
private parseForModuleWithProviders(
|
||||
name: string, node: ts.Node|null, implementation: ts.Node|null = node,
|
||||
container: ts.Declaration|null = null): ModuleWithProvidersInfo|null {
|
||||
container: DeclarationNode|null = null): ModuleWithProvidersInfo|null {
|
||||
if (implementation === null ||
|
||||
(!ts.isFunctionDeclaration(implementation) && !ts.isMethodDeclaration(implementation) &&
|
||||
!ts.isFunctionExpression(implementation))) {
|
||||
|
@ -9,7 +9,7 @@
|
||||
import * as ts from 'typescript';
|
||||
import {ReferencesRegistry} from '../../../src/ngtsc/annotations';
|
||||
import {Reference} from '../../../src/ngtsc/imports';
|
||||
import {ConcreteDeclaration, ReflectionHost} from '../../../src/ngtsc/reflection';
|
||||
import {Declaration, DeclarationNode, ReflectionHost} from '../../../src/ngtsc/reflection';
|
||||
import {hasNameIdentifier} from '../utils';
|
||||
|
||||
/**
|
||||
@ -20,7 +20,7 @@ import {hasNameIdentifier} from '../utils';
|
||||
* from libraries that are compiled by ngcc.
|
||||
*/
|
||||
export class NgccReferencesRegistry implements ReferencesRegistry {
|
||||
private map = new Map<ts.Identifier, ConcreteDeclaration>();
|
||||
private map = new Map<ts.Identifier, Declaration>();
|
||||
|
||||
constructor(private host: ReflectionHost) {}
|
||||
|
||||
@ -29,12 +29,12 @@ export class NgccReferencesRegistry implements ReferencesRegistry {
|
||||
* Only `ResolveReference` references are stored. Other types are ignored.
|
||||
* @param references A collection of references to register.
|
||||
*/
|
||||
add(source: ts.Declaration, ...references: Reference<ts.Declaration>[]): void {
|
||||
add(source: DeclarationNode, ...references: Reference<DeclarationNode>[]): void {
|
||||
references.forEach(ref => {
|
||||
// Only store relative references. We are not interested in literals.
|
||||
if (ref.bestGuessOwningModule === null && hasNameIdentifier(ref.node)) {
|
||||
const declaration = this.host.getDeclarationOfIdentifier(ref.node.name);
|
||||
if (declaration && declaration.node !== null && hasNameIdentifier(declaration.node)) {
|
||||
if (declaration && hasNameIdentifier(declaration.node)) {
|
||||
this.map.set(declaration.node.name, declaration);
|
||||
}
|
||||
}
|
||||
@ -45,7 +45,7 @@ export class NgccReferencesRegistry implements ReferencesRegistry {
|
||||
* Create and return a mapping for the registered resolved references.
|
||||
* @returns A map of reference identifiers to reference declarations.
|
||||
*/
|
||||
getDeclarationMap(): Map<ts.Identifier, ConcreteDeclaration> {
|
||||
getDeclarationMap(): Map<ts.Identifier, Declaration> {
|
||||
return this.map;
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {absoluteFromSourceFile, AbsoluteFsPath} from '../../../src/ngtsc/file_system';
|
||||
import {ConcreteDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {Declaration} from '../../../src/ngtsc/reflection';
|
||||
import {NgccReflectionHost} from '../host/ngcc_host';
|
||||
import {hasNameIdentifier, isDefined} from '../utils';
|
||||
|
||||
@ -40,8 +40,8 @@ export class PrivateDeclarationsAnalyzer {
|
||||
|
||||
private getPrivateDeclarations(
|
||||
rootFiles: ts.SourceFile[],
|
||||
declarations: Map<ts.Identifier, ConcreteDeclaration>): PrivateDeclarationsAnalyses {
|
||||
const privateDeclarations: Map<ts.Identifier, ConcreteDeclaration> = new Map(declarations);
|
||||
declarations: Map<ts.Identifier, Declaration>): PrivateDeclarationsAnalyses {
|
||||
const privateDeclarations: Map<ts.Identifier, Declaration> = new Map(declarations);
|
||||
|
||||
rootFiles.forEach(f => {
|
||||
const exports = this.host.getExportsOfModule(f);
|
||||
|
@ -10,7 +10,7 @@ import * as ts from 'typescript';
|
||||
|
||||
import {absoluteFrom} from '../../../src/ngtsc/file_system';
|
||||
import {Logger} from '../../../src/ngtsc/logging';
|
||||
import {Declaration, Import} from '../../../src/ngtsc/reflection';
|
||||
import {Declaration, DeclarationKind, Import} from '../../../src/ngtsc/reflection';
|
||||
import {BundleProgram} from '../packages/bundle_program';
|
||||
import {FactoryMap, isDefined} from '../utils';
|
||||
|
||||
@ -181,7 +181,7 @@ export class CommonJsReflectionHost extends Esm5ReflectionHost {
|
||||
} else {
|
||||
return {
|
||||
name,
|
||||
declaration: {node: null, known: null, expression, viaModule: null},
|
||||
declaration: {node: expression, known: null, kind: DeclarationKind.Inline, viaModule: null},
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -204,7 +204,7 @@ export class CommonJsReflectionHost extends Esm5ReflectionHost {
|
||||
return null;
|
||||
}
|
||||
const viaModule = isExternalImport(importPath) ? importPath : null;
|
||||
return {node: module, known: null, viaModule, identity: null};
|
||||
return {node: module, known: null, viaModule, identity: null, kind: DeclarationKind.Concrete};
|
||||
}
|
||||
|
||||
private resolveModuleName(moduleName: string, containingFile: ts.SourceFile): ts.SourceFile
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ClassDeclaration, ClassMember, CtorParameter, Declaration, Decorator, FunctionDefinition, Import, ReflectionHost} from '../../../src/ngtsc/reflection';
|
||||
import {ClassDeclaration, ClassMember, CtorParameter, Declaration, DeclarationNode, Decorator, FunctionDefinition, Import, ReflectionHost} from '../../../src/ngtsc/reflection';
|
||||
import {isFromDtsFile} from '../../../src/ngtsc/util/src/typescript';
|
||||
|
||||
import {NgccClassSymbol, NgccReflectionHost, SwitchableVariableDeclaration} from './ngcc_host';
|
||||
@ -38,7 +38,7 @@ export class DelegatingReflectionHost implements NgccReflectionHost {
|
||||
return this.ngccHost.getDeclarationOfIdentifier(id);
|
||||
}
|
||||
|
||||
getDecoratorsOfDeclaration(declaration: ts.Declaration): Decorator[]|null {
|
||||
getDecoratorsOfDeclaration(declaration: DeclarationNode): Decorator[]|null {
|
||||
if (isFromDtsFile(declaration)) {
|
||||
return this.tsHost.getDecoratorsOfDeclaration(declaration);
|
||||
}
|
||||
@ -52,7 +52,7 @@ export class DelegatingReflectionHost implements NgccReflectionHost {
|
||||
return this.ngccHost.getDefinitionOfFunction(fn);
|
||||
}
|
||||
|
||||
getDtsDeclaration(declaration: ts.Declaration): ts.Declaration|null {
|
||||
getDtsDeclaration(declaration: DeclarationNode): ts.Declaration|null {
|
||||
if (isFromDtsFile(declaration)) {
|
||||
return this.tsHost.getDtsDeclaration(declaration);
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import * as ts from 'typescript';
|
||||
|
||||
import {absoluteFromSourceFile} from '../../../src/ngtsc/file_system';
|
||||
import {Logger} from '../../../src/ngtsc/logging';
|
||||
import {ClassDeclaration, ClassMember, ClassMemberKind, CtorParameter, Declaration, Decorator, EnumMember, Import, isDecoratorIdentifier, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, reflectObjectLiteral, SpecialDeclarationKind, TypeScriptReflectionHost, TypeValueReference, TypeValueReferenceKind, ValueUnavailableKind} from '../../../src/ngtsc/reflection';
|
||||
import {ClassDeclaration, ClassMember, ClassMemberKind, CtorParameter, Declaration, DeclarationNode, Decorator, EnumMember, Import, isConcreteDeclaration, isDecoratorIdentifier, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, reflectObjectLiteral, SpecialDeclarationKind, TypeScriptReflectionHost, TypeValueReference, TypeValueReferenceKind, ValueUnavailableKind} from '../../../src/ngtsc/reflection';
|
||||
import {isWithinPackage} from '../analysis/util';
|
||||
import {BundleProgram} from '../packages/bundle_program';
|
||||
import {findAll, getNameText, hasNameIdentifier, isDefined, stripDollarSuffix} from '../utils';
|
||||
@ -58,7 +58,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
* tree. Note that by definition the key and value declarations will not be in the same TS
|
||||
* program.
|
||||
*/
|
||||
protected publicDtsDeclarationMap: Map<ts.Declaration, ts.Declaration>|null = null;
|
||||
protected publicDtsDeclarationMap: Map<DeclarationNode, ts.Declaration>|null = null;
|
||||
/**
|
||||
* A mapping from source declarations to typings declarations, which are not publicly exported.
|
||||
*
|
||||
@ -66,7 +66,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
* the same name in both the source and the dts file. Note that by definition the key and value
|
||||
* declarations will not be in the same TS program.
|
||||
*/
|
||||
protected privateDtsDeclarationMap: Map<ts.Declaration, ts.Declaration>|null = null;
|
||||
protected privateDtsDeclarationMap: Map<DeclarationNode, ts.Declaration>|null = null;
|
||||
|
||||
/**
|
||||
* The set of source files that have already been preprocessed.
|
||||
@ -88,7 +88,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
*
|
||||
* This map is populated during the preprocessing of each source file.
|
||||
*/
|
||||
protected aliasedClassDeclarations = new Map<ts.Declaration, ts.Identifier>();
|
||||
protected aliasedClassDeclarations = new Map<DeclarationNode, ts.Identifier>();
|
||||
|
||||
/**
|
||||
* Caches the information of the decorators on a class, as the work involved with extracting
|
||||
@ -140,16 +140,17 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
* Examine a declaration (for example, of a class or function) and return metadata about any
|
||||
* decorators present on the declaration.
|
||||
*
|
||||
* @param declaration a TypeScript `ts.Declaration` node representing the class or function over
|
||||
* which to reflect. For example, if the intent is to reflect the decorators of a class and the
|
||||
* source is in ES6 format, this will be a `ts.ClassDeclaration` node. If the source is in ES5
|
||||
* format, this might be a `ts.VariableDeclaration` as classes in ES5 are represented as the
|
||||
* result of an IIFE execution.
|
||||
* @param declaration a TypeScript node representing the class or function over which to reflect.
|
||||
* For example, if the intent is to reflect the decorators of a class and the source is in ES6
|
||||
* format, this will be a `ts.ClassDeclaration` node. If the source is in ES5 format, this
|
||||
* might be a `ts.VariableDeclaration` as classes in ES5 are represented as the result of an
|
||||
* IIFE execution.
|
||||
*
|
||||
* @returns an array of `Decorator` metadata if decorators are present on the declaration, or
|
||||
* `null` if either no decorators were present or if the declaration is not of a decoratable type.
|
||||
* `null` if either no decorators were present or if the declaration is not of a decoratable
|
||||
* type.
|
||||
*/
|
||||
getDecoratorsOfDeclaration(declaration: ts.Declaration): Decorator[]|null {
|
||||
getDecoratorsOfDeclaration(declaration: DeclarationNode): Decorator[]|null {
|
||||
const symbol = this.getClassSymbol(declaration);
|
||||
if (!symbol) {
|
||||
return null;
|
||||
@ -280,13 +281,14 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
getDeclarationOfIdentifier(id: ts.Identifier): Declaration|null {
|
||||
const superDeclaration = super.getDeclarationOfIdentifier(id);
|
||||
|
||||
// If no declaration was found or it's an inline declaration, return as is.
|
||||
if (superDeclaration === null || superDeclaration.node === null) {
|
||||
// If no declaration was found, return.
|
||||
if (superDeclaration === null) {
|
||||
return superDeclaration;
|
||||
}
|
||||
|
||||
// If the declaration already has traits assigned to it, return as is.
|
||||
if (superDeclaration.known !== null || superDeclaration.identity !== null) {
|
||||
if (superDeclaration.known !== null ||
|
||||
isConcreteDeclaration(superDeclaration) && superDeclaration.identity !== null) {
|
||||
return superDeclaration;
|
||||
}
|
||||
|
||||
@ -302,7 +304,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
const declaration = outerNode !== null && isNamedVariableDeclaration(outerNode) ?
|
||||
this.getDeclarationOfIdentifier(outerNode.name) :
|
||||
superDeclaration;
|
||||
if (declaration === null || declaration.node === null || declaration.known !== null) {
|
||||
if (declaration === null || declaration.known !== null ||
|
||||
isConcreteDeclaration(declaration) && declaration.identity !== null) {
|
||||
return declaration;
|
||||
}
|
||||
|
||||
@ -314,7 +317,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
}
|
||||
|
||||
// Variable declarations may represent an enum declaration, so attempt to resolve its members.
|
||||
if (ts.isVariableDeclaration(declaration.node)) {
|
||||
if (isConcreteDeclaration(declaration) && ts.isVariableDeclaration(declaration.node)) {
|
||||
const enumMembers = this.resolveEnumMembers(declaration.node);
|
||||
if (enumMembers !== null) {
|
||||
declaration.identity = {kind: SpecialDeclarationKind.DownleveledEnum, enumMembers};
|
||||
@ -450,7 +453,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
* Note that the `ts.ClassDeclaration` returned from this function may not be from the same
|
||||
* `ts.Program` as the input declaration.
|
||||
*/
|
||||
getDtsDeclaration(declaration: ts.Declaration): ts.Declaration|null {
|
||||
getDtsDeclaration(declaration: DeclarationNode): ts.Declaration|null {
|
||||
if (this.dts === null) {
|
||||
return null;
|
||||
}
|
||||
@ -777,7 +780,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
* @returns The original identifier that the given class declaration resolves to, or `undefined`
|
||||
* if the declaration does not represent an aliased class.
|
||||
*/
|
||||
protected resolveAliasedClassIdentifier(declaration: ts.Declaration): ts.Identifier|null {
|
||||
protected resolveAliasedClassIdentifier(declaration: DeclarationNode): ts.Identifier|null {
|
||||
this.ensurePreprocessed(declaration.getSourceFile());
|
||||
return this.aliasedClassDeclarations.has(declaration) ?
|
||||
this.aliasedClassDeclarations.get(declaration)! :
|
||||
@ -829,7 +832,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
const aliasedIdentifier = initializer.left;
|
||||
|
||||
const aliasedDeclaration = this.getDeclarationOfIdentifier(aliasedIdentifier);
|
||||
if (aliasedDeclaration === null || aliasedDeclaration.node === null) {
|
||||
if (aliasedDeclaration === null) {
|
||||
throw new Error(
|
||||
`Unable to locate declaration of ${aliasedIdentifier.text} in "${statement.getText()}"`);
|
||||
}
|
||||
@ -1628,7 +1631,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
|
||||
const imp = this.getImportOfExpression(typeExpression);
|
||||
const decl = this.getDeclarationOfExpression(typeExpression);
|
||||
if (imp === null || decl === null || decl.node === null) {
|
||||
if (imp === null || decl === null) {
|
||||
return {
|
||||
kind: TypeValueReferenceKind.LOCAL,
|
||||
expression: typeExpression,
|
||||
@ -1788,8 +1791,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
* @returns a map of source declarations to typings declarations.
|
||||
*/
|
||||
protected computePublicDtsDeclarationMap(src: BundleProgram, dts: BundleProgram):
|
||||
Map<ts.Declaration, ts.Declaration> {
|
||||
const declarationMap = new Map<ts.Declaration, ts.Declaration>();
|
||||
Map<DeclarationNode, ts.Declaration> {
|
||||
const declarationMap = new Map<DeclarationNode, ts.Declaration>();
|
||||
const dtsDeclarationMap = new Map<string, ts.Declaration>();
|
||||
const rootDts = getRootFileOrFail(dts);
|
||||
this.collectDtsExportedDeclarations(dtsDeclarationMap, rootDts, dts.program.getTypeChecker());
|
||||
@ -1812,8 +1815,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
* @returns a map of source declarations to typings declarations.
|
||||
*/
|
||||
protected computePrivateDtsDeclarationMap(src: BundleProgram, dts: BundleProgram):
|
||||
Map<ts.Declaration, ts.Declaration> {
|
||||
const declarationMap = new Map<ts.Declaration, ts.Declaration>();
|
||||
Map<DeclarationNode, ts.Declaration> {
|
||||
const declarationMap = new Map<DeclarationNode, ts.Declaration>();
|
||||
const dtsDeclarationMap = new Map<string, ts.Declaration>();
|
||||
const typeChecker = dts.program.getTypeChecker();
|
||||
|
||||
@ -1855,13 +1858,13 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
|
||||
|
||||
protected collectSrcExportedDeclarations(
|
||||
declarationMap: Map<ts.Declaration, ts.Declaration>,
|
||||
declarationMap: Map<DeclarationNode, ts.Declaration>,
|
||||
dtsDeclarationMap: Map<string, ts.Declaration>, srcFile: ts.SourceFile): void {
|
||||
const fileExports = this.getExportsOfModule(srcFile);
|
||||
if (fileExports !== null) {
|
||||
for (const [exportName, {node: declaration}] of fileExports) {
|
||||
if (declaration !== null && dtsDeclarationMap.has(exportName)) {
|
||||
declarationMap.set(declaration, dtsDeclarationMap.get(exportName)!);
|
||||
for (const [exportName, {node: declarationNode}] of fileExports) {
|
||||
if (dtsDeclarationMap.has(exportName)) {
|
||||
declarationMap.set(declarationNode, dtsDeclarationMap.get(exportName)!);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1877,7 +1880,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
}
|
||||
|
||||
const namespaceDecl = this.getDeclarationOfIdentifier(expression.expression);
|
||||
if (!namespaceDecl || namespaceDecl.node === null || !ts.isSourceFile(namespaceDecl.node)) {
|
||||
if (!namespaceDecl || !ts.isSourceFile(namespaceDecl.node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -1896,9 +1899,6 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
|
||||
/** Checks if the specified declaration resolves to the known JavaScript global `Object`. */
|
||||
protected isJavaScriptObjectDeclaration(decl: Declaration): boolean {
|
||||
if (decl.node === null) {
|
||||
return false;
|
||||
}
|
||||
const node = decl.node;
|
||||
// The default TypeScript library types the global `Object` variable through
|
||||
// a variable declaration with a type reference resolving to `ObjectConstructor`.
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ClassDeclaration, ClassMember, ClassMemberKind, Declaration, Decorator, FunctionDefinition, isNamedFunctionDeclaration, KnownDeclaration, Parameter, reflectObjectLiteral} from '../../../src/ngtsc/reflection';
|
||||
import {ClassDeclaration, ClassMember, ClassMemberKind, Declaration, DeclarationKind, Decorator, FunctionDefinition, isNamedFunctionDeclaration, KnownDeclaration, Parameter, reflectObjectLiteral} from '../../../src/ngtsc/reflection';
|
||||
import {getTsHelperFnFromDeclaration, getTsHelperFnFromIdentifier, hasNameIdentifier} from '../utils';
|
||||
|
||||
import {Esm2015ReflectionHost, getOuterNodeFromInnerDeclaration, getPropertyValueFromSymbol, isAssignmentStatement, ParamInfo} from './esm2015_host';
|
||||
@ -82,9 +82,9 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost {
|
||||
// `importHelpers: false` (the default). This is, for example, the case with
|
||||
// `@nativescript/angular@9.0.0-next-2019-11-12-155500-01`.
|
||||
return {
|
||||
expression: id,
|
||||
kind: DeclarationKind.Inline,
|
||||
node: id,
|
||||
known: nonEmittedNorImportedTsHelperDeclaration,
|
||||
node: null,
|
||||
viaModule: null,
|
||||
};
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import * as ts from 'typescript';
|
||||
|
||||
import {absoluteFrom} from '../../../src/ngtsc/file_system';
|
||||
import {Logger} from '../../../src/ngtsc/logging';
|
||||
import {Declaration, Import} from '../../../src/ngtsc/reflection';
|
||||
import {Declaration, DeclarationKind, Import} from '../../../src/ngtsc/reflection';
|
||||
import {BundleProgram} from '../packages/bundle_program';
|
||||
import {FactoryMap, getTsHelperFnFromIdentifier, stripExtension} from '../utils';
|
||||
|
||||
@ -172,17 +172,8 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
|
||||
|
||||
const viaModule = stripExtension(importedFile.fileName);
|
||||
const reexports: ExportDeclaration[] = [];
|
||||
importedExports.forEach((decl, name) => {
|
||||
if (decl.node !== null) {
|
||||
reexports.push({
|
||||
name,
|
||||
declaration: {node: decl.node, known: null, viaModule, identity: decl.identity}
|
||||
});
|
||||
} else {
|
||||
reexports.push(
|
||||
{name, declaration: {node: null, known: null, expression: decl.expression, viaModule}});
|
||||
}
|
||||
});
|
||||
importedExports.forEach(
|
||||
(decl, name) => reexports.push({name, declaration: {...decl, viaModule}}));
|
||||
return reexports;
|
||||
}
|
||||
|
||||
@ -204,7 +195,7 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
|
||||
}
|
||||
return {
|
||||
name,
|
||||
declaration: {node: null, known: null, expression, viaModule: null},
|
||||
declaration: {kind: DeclarationKind.Inline, node: expression, known: null, viaModule: null},
|
||||
};
|
||||
}
|
||||
|
||||
@ -255,22 +246,31 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Sadly, in the case of `exports.foo = bar`, we can't use `this.findUmdImportParameter(id)` to
|
||||
// check whether this `exports` is from the IIFE body arguments, because
|
||||
// `this.checker.getSymbolAtLocation(id)` will return the symbol for the `foo` identifier rather
|
||||
// than the `exports` identifier.
|
||||
// Sadly, in the case of `exports.foo = bar`, we can't use `this.findUmdImportParameter(id)`
|
||||
// to check whether this `exports` is from the IIFE body arguments, because
|
||||
// `this.checker.getSymbolAtLocation(id)` will return the symbol for the `foo` identifier
|
||||
// rather than the `exports` identifier.
|
||||
//
|
||||
// Instead we search the symbols in the current local scope.
|
||||
const exportsSymbol = this.checker.getSymbolsInScope(id, ts.SymbolFlags.Variable)
|
||||
.find(symbol => symbol.name === 'exports');
|
||||
if (exportsSymbol !== undefined &&
|
||||
!ts.isFunctionExpression(exportsSymbol.valueDeclaration.parent)) {
|
||||
// There is an `exports` symbol in the local scope that is not a function parameter.
|
||||
// So this `exports` identifier must be a local variable and does not represent the module.
|
||||
return {node: exportsSymbol.valueDeclaration, viaModule: null, known: null, identity: null};
|
||||
}
|
||||
|
||||
return {node: id.getSourceFile(), viaModule: null, known: null, identity: null};
|
||||
const node = exportsSymbol !== undefined &&
|
||||
!ts.isFunctionExpression(exportsSymbol.valueDeclaration.parent) ?
|
||||
// There is a locally defined `exports` variable that is not a function parameter.
|
||||
// So this `exports` identifier must be a local variable and does not represent the module.
|
||||
exportsSymbol.valueDeclaration :
|
||||
// There is no local symbol or it is a parameter of an IIFE.
|
||||
// So this `exports` represents the current "module".
|
||||
id.getSourceFile();
|
||||
|
||||
return {
|
||||
kind: DeclarationKind.Concrete,
|
||||
node,
|
||||
viaModule: null,
|
||||
known: null,
|
||||
identity: null,
|
||||
};
|
||||
}
|
||||
|
||||
private getUmdModuleDeclaration(id: ts.Identifier): Declaration|null {
|
||||
@ -285,7 +285,7 @@ export class UmdReflectionHost extends Esm5ReflectionHost {
|
||||
}
|
||||
|
||||
const viaModule = isExternalImport(importPath) ? importPath : null;
|
||||
return {node: module, viaModule, known: null, identity: null};
|
||||
return {kind: DeclarationKind.Concrete, node: module, viaModule, known: null, identity: null};
|
||||
}
|
||||
|
||||
private getImportPathFromParameter(id: ts.Identifier): string|null {
|
||||
|
@ -151,7 +151,7 @@ function migrateProviderClass(provider: ResolvedValue, host: MigrationHost): voi
|
||||
return;
|
||||
}
|
||||
|
||||
const clazz = provider.node as ts.Declaration;
|
||||
const clazz = provider.node;
|
||||
if (isClassDeclaration(clazz) && host.isInScope(clazz) && needsInjectableDecorator(clazz, host)) {
|
||||
host.injectSyntheticDecorator(clazz, createInjectableDecorator(clazz));
|
||||
}
|
||||
|
@ -101,7 +101,7 @@ function determineBaseClass(
|
||||
}
|
||||
|
||||
const baseClass = host.evaluator.evaluate(baseClassExpr);
|
||||
if (!(baseClass instanceof Reference) || !isClassDeclaration(baseClass.node as ts.Declaration)) {
|
||||
if (!(baseClass instanceof Reference) || !isClassDeclaration(baseClass.node)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import {Reference} from '../../../src/ngtsc/imports';
|
||||
import {ClassDeclaration, Decorator, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {MigrationHost} from './migration';
|
||||
|
||||
export function isClassDeclaration(clazz: ts.Declaration): clazz is ClassDeclaration {
|
||||
export function isClassDeclaration(clazz: ts.Node): clazz is ClassDeclaration<ts.Declaration> {
|
||||
return isNamedClassDeclaration(clazz) || isNamedFunctionDeclaration(clazz) ||
|
||||
isNamedVariableDeclaration(clazz);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {absoluteFrom, AbsoluteFsPath, FileSystem, isRooted} from '../../src/ngtsc/file_system';
|
||||
import {KnownDeclaration} from '../../src/ngtsc/reflection';
|
||||
import {DeclarationNode, KnownDeclaration} from '../../src/ngtsc/reflection';
|
||||
|
||||
/**
|
||||
* A list (`Array`) of partially ordered `T` items.
|
||||
@ -71,7 +71,7 @@ export function findAll<T>(node: ts.Node, test: (node: ts.Node) => node is ts.No
|
||||
* @param declaration The declaration to test.
|
||||
* @returns true if the declaration has an identifier for a name.
|
||||
*/
|
||||
export function hasNameIdentifier(declaration: ts.Node): declaration is ts.Declaration&
|
||||
export function hasNameIdentifier(declaration: ts.Node): declaration is DeclarationNode&
|
||||
{name: ts.Identifier} {
|
||||
const namedDeclaration: ts.Node&{name?: ts.Node} = declaration;
|
||||
return namedDeclaration.name !== undefined && ts.isIdentifier(namedDeclaration.name);
|
||||
@ -136,7 +136,7 @@ export function resolveFileWithPostfixes(
|
||||
* Determine whether a function declaration corresponds with a TypeScript helper function, returning
|
||||
* its kind if so or null if the declaration does not seem to correspond with such a helper.
|
||||
*/
|
||||
export function getTsHelperFnFromDeclaration(decl: ts.Declaration): KnownDeclaration|null {
|
||||
export function getTsHelperFnFromDeclaration(decl: DeclarationNode): KnownDeclaration|null {
|
||||
if (!ts.isFunctionDeclaration(decl) && !ts.isVariableDeclaration(decl)) {
|
||||
return null;
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import {FatalDiagnosticError, makeDiagnostic} from '../../../src/ngtsc/diagnosti
|
||||
import {absoluteFrom, getFileSystem, getSourceFileOrError} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
|
||||
import {MockLogger} from '../../../src/ngtsc/logging/testing';
|
||||
import {ClassDeclaration, Decorator} from '../../../src/ngtsc/reflection';
|
||||
import {ClassDeclaration, DeclarationNode, Decorator} from '../../../src/ngtsc/reflection';
|
||||
import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence} from '../../../src/ngtsc/transform';
|
||||
import {loadFakeCore, loadTestFiles} from '../../../test/helpers';
|
||||
import {DecorationAnalyzer} from '../../src/analysis/decoration_analyzer';
|
||||
@ -52,7 +52,7 @@ runInEachFileSystem(() => {
|
||||
]);
|
||||
// Only detect the Component and Directive decorators
|
||||
handler.detect.and.callFake(
|
||||
(node: ts.Declaration, decorators: Decorator[]|null): DetectResult<unknown>|
|
||||
(node: DeclarationNode, decorators: Decorator[]|null): DetectResult<unknown>|
|
||||
undefined => {
|
||||
const className = (node as any).name.text;
|
||||
if (decorators === null) {
|
||||
@ -76,7 +76,7 @@ runInEachFileSystem(() => {
|
||||
}
|
||||
});
|
||||
// The "test" analysis is an object with the name of the decorator being analyzed
|
||||
handler.analyze.and.callFake((decl: ts.Declaration, dec: Decorator) => {
|
||||
handler.analyze.and.callFake((decl: DeclarationNode, dec: Decorator) => {
|
||||
logs.push(`analyze: ${(decl as any).name.text}@${dec.name}`);
|
||||
return {
|
||||
analysis: {decoratorName: dec.name},
|
||||
@ -85,7 +85,7 @@ runInEachFileSystem(() => {
|
||||
};
|
||||
});
|
||||
// The "test" resolution is just setting `resolved: true` on the analysis
|
||||
handler.resolve.and.callFake((decl: ts.Declaration, analysis: any) => {
|
||||
handler.resolve.and.callFake((decl: DeclarationNode, analysis: any) => {
|
||||
logs.push(`resolve: ${(decl as any).name.text}@${analysis.decoratorName}`);
|
||||
analysis.resolved = true;
|
||||
return {
|
||||
@ -95,10 +95,10 @@ runInEachFileSystem(() => {
|
||||
});
|
||||
// The "test" compilation result is just the name of the decorator being compiled
|
||||
// (suffixed with `(compiled)`)
|
||||
(handler.compile as any).and.callFake((decl: ts.Declaration, analysis: any) => {
|
||||
(handler.compile as any).and.callFake((decl: DeclarationNode, analysis: any) => {
|
||||
logs.push(`compile: ${(decl as any).name.text}@${analysis.decoratorName} (resolved: ${
|
||||
analysis.resolved})`);
|
||||
return `@${analysis.decoratorName} (compiled)`;
|
||||
return `@${analysis.decoratorName} (compiled)` as any;
|
||||
});
|
||||
return handler;
|
||||
};
|
||||
|
@ -10,7 +10,7 @@ import * as ts from 'typescript';
|
||||
import {absoluteFrom, AbsoluteFsPath, getSourceFileOrError} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
|
||||
import {MockLogger} from '../../../src/ngtsc/logging/testing';
|
||||
import {isNamedClassDeclaration, isNamedVariableDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {DeclarationNode, isNamedClassDeclaration, isNamedVariableDeclaration} from '../../../src/ngtsc/reflection';
|
||||
import {getDeclaration} from '../../../src/ngtsc/testing';
|
||||
import {loadTestFiles} from '../../../test/helpers';
|
||||
import {ModuleWithProvidersAnalyses, ModuleWithProvidersAnalyzer} from '../../src/analysis/module_with_providers_analyzer';
|
||||
@ -660,7 +660,7 @@ runInEachFileSystem(() => {
|
||||
[];
|
||||
}
|
||||
|
||||
function getName(node: ts.Declaration|null): string {
|
||||
function getName(node: DeclarationNode|null): string {
|
||||
return node && (isNamedVariableDeclaration(node) || isNamedClassDeclaration(node)) ?
|
||||
`${node.name.text}.` :
|
||||
'';
|
||||
|
@ -11,7 +11,7 @@ import {absoluteFrom} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
|
||||
import {Reference} from '../../../src/ngtsc/imports';
|
||||
import {PartialEvaluator} from '../../../src/ngtsc/partial_evaluator';
|
||||
import {TypeScriptReflectionHost} from '../../../src/ngtsc/reflection';
|
||||
import {DeclarationNode, TypeScriptReflectionHost} from '../../../src/ngtsc/reflection';
|
||||
import {getDeclaration} from '../../../src/ngtsc/testing';
|
||||
import {loadTestFiles} from '../../../test/helpers';
|
||||
import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry';
|
||||
@ -61,7 +61,7 @@ runInEachFileSystem(() => {
|
||||
});
|
||||
});
|
||||
|
||||
function isReference(ref: any): ref is Reference<ts.Declaration> {
|
||||
function isReference(ref: any): ref is Reference<DeclarationNode> {
|
||||
return ref instanceof Reference;
|
||||
}
|
||||
});
|
||||
|
@ -10,7 +10,7 @@ import * as ts from 'typescript';
|
||||
import {absoluteFrom, getFileSystem, getSourceFileOrError} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
|
||||
import {MockLogger} from '../../../src/ngtsc/logging/testing';
|
||||
import {ClassMemberKind, ConcreteDeclaration, CtorParameter, DownleveledEnum, InlineDeclaration, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, TypeScriptReflectionHost, TypeValueReferenceKind} from '../../../src/ngtsc/reflection';
|
||||
import {ClassMemberKind, ConcreteDeclaration, CtorParameter, DeclarationKind, DownleveledEnum, InlineDeclaration, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, TypeScriptReflectionHost, TypeValueReferenceKind} from '../../../src/ngtsc/reflection';
|
||||
import {getDeclaration} from '../../../src/ngtsc/testing';
|
||||
import {loadFakeCore, loadTestFiles} from '../../../test/helpers';
|
||||
import {CommonJsReflectionHost} from '../../src/host/commonjs_host';
|
||||
@ -1840,6 +1840,7 @@ exports.MissingClass2 = MissingClass2;
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Concrete,
|
||||
known: knownAs,
|
||||
node: getHelperDeclaration(helperName),
|
||||
viaModule,
|
||||
@ -2163,9 +2164,9 @@ exports.MissingClass2 = MissingClass2;
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Inline,
|
||||
known: knownAs,
|
||||
expression: helperIdentifier,
|
||||
node: null,
|
||||
node: helperIdentifier,
|
||||
viaModule: null,
|
||||
});
|
||||
};
|
||||
@ -2197,9 +2198,9 @@ exports.MissingClass2 = MissingClass2;
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Inline,
|
||||
known: knownAs,
|
||||
expression: helperIdentifier,
|
||||
node: null,
|
||||
node: helperIdentifier,
|
||||
viaModule: null,
|
||||
});
|
||||
};
|
||||
@ -2421,10 +2422,10 @@ exports.MissingClass2 = MissingClass2;
|
||||
const file = getSourceFileOrError(bundle.program, _('/inline_export.js'));
|
||||
const exportDeclarations = host.getExportsOfModule(file);
|
||||
expect(exportDeclarations).not.toBeNull();
|
||||
const decl = exportDeclarations!.get('directives') as InlineDeclaration;
|
||||
expect(decl).not.toBeUndefined();
|
||||
expect(decl.node).toBeNull();
|
||||
expect(decl.expression).toBeDefined();
|
||||
const decl = exportDeclarations!.get('directives')!;
|
||||
expect(decl).toBeDefined();
|
||||
expect(decl.node).toBeDefined();
|
||||
expect(decl.kind).toEqual(DeclarationKind.Inline);
|
||||
});
|
||||
|
||||
it('should recognize declarations of known TypeScript helpers', () => {
|
||||
|
@ -2076,7 +2076,8 @@ runInEachFileSystem(() => {
|
||||
}
|
||||
expect(classSymbol.name).toEqual('DecoratedWrappedClass');
|
||||
expect(classSymbol.declaration.valueDeclaration).toBe(outerNode);
|
||||
expect(classSymbol.implementation.valueDeclaration).toBe(innerNodes[0]);
|
||||
expect(classSymbol.implementation.valueDeclaration)
|
||||
.toBe(innerNodes[0] as ts.Declaration);
|
||||
|
||||
if (classSymbol.adjacent === undefined ||
|
||||
!isNamedVariableDeclaration(classSymbol.adjacent.valueDeclaration)) {
|
||||
@ -2112,7 +2113,8 @@ runInEachFileSystem(() => {
|
||||
}
|
||||
expect(classSymbol.name).toEqual('DecoratedWrappedClass');
|
||||
expect(classSymbol.declaration.valueDeclaration).toBe(outerNode);
|
||||
expect(classSymbol.implementation.valueDeclaration).toBe(innerNodes[0]);
|
||||
expect(classSymbol.implementation.valueDeclaration)
|
||||
.toBe(innerNodes[0] as ts.Declaration);
|
||||
|
||||
if (classSymbol.adjacent === undefined ||
|
||||
!isNamedVariableDeclaration(classSymbol.adjacent.valueDeclaration)) {
|
||||
|
@ -11,7 +11,7 @@ import * as ts from 'typescript';
|
||||
import {absoluteFrom, getFileSystem, getSourceFileOrError} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
|
||||
import {MockLogger} from '../../../src/ngtsc/logging/testing';
|
||||
import {ClassMemberKind, ConcreteDeclaration, CtorParameter, Decorator, DownleveledEnum, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, TypeScriptReflectionHost, TypeValueReferenceKind} from '../../../src/ngtsc/reflection';
|
||||
import {ClassMemberKind, ConcreteDeclaration, CtorParameter, DeclarationKind, Decorator, DownleveledEnum, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, TypeScriptReflectionHost, TypeValueReferenceKind} from '../../../src/ngtsc/reflection';
|
||||
import {getDeclaration} from '../../../src/ngtsc/testing';
|
||||
import {loadFakeCore, loadTestFiles} from '../../../test/helpers';
|
||||
import {DelegatingReflectionHost} from '../../src/host/delegating_host';
|
||||
@ -1858,6 +1858,7 @@ runInEachFileSystem(() => {
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Concrete,
|
||||
known: knownAs,
|
||||
node: getHelperDeclaration(helperName),
|
||||
viaModule,
|
||||
@ -2253,9 +2254,9 @@ runInEachFileSystem(() => {
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Inline,
|
||||
known: knownAs,
|
||||
expression: helperIdentifier,
|
||||
node: null,
|
||||
node: helperIdentifier,
|
||||
viaModule: null,
|
||||
});
|
||||
};
|
||||
@ -2284,9 +2285,9 @@ runInEachFileSystem(() => {
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Inline,
|
||||
known: knownAs,
|
||||
expression: helperIdentifier,
|
||||
node: null,
|
||||
node: helperIdentifier,
|
||||
viaModule: null,
|
||||
});
|
||||
};
|
||||
|
@ -11,7 +11,7 @@ import * as ts from 'typescript';
|
||||
import {absoluteFrom, getFileSystem, getSourceFileOrError} from '../../../src/ngtsc/file_system';
|
||||
import {runInEachFileSystem, TestFile} from '../../../src/ngtsc/file_system/testing';
|
||||
import {MockLogger} from '../../../src/ngtsc/logging/testing';
|
||||
import {ClassMemberKind, ConcreteDeclaration, CtorParameter, DownleveledEnum, Import, InlineDeclaration, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, TypeScriptReflectionHost, TypeValueReferenceKind} from '../../../src/ngtsc/reflection';
|
||||
import {ClassMemberKind, ConcreteDeclaration, CtorParameter, DeclarationKind, DownleveledEnum, Import, InlineDeclaration, isNamedClassDeclaration, isNamedFunctionDeclaration, isNamedVariableDeclaration, KnownDeclaration, TypeScriptReflectionHost, TypeValueReferenceKind} from '../../../src/ngtsc/reflection';
|
||||
import {getDeclaration} from '../../../src/ngtsc/testing';
|
||||
import {loadFakeCore, loadTestFiles} from '../../../test/helpers';
|
||||
import {isExportsStatement} from '../../src/host/commonjs_umd_utils';
|
||||
@ -2003,6 +2003,7 @@ runInEachFileSystem(() => {
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Concrete,
|
||||
known: knownAs,
|
||||
node: getHelperDeclaration(factoryFn, helperName),
|
||||
viaModule,
|
||||
@ -2410,9 +2411,9 @@ runInEachFileSystem(() => {
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Inline,
|
||||
known: knownAs,
|
||||
expression: helperIdentifier,
|
||||
node: null,
|
||||
node: helperIdentifier,
|
||||
viaModule: null,
|
||||
});
|
||||
};
|
||||
@ -2449,9 +2450,9 @@ runInEachFileSystem(() => {
|
||||
const helperDeclaration = host.getDeclarationOfIdentifier(helperIdentifier);
|
||||
|
||||
expect(helperDeclaration).toEqual({
|
||||
kind: DeclarationKind.Inline,
|
||||
known: knownAs,
|
||||
expression: helperIdentifier,
|
||||
node: null,
|
||||
node: helperIdentifier,
|
||||
viaModule: null,
|
||||
});
|
||||
};
|
||||
@ -2697,10 +2698,10 @@ runInEachFileSystem(() => {
|
||||
const file = getSourceFileOrError(bundle.program, INLINE_EXPORT_FILE.name);
|
||||
const exportDeclarations = host.getExportsOfModule(file);
|
||||
expect(exportDeclarations).not.toBe(null);
|
||||
const decl = exportDeclarations!.get('directives') as InlineDeclaration;
|
||||
expect(decl).not.toBeUndefined();
|
||||
expect(decl.node).toBeNull();
|
||||
expect(decl.expression).toBeDefined();
|
||||
const decl = exportDeclarations!.get('directives')!;
|
||||
expect(decl).toBeDefined();
|
||||
expect(decl.node).toBeDefined();
|
||||
expect(decl.kind).toEqual(DeclarationKind.Inline);
|
||||
});
|
||||
|
||||
it('should recognize declarations of known TypeScript helpers', () => {
|
||||
@ -2901,7 +2902,7 @@ runInEachFileSystem(() => {
|
||||
const classSymbol = host.getClassSymbol(outerNode);
|
||||
|
||||
expect(classSymbol).toBeDefined();
|
||||
expect(classSymbol!.declaration.valueDeclaration).toBe(outerNode);
|
||||
expect(classSymbol!.declaration.valueDeclaration).toBe(outerNode as any);
|
||||
expect(classSymbol!.implementation.valueDeclaration).toBe(innerNode);
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user