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
This commit is contained in:
Pete Bacon Darwin 2021-03-25 20:38:51 +00:00 committed by Alex Rickabaugh
parent 72b65f995d
commit 0c1259505b
5 changed files with 30 additions and 39 deletions

View File

@ -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<string, Expression>();
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};
}

View File

@ -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<DirectiveHandlerData>,
resolution: Readonly<unknown>, 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<DirectiveHandlerData>,
resolution: Readonly<unknown>): 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};
}

View File

@ -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`.

View File

@ -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<PipeHandlerData>): 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<PipeHandlerData>): 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};
}

View File

@ -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<R3FactoryMetadata, 'target'>, target: R3FactoryTarget): R3FactoryMetadata {
return {
name: meta.name,
type: meta.type,
internalType: meta.internalType,
typeArgumentCount: meta.typeArgumentCount,
deps: meta.deps,
target
};
}