Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion integration/_payload-limits.json
Expand Up @@ -12,7 +12,7 @@
"master": {
"uncompressed": {
"runtime": 1440,
"main": 13411,
"main": 13266,
"polyfills": 45340
}
}
Expand Down
4 changes: 3 additions & 1 deletion modules/benchmarks/src/tree/render3_function/index.ts
Expand Up @@ -17,6 +17,9 @@ function noop() {}
export class TreeFunction {
data: TreeNode = emptyTree;

/** @nocollapse */
static ngFactoryDef = () => new TreeFunction;

/** @nocollapse */
static ngComponentDef = ɵɵdefineComponent({
type: TreeFunction,
Expand All @@ -27,7 +30,6 @@ export class TreeFunction {
// bit of a hack
TreeTpl(rf, ctx.data);
},
factory: () => new TreeFunction,
inputs: {data: 'data'}
});
}
Expand Down
4 changes: 2 additions & 2 deletions packages/common/src/common.ts
Expand Up @@ -29,5 +29,5 @@ export {ViewportScroller, NullViewportScroller as ɵNullViewportScroller} from '

export {NgClassImplProvider__POST_R3__ as ɵNgClassImplProvider__POST_R3__, NgClassR2Impl as ɵNgClassR2Impl, NgClassImpl as ɵNgClassImpl} from './directives/ng_class_impl';
export {NgStyleImplProvider__POST_R3__ as ɵNgStyleImplProvider__POST_R3__, NgStyleR2Impl as ɵNgStyleR2Impl, NgStyleImpl as ɵNgStyleImpl} from './directives/ng_style_impl';
export {ngStyleDirectiveDef__POST_R3__ as ɵngStyleDirectiveDef__POST_R3__} from './directives/ng_style';
export {ngClassDirectiveDef__POST_R3__ as ɵngClassDirectiveDef__POST_R3__} from './directives/ng_class';
export {ngStyleDirectiveDef__POST_R3__ as ɵngStyleDirectiveDef__POST_R3__, ngStyleFactoryDef__POST_R3__ as ɵngStyleFactoryDef__POST_R3__} from './directives/ng_style';
export {ngClassDirectiveDef__POST_R3__ as ɵngClassDirectiveDef__POST_R3__, ngClassFactoryDef__POST_R3__ as ɵngClassFactoryDef__POST_R3__} from './directives/ng_class';
6 changes: 5 additions & 1 deletion packages/common/src/directives/ng_class.ts
Expand Up @@ -32,7 +32,6 @@ export const ngClassDirectiveDef__PRE_R3__ = undefined;
export const ngClassDirectiveDef__POST_R3__ = ɵɵdefineDirective({
type: function() {} as any,
selectors: null as any,
factory: () => {},
hostBindings: function(rf: ɵRenderFlags, ctx: any, elIndex: number) {
if (rf & ɵRenderFlags.Create) {
ɵɵallocHostVars(1);
Expand All @@ -47,6 +46,10 @@ export const ngClassDirectiveDef__POST_R3__ = ɵɵdefineDirective({

export const ngClassDirectiveDef = ngClassDirectiveDef__PRE_R3__;

export const ngClassFactoryDef__PRE_R3__ = undefined;
export const ngClassFactoryDef__POST_R3__ = function() {};
export const ngClassFactoryDef = ngClassFactoryDef__PRE_R3__;

/**
* Serves as the base non-VE container for NgClass.
*
Expand All @@ -63,6 +66,7 @@ export const ngClassDirectiveDef = ngClassDirectiveDef__PRE_R3__;
*/
export class NgClassBase {
static ngDirectiveDef: any = ngClassDirectiveDef;
static ngFactoryDef: any = ngClassFactoryDef;

constructor(protected _delegate: NgClassImpl) {}

Expand Down
6 changes: 5 additions & 1 deletion packages/common/src/directives/ng_style.ts
Expand Up @@ -25,14 +25,14 @@ import {NgStyleImpl, NgStyleImplProvider} from './ng_style_impl';

// used when the VE is present
export const ngStyleDirectiveDef__PRE_R3__ = undefined;
export const ngStyleFactoryDef__PRE_R3__ = undefined;

// used when the VE is not present (note the directive will
// never be instantiated normally because it is apart of a
// base class)
export const ngStyleDirectiveDef__POST_R3__ = ɵɵdefineDirective({
type: function() {} as any,
selectors: null as any,
factory: () => {},
hostBindings: function(rf: ɵRenderFlags, ctx: any, elIndex: number) {
if (rf & ɵRenderFlags.Create) {
ɵɵstyling();
Expand All @@ -44,7 +44,10 @@ export const ngStyleDirectiveDef__POST_R3__ = ɵɵdefineDirective({
}
});

export const ngStyleFactoryDef__POST_R3__ = function() {};

export const ngStyleDirectiveDef = ngStyleDirectiveDef__PRE_R3__;
export const ngStyleFactoryDef = ngStyleDirectiveDef__PRE_R3__;

/**
* Serves as the base non-VE container for NgStyle.
Expand All @@ -62,6 +65,7 @@ export const ngStyleDirectiveDef = ngStyleDirectiveDef__PRE_R3__;
*/
export class NgStyleBase {
static ngDirectiveDef: any = ngStyleDirectiveDef;
static ngFactory: any = ngStyleFactoryDef;

constructor(protected _delegate: NgStyleImpl) {}

Expand Down
Expand Up @@ -119,7 +119,7 @@ runInEachFileSystem(() => {
const typingsFile = result.find(f => f.path === _('/typings/file.d.ts')) !;
expect(typingsFile.contents)
.toContain(
'foo(x: number): number;\n static ngDirectiveDef: ɵngcc0.ɵɵDirectiveDefWithMeta');
'foo(x: number): number;\n static ngFactoryDef: ɵngcc0.ɵɵFactoryDef<A>;\n static ngDirectiveDef: ɵngcc0.ɵɵDirectiveDefWithMeta');
});

it('should render imports into typings files', () => {
Expand Down
9 changes: 5 additions & 4 deletions packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts
Expand Up @@ -188,8 +188,8 @@ runInEachFileSystem(() => {
decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses);
const addDefinitionsSpy = testFormatter.addDefinitions as jasmine.Spy;
expect(addDefinitionsSpy.calls.first().args[2])
.toEqual(
`A.ngComponentDef = ɵngcc0.ɵɵdefineComponent({ type: A, selectors: [["a"]], factory: function A_Factory(t) { return new (t || A)(); }, consts: 1, vars: 1, template: function A_Template(rf, ctx) { if (rf & 1) {
.toEqual(`A.ngFactoryDef = function A_Factory(t) { return new (t || A)(); };
A.ngComponentDef = ɵngcc0.ɵɵdefineComponent({ type: A, selectors: [["a"]], consts: 1, vars: 1, template: function A_Template(rf, ctx) { if (rf & 1) {
ɵngcc0.ɵɵtext(0);
} if (rf & 2) {
ɵngcc0.ɵɵtextInterpolate(ctx.person.name);
Expand Down Expand Up @@ -227,9 +227,10 @@ runInEachFileSystem(() => {
name: 'A',
decorators: [jasmine.objectContaining({name: 'Directive'})]
}));

expect(addDefinitionsSpy.calls.first().args[2])
.toEqual(
`A.ngDirectiveDef = ɵngcc0.ɵɵdefineDirective({ type: A, selectors: [["", "a", ""]], factory: function A_Factory(t) { return new (t || A)(); } });
.toEqual(`A.ngFactoryDef = function A_Factory(t) { return new (t || A)(); };
A.ngDirectiveDef = ɵngcc0.ɵɵdefineDirective({ type: A, selectors: [["", "a", ""]] });
/*@__PURE__*/ ɵngcc0.ɵsetClassMetadata(A, [{
type: Directive,
args: [{ selector: '[a]' }]
Expand Down
28 changes: 16 additions & 12 deletions packages/compiler-cli/src/ngtsc/annotations/src/component.ts
Expand Up @@ -26,6 +26,7 @@ import {tsSourceMapBug29300Fixed} from '../../util/src/ts_source_map_bug_29300';

import {ResourceLoader} from './api';
import {extractDirectiveMetadata, parseFieldArrayValue} from './directive';
import {compileNgFactoryDefField} from './factory';
import {generateSetClassMetadataCall} from './metadata';
import {findAngularDecorator, isAngularCoreReference, isExpressionForwardReference, readBaseClass, unwrapExpression} from './util';

Expand Down Expand Up @@ -517,18 +518,21 @@ export class ComponentDecoratorHandler implements
}

compile(node: ClassDeclaration, analysis: ComponentHandlerData, pool: ConstantPool):
CompileResult {
const res = compileComponentFromMetadata(analysis.meta, pool, makeBindingParser());

const statements = res.statements;
CompileResult[] {
const meta = analysis.meta;
const res = compileComponentFromMetadata(meta, pool, makeBindingParser());
const factoryRes = compileNgFactoryDefField(meta);
if (analysis.metadataStmt !== null) {
statements.push(analysis.metadataStmt);
}
return {
name: 'ngComponentDef',
initializer: res.expression, statements,
type: res.type,
};
factoryRes.statements.push(analysis.metadataStmt);
}
return [
factoryRes, {
name: 'ngComponentDef',
initializer: res.expression,
statements: [],
type: res.type,
}
];
}

private _resolveLiteral(decorator: Decorator): ts.ObjectLiteralExpression {
Expand Down Expand Up @@ -822,4 +826,4 @@ export interface ParsedTemplate {

interface PreanalyzedTemplate extends ParsedTemplate {
parseTemplate: (options?: ParseTemplateOptions) => ParsedTemplate;
}
}
24 changes: 14 additions & 10 deletions packages/compiler-cli/src/ngtsc/annotations/src/directive.ts
Expand Up @@ -17,6 +17,7 @@ import {DynamicValue, EnumValue, PartialEvaluator} from '../../partial_evaluator
import {ClassDeclaration, ClassMember, ClassMemberKind, Decorator, ReflectionHost, filterToMembersWithDecorator, reflectObjectLiteral} from '../../reflection';
import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence} from '../../transform';

import {compileNgFactoryDefField} from './factory';
import {generateSetClassMetadataCall} from './metadata';
import {findAngularDecorator, getValidConstructorDependencies, readBaseClass, unwrapExpression, unwrapForwardRef} from './util';

Expand Down Expand Up @@ -90,18 +91,21 @@ export class DirectiveDecoratorHandler implements
}

compile(node: ClassDeclaration, analysis: DirectiveHandlerData, pool: ConstantPool):
CompileResult {
const res = compileDirectiveFromMetadata(analysis.meta, pool, makeBindingParser());
const statements = res.statements;
CompileResult[] {
const meta = analysis.meta;
const res = compileDirectiveFromMetadata(meta, pool, makeBindingParser());
const factoryRes = compileNgFactoryDefField(meta);
if (analysis.metadataStmt !== null) {
statements.push(analysis.metadataStmt);
factoryRes.statements.push(analysis.metadataStmt);
}
return {
name: 'ngDirectiveDef',
initializer: res.expression,
statements: statements,
type: res.type,
};
return [
factoryRes, {
name: 'ngDirectiveDef',
initializer: res.expression,
statements: [],
type: res.type,
}
];
}
}

Expand Down
21 changes: 21 additions & 0 deletions packages/compiler-cli/src/ngtsc/annotations/src/factory.ts
@@ -0,0 +1,21 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/

import {R3FactoryDefMetadata, compileFactoryFromMetadata} from '@angular/compiler';

import {CompileResult} from '../../transform';

export function compileNgFactoryDefField(metadata: R3FactoryDefMetadata): CompileResult {
const res = compileFactoryFromMetadata(metadata);
return {
name: 'ngFactoryDef',
initializer: res.factory,
statements: res.statements,
type: res.type
};
}
23 changes: 14 additions & 9 deletions packages/compiler-cli/src/ngtsc/annotations/src/pipe.ts
Expand Up @@ -16,6 +16,7 @@ import {PartialEvaluator} from '../../partial_evaluator';
import {ClassDeclaration, Decorator, ReflectionHost, reflectObjectLiteral} from '../../reflection';
import {AnalysisOutput, CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence} from '../../transform';

import {compileNgFactoryDefField} from './factory';
import {generateSetClassMetadataCall} from './metadata';
import {findAngularDecorator, getValidConstructorDependencies, unwrapExpression} from './util';

Expand Down Expand Up @@ -105,16 +106,20 @@ export class PipeDecoratorHandler implements DecoratorHandler<PipeHandlerData, D
};
}

compile(node: ClassDeclaration, analysis: PipeHandlerData): CompileResult {
const res = compilePipeFromMetadata(analysis.meta);
const statements = res.statements;
compile(node: ClassDeclaration, analysis: PipeHandlerData): CompileResult[] {
const meta = analysis.meta;
const res = compilePipeFromMetadata(meta);
const factoryRes = compileNgFactoryDefField({...meta, isPipe: true});
if (analysis.metadataStmt !== null) {
statements.push(analysis.metadataStmt);
factoryRes.statements.push(analysis.metadataStmt);
}
return {
name: 'ngPipeDef',
initializer: res.expression, statements,
type: res.type,
};
return [
factoryRes, {
name: 'ngPipeDef',
initializer: res.expression,
statements: [],
type: res.type,
}
];
}
}
1 change: 1 addition & 0 deletions packages/compiler-cli/src/transformers/nocollapse_hack.ts
Expand Up @@ -26,6 +26,7 @@ const R3_DEF_NAME_PATTERN = [
'ngInjectorDef',
'ngModuleDef',
'ngPipeDef',
'ngFactoryDef',
].join('|');

// Pattern matching `Identifier.property` where property is a Render3 property.
Expand Down