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 * 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 * as ts from 'typescript';
import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics'; import {ErrorCode, FatalDiagnosticError, makeDiagnostic, makeRelatedInformation} from '../../diagnostics';
@ -449,21 +449,33 @@ export class NgModuleDecoratorHandler implements
} }
compileFull( compileFull(
node: ClassDeclaration, analysis: Readonly<NgModuleAnalysis>, node: ClassDeclaration, {inj, mod, metadataStmt, declarations}: Readonly<NgModuleAnalysis>,
resolution: Readonly<NgModuleResolution>): CompileResult[] { 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) // Merge the injector imports (which are 'exports' that were later found to be NgModules)
// computed during resolution with the ones from analysis. // computed during resolution with the ones from analysis.
const ngInjectorDef = compileInjector({ const ngInjectorDef = compileInjector(
...analysis.inj, {
imports: [...analysis.inj.imports, ...resolution.injectorImports], ...inj,
}); imports: [...inj.imports, ...resolution.injectorImports],
const ngModuleDef = compileNgModule(analysis.mod); },
factoryFn);
const ngModuleDef = compileNgModule(mod);
const ngModuleStatements = ngModuleDef.additionalStatements; const ngModuleStatements = ngModuleDef.additionalStatements;
if (analysis.metadataStmt !== null) { if (metadataStmt !== null) {
ngModuleStatements.push(analysis.metadataStmt); ngModuleStatements.push(metadataStmt);
} }
const context = getSourceFile(node); const context = getSourceFile(node);
for (const decl of analysis.declarations) { for (const decl of declarations) {
const remoteScope = this.scopeRegistry.getRemoteScope(decl.node); const remoteScope = this.scopeRegistry.getRemoteScope(decl.node);
if (remoteScope !== null) { if (remoteScope !== null) {
const directives = remoteScope.directives.map( const directives = remoteScope.directives.map(

View File

@ -88,7 +88,16 @@ export class CompilerFacadeImpl implements CompilerFacade {
providers: new WrappedNodeExpr(facade.providers), providers: new WrappedNodeExpr(facade.providers),
imports: facade.imports.map(i => new WrappedNodeExpr(i)), 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); return this.jitExpression(res.expression, angularCoreEnv, sourceMapUrl, res.statements);
} }

View File

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