refactor(compiler): separate `compileFactoryFunction()` from `compileInjector()` (#41022)

This commit moves the creation of the injector's factory function
out so that it can be more easily refactored further.

PR Close #41022
This commit is contained in:
Pete Bacon Darwin 2021-02-25 13:48:39 +00:00 committed by Andrew Kushnir
parent bdf13fe376
commit d04515cf53
3 changed files with 37 additions and 26 deletions

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/
import {compileInjector, compileNgModule, CUSTOM_ELEMENTS_SCHEMA, Expression, ExternalExpr, InvokeFunctionExpr, LiteralArrayExpr, LiteralExpr, NO_ERRORS_SCHEMA, R3Identifiers, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, SchemaMetadata, Statement, STRING_TYPE, WrappedNodeExpr} from '@angular/compiler';
import {compileFactoryFunction, compileInjector, compileNgModule, CUSTOM_ELEMENTS_SCHEMA, Expression, ExternalExpr, Identifiers as R3, InvokeFunctionExpr, LiteralArrayExpr, LiteralExpr, NO_ERRORS_SCHEMA, R3FactoryTarget, R3Identifiers, R3InjectorMetadata, R3NgModuleMetadata, R3Reference, SchemaMetadata, Statement, STRING_TYPE, WrappedNodeExpr} from '@angular/compiler';
import * as ts from 'typescript';
import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics';
@ -449,21 +449,33 @@ export class NgModuleDecoratorHandler implements
}
compileFull(
node: ClassDeclaration, analysis: Readonly<NgModuleAnalysis>,
node: ClassDeclaration, {inj, mod, metadataStmt, declarations}: Readonly<NgModuleAnalysis>,
resolution: Readonly<NgModuleResolution>): CompileResult[] {
const factoryFn = compileFactoryFunction({
name: inj.name,
type: inj.type,
internalType: inj.internalType,
typeArgumentCount: 0,
deps: inj.deps,
injectFn: R3.inject,
target: R3FactoryTarget.NgModule,
});
// Merge the injector imports (which are 'exports' that were later found to be NgModules)
// computed during resolution with the ones from analysis.
const ngInjectorDef = compileInjector({
...analysis.inj,
imports: [...analysis.inj.imports, ...resolution.injectorImports],
});
const ngModuleDef = compileNgModule(analysis.mod);
const ngInjectorDef = compileInjector(
{
...inj,
imports: [...inj.imports, ...resolution.injectorImports],
},
factoryFn);
const ngModuleDef = compileNgModule(mod);
const ngModuleStatements = ngModuleDef.additionalStatements;
if (analysis.metadataStmt !== null) {
ngModuleStatements.push(analysis.metadataStmt);
if (metadataStmt !== null) {
ngModuleStatements.push(metadataStmt);
}
const context = getSourceFile(node);
for (const decl of analysis.declarations) {
for (const decl of declarations) {
const remoteScope = this.scopeRegistry.getRemoteScope(decl.node);
if (remoteScope !== null) {
const directives = remoteScope.directives.map(

View File

@ -88,7 +88,16 @@ export class CompilerFacadeImpl implements CompilerFacade {
providers: new WrappedNodeExpr(facade.providers),
imports: facade.imports.map(i => new WrappedNodeExpr(i)),
};
const res = compileInjector(meta);
const factoryFn = compileFactoryFunction({
name: meta.name,
type: meta.type,
internalType: meta.internalType,
typeArgumentCount: 0,
deps: meta.deps,
injectFn: Identifiers.inject,
target: R3FactoryTarget.NgModule,
});
const res = compileInjector(meta, factoryFn);
return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, res.statements);
}

View File

@ -8,7 +8,7 @@
import * as o from '../output/output_ast';
import {compileFactoryFunction, R3DependencyMetadata, R3FactoryTarget} from './r3_factory';
import {R3DependencyMetadata, R3FactoryFn} from './r3_factory';
import {Identifiers as R3} from './r3_identifiers';
import {jitOnlyGuardedExpression, mapToMapExpression, R3Reference} from './util';
@ -230,19 +230,9 @@ export interface R3InjectorMetadata {
imports: o.Expression[];
}
export function compileInjector(meta: R3InjectorMetadata): R3InjectorDef {
const result = compileFactoryFunction({
name: meta.name,
type: meta.type,
internalType: meta.internalType,
typeArgumentCount: 0,
deps: meta.deps,
injectFn: R3.inject,
target: R3FactoryTarget.NgModule,
});
const definitionMap = {
factory: result.factory,
} as {factory: o.Expression, providers: o.Expression, imports: o.Expression};
export function compileInjector(
meta: R3InjectorMetadata, {factory, statements}: R3FactoryFn): R3InjectorDef {
const definitionMap: Record<string, o.Expression> = {factory};
if (meta.providers !== null) {
definitionMap.providers = meta.providers;
@ -256,7 +246,7 @@ export function compileInjector(meta: R3InjectorMetadata): R3InjectorDef {
o.importExpr(R3.defineInjector).callFn([mapToMapExpression(definitionMap)], undefined, true);
const type =
new o.ExpressionType(o.importExpr(R3.InjectorDef, [new o.ExpressionType(meta.type.type)]));
return {expression, type, statements: result.statements};
return {expression, type, statements};
}
function tupleTypeOf(exp: R3Reference[]): o.Type {