From 2279cb8dc06b6ea634f44d5f999ddde48adba659 Mon Sep 17 00:00:00 2001 From: JoostK Date: Sun, 1 Sep 2019 20:54:41 +0200 Subject: [PATCH] refactor(ngcc): move `ClassSymbol` to become `NgccClassSymbol` (#32539) PR Close #32539 --- .../ngcc/src/analysis/decoration_analyzer.ts | 5 ++- .../compiler-cli/ngcc/src/analysis/util.ts | 5 +-- .../ngcc/src/host/commonjs_host.ts | 7 ++-- .../ngcc/src/host/esm2015_host.ts | 34 ++++++++++--------- .../compiler-cli/ngcc/src/host/esm5_host.ts | 20 ++++++----- .../compiler-cli/ngcc/src/host/ngcc_host.ts | 14 +++++--- .../ngcc/test/analysis/migration_host_spec.ts | 5 +-- .../src/ngtsc/reflection/src/host.ts | 6 ---- 8 files changed, 51 insertions(+), 45 deletions(-) diff --git a/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts b/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts index 5705636e3c..71bf20d46c 100644 --- a/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts +++ b/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts @@ -14,10 +14,9 @@ import {FileSystem, LogicalFileSystem, absoluteFrom, dirname, resolve} from '../ import {AbsoluteModuleStrategy, LocalIdentifierStrategy, LogicalProjectStrategy, ModuleResolver, NOOP_DEFAULT_IMPORT_RECORDER, ReferenceEmitter} from '../../../src/ngtsc/imports'; import {CompoundMetadataReader, CompoundMetadataRegistry, DtsMetadataReader, LocalMetadataRegistry} from '../../../src/ngtsc/metadata'; import {PartialEvaluator} from '../../../src/ngtsc/partial_evaluator'; -import {ClassSymbol} from '../../../src/ngtsc/reflection'; import {LocalModuleScopeRegistry, MetadataDtsModuleScopeResolver} from '../../../src/ngtsc/scope'; import {CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence} from '../../../src/ngtsc/transform'; -import {NgccReflectionHost} from '../host/ngcc_host'; +import {NgccClassSymbol, NgccReflectionHost} from '../host/ngcc_host'; import {Migration, MigrationHost} from '../migrations/migration'; import {EntryPointBundle} from '../packages/entry_point_bundle'; import {isDefined} from '../utils'; @@ -128,7 +127,7 @@ export class DecorationAnalyzer { return analyzedClasses.length ? {sourceFile, analyzedClasses} : undefined; } - protected analyzeClass(symbol: ClassSymbol): AnalyzedClass|null { + protected analyzeClass(symbol: NgccClassSymbol): AnalyzedClass|null { const decorators = this.reflectionHost.getDecoratorsOfSymbol(symbol); const analyzedClass = analyzeDecorators(symbol, decorators, this.handlers); if (analyzedClass !== null && analyzedClass.diagnostics !== undefined) { diff --git a/packages/compiler-cli/ngcc/src/analysis/util.ts b/packages/compiler-cli/ngcc/src/analysis/util.ts index b617199ed7..2e2a540ae9 100644 --- a/packages/compiler-cli/ngcc/src/analysis/util.ts +++ b/packages/compiler-cli/ngcc/src/analysis/util.ts @@ -9,8 +9,9 @@ import * as ts from 'typescript'; import {isFatalDiagnosticError} from '../../../src/ngtsc/diagnostics'; import {AbsoluteFsPath, absoluteFromSourceFile, relative} from '../../../src/ngtsc/file_system'; -import {ClassSymbol, Decorator} from '../../../src/ngtsc/reflection'; +import {Decorator} from '../../../src/ngtsc/reflection'; import {DecoratorHandler, DetectResult, HandlerPrecedence} from '../../../src/ngtsc/transform'; +import {NgccClassSymbol} from '../host/ngcc_host'; import {AnalyzedClass, MatchingHandler} from './types'; @@ -19,7 +20,7 @@ export function isWithinPackage(packagePath: AbsoluteFsPath, sourceFile: ts.Sour } export function analyzeDecorators( - symbol: ClassSymbol, decorators: Decorator[] | null, + symbol: NgccClassSymbol, decorators: Decorator[] | null, handlers: DecoratorHandler[]): AnalyzedClass|null { const declaration = symbol.valueDeclaration; const matchingHandlers = handlers diff --git a/packages/compiler-cli/ngcc/src/host/commonjs_host.ts b/packages/compiler-cli/ngcc/src/host/commonjs_host.ts index 9b4ca11f30..e6b9ae83e6 100644 --- a/packages/compiler-cli/ngcc/src/host/commonjs_host.ts +++ b/packages/compiler-cli/ngcc/src/host/commonjs_host.ts @@ -8,12 +8,13 @@ import * as ts from 'typescript'; import {absoluteFrom} from '../../../src/ngtsc/file_system'; -import {ClassSymbol, Declaration, Import} from '../../../src/ngtsc/reflection'; +import {Declaration, Import} from '../../../src/ngtsc/reflection'; import {Logger} from '../logging/logger'; import {BundleProgram} from '../packages/bundle_program'; import {isDefined} from '../utils'; import {Esm5ReflectionHost} from './esm5_host'; +import {NgccClassSymbol} from './ngcc_host'; export class CommonJsReflectionHost extends Esm5ReflectionHost { protected commonJsExports = new Map|null>(); @@ -57,7 +58,7 @@ export class CommonJsReflectionHost extends Esm5ReflectionHost { * @param helperName the name of the helper (e.g. `__decorate`) whose calls we are interested in. * @returns an array of nodes of calls to the helper with the given name. */ - protected getHelperCallsForClass(classSymbol: ClassSymbol, helperName: string): + protected getHelperCallsForClass(classSymbol: NgccClassSymbol, helperName: string): ts.CallExpression[] { const esm5HelperCalls = super.getHelperCallsForClass(classSymbol, helperName); if (esm5HelperCalls.length > 0) { @@ -244,4 +245,4 @@ function getOrDefault(map: Map, key: K, factory: (key: K) => V): V { map.set(key, factory(key)); } return map.get(key) !; -} \ No newline at end of file +} diff --git a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts index 3fe00cc06a..927409aa8f 100644 --- a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts @@ -9,13 +9,13 @@ import * as ts from 'typescript'; import {AbsoluteFsPath} from '../../../src/ngtsc/file_system'; -import {ClassDeclaration, ClassMember, ClassMemberKind, ClassSymbol, ConcreteDeclaration, CtorParameter, Declaration, Decorator, TypeScriptReflectionHost, isDecoratorIdentifier, reflectObjectLiteral} from '../../../src/ngtsc/reflection'; +import {ClassDeclaration, ClassMember, ClassMemberKind, ConcreteDeclaration, CtorParameter, Declaration, Decorator, TypeScriptReflectionHost, isDecoratorIdentifier, reflectObjectLiteral} from '../../../src/ngtsc/reflection'; import {isWithinPackage} from '../analysis/util'; import {Logger} from '../logging/logger'; import {BundleProgram} from '../packages/bundle_program'; import {findAll, getNameText, hasNameIdentifier, isDefined, stripDollarSuffix} from '../utils'; -import {ModuleWithProvidersFunction, NgccReflectionHost, PRE_R3_MARKER, SwitchableVariableDeclaration, isSwitchableVariableDeclaration} from './ngcc_host'; +import {ModuleWithProvidersFunction, NgccClassSymbol, NgccReflectionHost, PRE_R3_MARKER, SwitchableVariableDeclaration, isSwitchableVariableDeclaration} from './ngcc_host'; export const DECORATORS = 'decorators' as ts.__String; export const PROP_DECORATORS = 'propDecorators' as ts.__String; @@ -116,10 +116,10 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @param node the node whose symbol we are finding. * @returns the symbol for the node or `undefined` if it is not a "class" or has no symbol. */ - getClassSymbol(declaration: ts.Node): ClassSymbol|undefined { + getClassSymbol(declaration: ts.Node): NgccClassSymbol|undefined { const classDeclaration = this.getClassDeclaration(declaration); return classDeclaration && - this.checker.getSymbolAtLocation(classDeclaration.name) as ClassSymbol; + this.checker.getSymbolAtLocation(classDeclaration.name) as NgccClassSymbol; } /** @@ -256,7 +256,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N } /** Gets all decorators of the given class symbol. */ - getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null { + getDecoratorsOfSymbol(symbol: NgccClassSymbol): Decorator[]|null { const {classDecorators} = this.acquireDecoratorInfo(symbol); return classDecorators; } @@ -338,8 +338,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @param sourceFile The source file to search for classes. * @returns An array of class symbols. */ - findClassSymbols(sourceFile: ts.SourceFile): ClassSymbol[] { - const classes: ClassSymbol[] = []; + findClassSymbols(sourceFile: ts.SourceFile): NgccClassSymbol[] { + const classes: NgccClassSymbol[] = []; this.getModuleStatements(sourceFile).forEach(statement => { if (ts.isVariableStatement(statement)) { statement.declarationList.declarations.forEach(declaration => { @@ -547,7 +547,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @param propertyName the name of static property. * @returns the symbol if it is found or `undefined` if not. */ - protected getStaticProperty(symbol: ClassSymbol, propertyName: ts.__String): ts.Symbol|undefined { + protected getStaticProperty(symbol: NgccClassSymbol, propertyName: ts.__String): ts.Symbol + |undefined { return symbol.exports && symbol.exports.get(propertyName); } @@ -559,7 +560,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @param classSymbol the class for which decorators should be acquired. * @returns all information of the decorators on the class. */ - protected acquireDecoratorInfo(classSymbol: ClassSymbol): DecoratorInfo { + protected acquireDecoratorInfo(classSymbol: NgccClassSymbol): DecoratorInfo { if (this.decoratorCache.has(classSymbol.valueDeclaration)) { return this.decoratorCache.get(classSymbol.valueDeclaration) !; } @@ -585,7 +586,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @returns All information on the decorators as extracted from static properties, or `null` if * none of the static properties exist. */ - protected computeDecoratorInfoFromStaticProperties(classSymbol: ClassSymbol): DecoratorInfo|null { + protected computeDecoratorInfoFromStaticProperties(classSymbol: NgccClassSymbol): DecoratorInfo + |null { let classDecorators: Decorator[]|null = null; let memberDecorators: Map|null = null; let constructorParamInfo: ParamInfo[]|null = null; @@ -651,7 +653,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @param symbol the `ClassSymbol` representing the class over which to reflect. * @returns an array of `ClassMember` metadata representing the members of the class. */ - protected getMembersOfSymbol(symbol: ClassSymbol): ClassMember[] { + protected getMembersOfSymbol(symbol: NgccClassSymbol): ClassMember[] { const members: ClassMember[] = []; // The decorators map contains all the properties that are decorated @@ -788,7 +790,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @param classSymbol The class symbol for which decorators should be extracted. * @returns All information on the decorators of the class. */ - protected computeDecoratorInfoFromHelperCalls(classSymbol: ClassSymbol): DecoratorInfo { + protected computeDecoratorInfoFromHelperCalls(classSymbol: NgccClassSymbol): DecoratorInfo { let classDecorators: Decorator[]|null = null; const memberDecorators = new Map(); const constructorParamInfo: ParamInfo[] = []; @@ -1178,7 +1180,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @returns an array of `ts.ParameterDeclaration` objects representing each of the parameters in * the class's constructor or null if there is no constructor. */ - protected getConstructorParameterDeclarations(classSymbol: ClassSymbol): + protected getConstructorParameterDeclarations(classSymbol: NgccClassSymbol): ts.ParameterDeclaration[]|null { if (classSymbol.members && classSymbol.members.has(CONSTRUCTOR)) { const constructorSymbol = classSymbol.members.get(CONSTRUCTOR) !; @@ -1207,7 +1209,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @returns an array of constructor parameter info objects. */ protected getConstructorParamInfo( - classSymbol: ClassSymbol, parameterNodes: ts.ParameterDeclaration[]): CtorParameter[] { + classSymbol: NgccClassSymbol, parameterNodes: ts.ParameterDeclaration[]): CtorParameter[] { const {constructorParamInfo} = this.acquireDecoratorInfo(classSymbol); return parameterNodes.map((node, index) => { @@ -1295,7 +1297,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * in. * @returns an array of CallExpression nodes for each matching helper call. */ - protected getHelperCallsForClass(classSymbol: ClassSymbol, helperName: string): + protected getHelperCallsForClass(classSymbol: NgccClassSymbol, helperName: string): ts.CallExpression[] { return this.getStatementsForClass(classSymbol) .map(statement => this.getHelperCall(statement, helperName)) @@ -1311,7 +1313,7 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N * @param classSymbol the class whose helper calls we are interested in. * @returns an array of statements that may contain helper calls. */ - protected getStatementsForClass(classSymbol: ClassSymbol): ts.Statement[] { + protected getStatementsForClass(classSymbol: NgccClassSymbol): ts.Statement[] { return Array.from(classSymbol.valueDeclaration.getSourceFile().statements); } diff --git a/packages/compiler-cli/ngcc/src/host/esm5_host.ts b/packages/compiler-cli/ngcc/src/host/esm5_host.ts index 7c425b541c..5b5908d92f 100644 --- a/packages/compiler-cli/ngcc/src/host/esm5_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm5_host.ts @@ -8,11 +8,12 @@ import * as ts from 'typescript'; -import {ClassDeclaration, ClassMember, ClassMemberKind, ClassSymbol, CtorParameter, Declaration, Decorator, FunctionDefinition, Parameter, TsHelperFn, isNamedVariableDeclaration, reflectObjectLiteral} from '../../../src/ngtsc/reflection'; +import {ClassDeclaration, ClassMember, ClassMemberKind, CtorParameter, Declaration, Decorator, FunctionDefinition, Parameter, TsHelperFn, isNamedVariableDeclaration, reflectObjectLiteral} from '../../../src/ngtsc/reflection'; import {isFromDtsFile} from '../../../src/ngtsc/util/src/typescript'; import {getNameText, hasNameIdentifier, stripDollarSuffix} from '../utils'; import {Esm2015ReflectionHost, ParamInfo, getPropertyValueFromSymbol, isAssignmentStatement} from './esm2015_host'; +import {NgccClassSymbol} from './ngcc_host'; @@ -238,7 +239,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { } /** Gets all decorators of the given class symbol. */ - getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null { + getDecoratorsOfSymbol(symbol: NgccClassSymbol): Decorator[]|null { // The necessary info is on the inner function declaration (inside the ES5 class IIFE). const innerFunctionSymbol = this.getInnerFunctionSymbolFromClassDeclaration(symbol.valueDeclaration); @@ -302,12 +303,12 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { * @returns the inner function declaration identifier symbol or `undefined` if it is not a "class" * or has no identifier. */ - protected getInnerFunctionSymbolFromClassDeclaration(clazz: ClassDeclaration): ClassSymbol + protected getInnerFunctionSymbolFromClassDeclaration(clazz: ClassDeclaration): NgccClassSymbol |undefined { const innerFunctionDeclaration = this.getInnerFunctionDeclarationFromClassDeclaration(clazz); if (!innerFunctionDeclaration || !hasNameIdentifier(innerFunctionDeclaration)) return undefined; - return this.checker.getSymbolAtLocation(innerFunctionDeclaration.name) as ClassSymbol; + return this.checker.getSymbolAtLocation(innerFunctionDeclaration.name) as NgccClassSymbol; } /** @@ -322,7 +323,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { * @returns an array of `ts.ParameterDeclaration` objects representing each of the parameters in * the class's constructor or `null` if there is no constructor. */ - protected getConstructorParameterDeclarations(classSymbol: ClassSymbol): + protected getConstructorParameterDeclarations(classSymbol: NgccClassSymbol): ts.ParameterDeclaration[]|null { const constructor = this.getInnerFunctionDeclarationFromClassDeclaration(classSymbol.valueDeclaration); @@ -348,7 +349,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { * @returns an array of constructor parameter info objects. */ protected getConstructorParamInfo( - classSymbol: ClassSymbol, parameterNodes: ts.ParameterDeclaration[]): CtorParameter[] { + classSymbol: NgccClassSymbol, parameterNodes: ts.ParameterDeclaration[]): CtorParameter[] { // The necessary info is on the inner function declaration (inside the ES5 class IIFE). const innerFunctionSymbol = this.getInnerFunctionSymbolFromClassDeclaration(classSymbol.valueDeclaration); @@ -479,7 +480,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { * to reference the inner identifier inside the IIFE. * @returns an array of statements that may contain helper calls. */ - protected getStatementsForClass(classSymbol: ClassSymbol): ts.Statement[] { + protected getStatementsForClass(classSymbol: NgccClassSymbol): ts.Statement[] { const classDeclarationParent = classSymbol.valueDeclaration.parent; return ts.isBlock(classDeclarationParent) ? Array.from(classDeclarationParent.statements) : []; } @@ -496,7 +497,8 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { * @param propertyName the name of static property. * @returns the symbol if it is found or `undefined` if not. */ - protected getStaticProperty(symbol: ClassSymbol, propertyName: ts.__String): ts.Symbol|undefined { + protected getStaticProperty(symbol: NgccClassSymbol, propertyName: ts.__String): ts.Symbol + |undefined { // The symbol corresponds with the inner function declaration. First lets see if the static // property is set there. const prop = super.getStaticProperty(symbol, propertyName); @@ -516,7 +518,7 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { return undefined; } - return super.getStaticProperty(outerSymbol as ClassSymbol, propertyName); + return super.getStaticProperty(outerSymbol as NgccClassSymbol, propertyName); } } diff --git a/packages/compiler-cli/ngcc/src/host/ngcc_host.ts b/packages/compiler-cli/ngcc/src/host/ngcc_host.ts index 79bf887626..6fa2e9e248 100644 --- a/packages/compiler-cli/ngcc/src/host/ngcc_host.ts +++ b/packages/compiler-cli/ngcc/src/host/ngcc_host.ts @@ -7,7 +7,7 @@ */ import * as ts from 'typescript'; -import {ClassDeclaration, ClassSymbol, ConcreteDeclaration, Decorator, ReflectionHost} from '../../../src/ngtsc/reflection'; +import {ClassDeclaration, ConcreteDeclaration, Decorator, ReflectionHost} from '../../../src/ngtsc/reflection'; export const PRE_R3_MARKER = '__PRE_R3__'; export const POST_R3_MARKER = '__POST_R3__'; @@ -43,6 +43,12 @@ export interface ModuleWithProvidersFunction { ngModule: ConcreteDeclaration; } +/** + * The symbol corresponding to a "class" declaration. I.e. a `ts.Symbol` whose `valueDeclaration` is + * a `ClassDeclaration`. + */ +export type NgccClassSymbol = ts.Symbol & {valueDeclaration: ClassDeclaration}; + /** * A reflection host that has extra methods for looking at non-Typescript package formats */ @@ -53,7 +59,7 @@ export interface NgccReflectionHost extends ReflectionHost { * @returns the symbol for the declaration or `undefined` if it is not * a "class" or has no symbol. */ - getClassSymbol(node: ts.Node): ClassSymbol|undefined; + getClassSymbol(node: ts.Node): NgccClassSymbol|undefined; /** * Search the given module for variable declarations in which the initializer @@ -68,14 +74,14 @@ export interface NgccReflectionHost extends ReflectionHost { * @param symbol Class symbol that can refer to a declaration which can hold decorators. * @returns An array of decorators or null if none are declared. */ - getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null; + getDecoratorsOfSymbol(symbol: NgccClassSymbol): Decorator[]|null; /** * Retrieves all class symbols of a given source file. * @param sourceFile The source file to search for classes. * @returns An array of found class symbols. */ - findClassSymbols(sourceFile: ts.SourceFile): ClassSymbol[]; + findClassSymbols(sourceFile: ts.SourceFile): NgccClassSymbol[]; /** * Search the given source file for exported functions and static class methods that return diff --git a/packages/compiler-cli/ngcc/test/analysis/migration_host_spec.ts b/packages/compiler-cli/ngcc/test/analysis/migration_host_spec.ts index d827fb7ed8..41e1ec337c 100644 --- a/packages/compiler-cli/ngcc/test/analysis/migration_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/analysis/migration_host_spec.ts @@ -6,15 +6,16 @@ * found in the LICENSE file at https://angular.io/license */ import {ErrorCode} from '../../../src/ngtsc/diagnostics'; -import {ClassDeclaration, ClassSymbol, Decorator} from '../../../src/ngtsc/reflection'; +import {ClassDeclaration, Decorator} from '../../../src/ngtsc/reflection'; import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence} from '../../../src/ngtsc/transform'; import {DefaultMigrationHost} from '../../src/analysis/migration_host'; import {AnalyzedClass, AnalyzedFile} from '../../src/analysis/types'; +import {NgccClassSymbol} from '../../src/host/ngcc_host'; describe('DefaultMigrationHost', () => { describe('injectSyntheticDecorator()', () => { const mockHost: any = { - getClassSymbol: (node: any): ClassSymbol | undefined => + getClassSymbol: (node: any): NgccClassSymbol | undefined => ({ valueDeclaration: node, name: node.name.text } as any), }; const mockMetadata: any = {}; diff --git a/packages/compiler-cli/src/ngtsc/reflection/src/host.ts b/packages/compiler-cli/src/ngtsc/reflection/src/host.ts index 6666b53c3f..8593dfd7c1 100644 --- a/packages/compiler-cli/src/ngtsc/reflection/src/host.ts +++ b/packages/compiler-cli/src/ngtsc/reflection/src/host.ts @@ -70,12 +70,6 @@ export function isDecoratorIdentifier(exp: ts.Expression): exp is DecoratorIdent */ export type ClassDeclaration = T & {name: ts.Identifier}; -/** - * The symbol corresponding to a "class" declaration. I.e. a `ts.Symbol` whose `valueDeclaration` is - * a `ClassDeclaration`. - */ -export type ClassSymbol = ts.Symbol & {valueDeclaration: ClassDeclaration}; - /** * An enumeration of possible kinds of class members. */