refactor(ivy): move directive, component and pipe factories to ngFactoryFn (#31953)

Reworks the compiler to output the factories for directives, components and pipes under a new static field called `ngFactoryFn`, instead of the usual `factory` property in their respective defs. This should eventually allow us to inject any kind of decorated class (e.g. a pipe).

**Note:** these changes are the first part of the refactor and they don't include injectables. I decided to leave injectables for a follow-up PR, because there's some more cases we need to handle when it comes to their factories. Furthermore, directives, components and pipes make up most of the compiler output tests that need to be refactored and it'll make follow-up PRs easier to review if the tests are cleaned up now.

This is part of the larger refactor for FW-1468.

PR Close #31953
This commit is contained in:
Kristiyan Kostadinov
2019-08-12 09:26:20 +03:00
committed by atscott
parent 14feb56139
commit c885178d5f
71 changed files with 894 additions and 675 deletions

View File

@ -237,7 +237,6 @@ export interface R3QueryMetadata {
export interface R3DirectiveDef {
expression: o.Expression;
type: o.Type;
statements: o.Statement[];
}
/**
@ -246,7 +245,6 @@ export interface R3DirectiveDef {
export interface R3ComponentDef {
expression: o.Expression;
type: o.Type;
statements: o.Statement[];
}
/**

View File

@ -22,7 +22,7 @@ import {CONTENT_ATTR, HOST_ATTR} from '../../style_compiler';
import {BindingParser} from '../../template_parser/binding_parser';
import {OutputContext, error} from '../../util';
import {BoundEvent} from '../r3_ast';
import {compileFactoryFunction, dependenciesFromGlobalMetadata} from '../r3_factory';
import {compileFactoryFromMetadata, compileFactoryFunction, dependenciesFromGlobalMetadata} from '../r3_factory';
import {Identifiers as R3} from '../r3_identifiers';
import {Render3ParseResult} from '../r3_template_transform';
import {prepareSyntheticListenerFunctionName, prepareSyntheticPropertyName, typeWithParameters} from '../util';
@ -44,7 +44,7 @@ function getStylingPrefix(name: string): string {
function baseDirectiveFields(
meta: R3DirectiveMetadata, constantPool: ConstantPool,
bindingParser: BindingParser): {definitionMap: DefinitionMap, statements: o.Statement[]} {
bindingParser: BindingParser): DefinitionMap {
const definitionMap = new DefinitionMap();
// e.g. `type: MyDirective`
@ -53,16 +53,6 @@ function baseDirectiveFields(
// e.g. `selectors: [['', 'someDir', '']]`
definitionMap.set('selectors', createDirectiveSelector(meta.selector));
// e.g. `factory: () => new MyApp(directiveInject(ElementRef))`
const result = compileFactoryFunction({
name: meta.name,
type: meta.type,
deps: meta.deps,
injectFn: R3.directiveInject,
});
definitionMap.set('factory', result.factory);
if (meta.queries.length > 0) {
// e.g. `contentQueries: (rf, ctx, dirIndex) => { ... }
definitionMap.set(
@ -90,7 +80,7 @@ function baseDirectiveFields(
definitionMap.set('exportAs', o.literalArr(meta.exportAs.map(e => o.literal(e))));
}
return {definitionMap, statements: result.statements};
return definitionMap;
}
/**
@ -128,12 +118,12 @@ function addFeatures(
export function compileDirectiveFromMetadata(
meta: R3DirectiveMetadata, constantPool: ConstantPool,
bindingParser: BindingParser): R3DirectiveDef {
const {definitionMap, statements} = baseDirectiveFields(meta, constantPool, bindingParser);
const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
addFeatures(definitionMap, meta);
const expression = o.importExpr(R3.defineDirective).callFn([definitionMap.toLiteralMap()]);
const type = createTypeForDef(meta, R3.DirectiveDefWithMeta);
return {expression, type, statements};
return {expression, type};
}
export interface R3BaseRefMetaData {
@ -197,7 +187,7 @@ export function compileBaseDefFromMetadata(
export function compileComponentFromMetadata(
meta: R3ComponentMetadata, constantPool: ConstantPool,
bindingParser: BindingParser): R3ComponentDef {
const {definitionMap, statements} = baseDirectiveFields(meta, constantPool, bindingParser);
const definitionMap = baseDirectiveFields(meta, constantPool, bindingParser);
addFeatures(definitionMap, meta);
const selector = meta.selector && CssSelector.parse(meta.selector);
@ -315,7 +305,7 @@ export function compileComponentFromMetadata(
const expression = o.importExpr(R3.defineComponent).callFn([definitionMap.toLiteralMap()]);
const type = createTypeForDef(meta, R3.ComponentDefWithMeta);
return {expression, type, statements};
return {expression, type};
}
/**
@ -335,12 +325,19 @@ export function compileDirectiveFromRender2(
const meta = directiveMetadataFromGlobalMetadata(directive, outputCtx, reflector);
const res = compileDirectiveFromMetadata(meta, outputCtx.constantPool, bindingParser);
// Create the partial class to be merged with the actual class.
outputCtx.statements.push(new o.ClassStmt(
const factoryRes = compileFactoryFromMetadata(meta);
const ngFactoryDefStatement = new o.ClassStmt(
name, null,
[new o.ClassField(
'ngFactoryDef', o.INFERRED_TYPE, [o.StmtModifier.Static], factoryRes.factory)],
[], new o.ClassMethod(null, [], []), []);
const directiveDefStatement = new o.ClassStmt(
name, null,
[new o.ClassField(definitionField, o.INFERRED_TYPE, [o.StmtModifier.Static], res.expression)],
[], new o.ClassMethod(null, [], []), []));
[], new o.ClassMethod(null, [], []), []);
// Create the partial class to be merged with the actual class.
outputCtx.statements.push(ngFactoryDefStatement, directiveDefStatement);
}
/**
@ -381,12 +378,19 @@ export function compileComponentFromRender2(
i18nUseExternalIds: true,
};
const res = compileComponentFromMetadata(meta, outputCtx.constantPool, bindingParser);
// Create the partial class to be merged with the actual class.
outputCtx.statements.push(new o.ClassStmt(
const factoryRes = compileFactoryFromMetadata(meta);
const ngFactoryDefStatement = new o.ClassStmt(
name, null,
[new o.ClassField(
'ngFactoryDef', o.INFERRED_TYPE, [o.StmtModifier.Static], factoryRes.factory)],
[], new o.ClassMethod(null, [], []), []);
const componentDefStatement = new o.ClassStmt(
name, null,
[new o.ClassField(definitionField, o.INFERRED_TYPE, [o.StmtModifier.Static], res.expression)],
[], new o.ClassMethod(null, [], []), []));
[], new o.ClassMethod(null, [], []), []);
// Create the partial class to be merged with the actual class.
outputCtx.statements.push(ngFactoryDefStatement, componentDefStatement);
}
/**