From 0c1259505ba8bbe5ba5881611f62592cd830ec97 Mon Sep 17 00:00:00 2001 From: Pete Bacon Darwin Date: Thu, 25 Mar 2021 20:38:51 +0000 Subject: [PATCH] refactor(compiler-cli): use a shared function for gathering factory metadata. (#41231) Each of the annotations had its own function for doing this, and those methods were generally employing spread operators that could allow unwanted properties to leak into the factory metadata object. This commit supplies a shared function `toFactoryMetadata()` that avoids this spread of properties into the returned function. PR Close #41231 --- .../src/ngtsc/annotations/src/component.ts | 10 +++------ .../src/ngtsc/annotations/src/directive.ts | 11 ++++------ .../src/ngtsc/annotations/src/injectable.ts | 22 +++++-------------- .../src/ngtsc/annotations/src/pipe.ts | 12 ++++------ .../src/ngtsc/annotations/src/util.ts | 14 ++++++++++++ 5 files changed, 30 insertions(+), 39 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts index 4898493dff..16c57a1bf8 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/component.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/component.ts @@ -32,7 +32,7 @@ import {DirectiveSymbol, extractDirectiveMetadata, parseFieldArrayValue} from '. import {compileDeclareFactory, compileNgFactoryDefField} from './factory'; import {generateSetClassMetadataCall} from './metadata'; import {NgModuleSymbol} from './ng_module'; -import {compileResults, findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, readBaseClass, resolveProvidersRequiringFactory, unwrapExpression, wrapFunctionExpressionsInParens} from './util'; +import {compileResults, findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, readBaseClass, resolveProvidersRequiringFactory, toFactoryMetadata, unwrapExpression, wrapFunctionExpressionsInParens} from './util'; const EMPTY_MAP = new Map(); const EMPTY_ARRAY: any[] = []; @@ -833,7 +833,7 @@ export class ComponentDecoratorHandler implements return []; } const meta: R3ComponentMetadata = {...analysis.meta, ...resolution}; - const fac = compileNgFactoryDefField(toComponentFactoryMetadata(meta)); + const fac = compileNgFactoryDefField(toFactoryMetadata(meta, R3FactoryTarget.Component)); const def = compileComponentFromMetadata(meta, pool, makeBindingParser()); return compileResults(fac, def, analysis.metadataStmt, 'ɵcmp'); } @@ -845,7 +845,7 @@ export class ComponentDecoratorHandler implements return []; } const meta: R3ComponentMetadata = {...analysis.meta, ...resolution}; - const fac = compileDeclareFactory(toComponentFactoryMetadata(meta)); + const fac = compileDeclareFactory(toFactoryMetadata(meta, R3FactoryTarget.Component)); const def = compileDeclareComponentFromMetadata(meta, analysis.template); return compileResults(fac, def, analysis.metadataStmt, 'ɵcmp'); } @@ -1390,7 +1390,3 @@ function makeCyclicImportInfo( `The ${type} '${name}' is used in the template but importing it would create a cycle: `; return makeRelatedInformation(ref.node, message + path); } - -function toComponentFactoryMetadata(meta: R3ComponentMetadata): R3FactoryMetadata { - return {...meta, target: R3FactoryTarget.Component}; -} diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts index 0a175d7eeb..14b2a71d6f 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts @@ -24,7 +24,7 @@ import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerFl import {createValueHasWrongTypeError, getDirectiveDiagnostics, getProviderDiagnostics, getUndecoratedClassWithAngularFeaturesDiagnostic} from './diagnostics'; import {compileDeclareFactory, compileNgFactoryDefField} from './factory'; import {generateSetClassMetadataCall} from './metadata'; -import {compileResults, createSourceSpan, findAngularDecorator, getConstructorDependencies, isAngularDecorator, readBaseClass, resolveProvidersRequiringFactory, unwrapConstructorDependencies, unwrapExpression, unwrapForwardRef, validateConstructorDependencies, wrapFunctionExpressionsInParens, wrapTypeReference} from './util'; +import {compileResults, createSourceSpan, findAngularDecorator, getConstructorDependencies, isAngularDecorator, readBaseClass, resolveProvidersRequiringFactory, toFactoryMetadata, unwrapConstructorDependencies, unwrapExpression, unwrapForwardRef, validateConstructorDependencies, wrapFunctionExpressionsInParens, wrapTypeReference} from './util'; const EMPTY_OBJECT: {[key: string]: string} = {}; const FIELD_DECORATORS = [ @@ -302,7 +302,8 @@ export class DirectiveDecoratorHandler implements compileFull( node: ClassDeclaration, analysis: Readonly, resolution: Readonly, pool: ConstantPool): CompileResult[] { - const fac = compileNgFactoryDefField(toDirectiveFactoryMetadata(analysis.meta)); + const fac = + compileNgFactoryDefField(toFactoryMetadata(analysis.meta, R3FactoryTarget.Directive)); const def = compileDirectiveFromMetadata(analysis.meta, pool, makeBindingParser()); return compileResults(fac, def, analysis.metadataStmt, 'ɵdir'); } @@ -310,7 +311,7 @@ export class DirectiveDecoratorHandler implements compilePartial( node: ClassDeclaration, analysis: Readonly, resolution: Readonly): CompileResult[] { - const fac = compileDeclareFactory(toDirectiveFactoryMetadata(analysis.meta)); + const fac = compileDeclareFactory(toFactoryMetadata(analysis.meta, R3FactoryTarget.Directive)); const def = compileDeclareDirectiveFromMetadata(analysis.meta); return compileResults(fac, def, analysis.metadataStmt, 'ɵdir'); } @@ -919,7 +920,3 @@ const QUERY_TYPES = new Set([ 'ViewChild', 'ViewChildren', ]); - -function toDirectiveFactoryMetadata(meta: R3DirectiveMetadata): R3FactoryMetadata { - return {...meta, target: R3FactoryTarget.Directive}; -} diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts b/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts index 65d5e4839b..1e63bf0d30 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/injectable.ts @@ -18,7 +18,7 @@ import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPr import {compileDeclareFactory, compileNgFactoryDefField} from './factory'; import {generateSetClassMetadataCall} from './metadata'; -import {findAngularDecorator, getConstructorDependencies, getValidConstructorDependencies, isAngularCore, unwrapConstructorDependencies, unwrapForwardRef, validateConstructorDependencies, wrapTypeReference} from './util'; +import {findAngularDecorator, getConstructorDependencies, getValidConstructorDependencies, isAngularCore, toFactoryMetadata, unwrapConstructorDependencies, unwrapForwardRef, validateConstructorDependencies, wrapTypeReference} from './util'; export interface InjectableHandlerData { meta: R3InjectableMetadata; @@ -101,8 +101,8 @@ export class InjectableDecoratorHandler implements if (analysis.needsFactory) { const meta = analysis.meta; - const factoryRes = - compileNgFactoryDefField(toInjectableFactoryMetadata(meta, analysis.ctorDeps)); + const factoryRes = compileNgFactoryDefField( + toFactoryMetadata({...meta, deps: analysis.ctorDeps}, R3FactoryTarget.Injectable)); if (analysis.metadataStmt !== null) { factoryRes.statements.push(analysis.metadataStmt); } @@ -133,8 +133,8 @@ export class InjectableDecoratorHandler implements if (analysis.needsFactory) { const meta = analysis.meta; - const factoryRes = - compileDeclareFactory(toInjectableFactoryMetadata(meta, analysis.ctorDeps)); + const factoryRes = compileDeclareFactory( + toFactoryMetadata({...meta, deps: analysis.ctorDeps}, R3FactoryTarget.Injectable)); if (analysis.metadataStmt !== null) { factoryRes.statements.push(analysis.metadataStmt); } @@ -157,18 +157,6 @@ export class InjectableDecoratorHandler implements } } -function toInjectableFactoryMetadata( - meta: R3InjectableMetadata, deps: R3DependencyMetadata[]|'invalid'|null): R3FactoryMetadata { - return { - name: meta.name, - type: meta.type, - internalType: meta.internalType, - typeArgumentCount: meta.typeArgumentCount, - deps, - target: R3FactoryTarget.Injectable, - }; -} - /** * Read metadata from the `@Injectable` decorator and produce the `IvyInjectableMetadata`, the * input metadata needed to run `compileIvyInjectable`. diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts b/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts index d37ea2875b..3630076014 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {compileDeclarePipeFromMetadata, compilePipeFromMetadata, R3FactoryMetadata, R3FactoryTarget, R3PipeMetadata, Statement, WrappedNodeExpr} from '@angular/compiler'; +import {compileDeclarePipeFromMetadata, compilePipeFromMetadata, R3FactoryTarget, R3PipeMetadata, Statement, WrappedNodeExpr} from '@angular/compiler'; import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError} from '../../diagnostics'; @@ -22,7 +22,7 @@ import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPr import {createValueHasWrongTypeError} from './diagnostics'; import {compileDeclareFactory, compileNgFactoryDefField} from './factory'; import {generateSetClassMetadataCall} from './metadata'; -import {compileResults, findAngularDecorator, getValidConstructorDependencies, makeDuplicateDeclarationError, unwrapExpression, wrapTypeReference} from './util'; +import {compileResults, findAngularDecorator, getValidConstructorDependencies, makeDuplicateDeclarationError, toFactoryMetadata, unwrapExpression, wrapTypeReference} from './util'; export interface PipeHandlerData { meta: R3PipeMetadata; @@ -165,18 +165,14 @@ export class PipeDecoratorHandler implements } compileFull(node: ClassDeclaration, analysis: Readonly): CompileResult[] { - const fac = compileNgFactoryDefField(toPipeFactoryMetadata(analysis.meta)); + const fac = compileNgFactoryDefField(toFactoryMetadata(analysis.meta, R3FactoryTarget.Pipe)); const def = compilePipeFromMetadata(analysis.meta); return compileResults(fac, def, analysis.metadataStmt, 'ɵpipe'); } compilePartial(node: ClassDeclaration, analysis: Readonly): CompileResult[] { - const fac = compileDeclareFactory(toPipeFactoryMetadata(analysis.meta)); + const fac = compileDeclareFactory(toFactoryMetadata(analysis.meta, R3FactoryTarget.Pipe)); const def = compileDeclarePipeFromMetadata(analysis.meta); return compileResults(fac, def, analysis.metadataStmt, 'ɵpipe'); } } - -function toPipeFactoryMetadata(meta: R3PipeMetadata): R3FactoryMetadata { - return {...meta, target: R3FactoryTarget.Pipe}; -} diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/util.ts b/packages/compiler-cli/src/ngtsc/annotations/src/util.ts index 2fbf65c983..f1ddbb2e72 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/util.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/util.ts @@ -7,6 +7,8 @@ */ import {Expression, ExternalExpr, LiteralExpr, ParseLocation, ParseSourceFile, ParseSourceSpan, R3CompiledExpression, R3DependencyMetadata, R3Reference, ReadPropExpr, Statement, WrappedNodeExpr} from '@angular/compiler'; +import {R3FactoryMetadata} from '@angular/compiler/src/compiler'; +import {R3FactoryTarget} from '@angular/compiler/src/render3/partial/api'; import * as ts from 'typescript'; import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics'; @@ -579,3 +581,15 @@ export function compileResults( } ]; } + +export function toFactoryMetadata( + meta: Omit, target: R3FactoryTarget): R3FactoryMetadata { + return { + name: meta.name, + type: meta.type, + internalType: meta.internalType, + typeArgumentCount: meta.typeArgumentCount, + deps: meta.deps, + target + }; +}