refactor(compiler-cli): separate used components from used directives in partial declaration (#41104)
The partial declaration of a component includes the list of directives that are used in its template, including some metadata of the directive which can be used during actual compilation of the component. Used components are currently part of this list, as components are also directives. This commit splits the used components into a dedicate property in the partial declaration, which allows for template compilation to optimize the generated code for components. PR Close #41104
This commit is contained in:
parent
98de4cb1bf
commit
eb74a96935
|
@ -5,7 +5,7 @@
|
|||
* 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 {compileComponentFromMetadata, ConstantPool, DeclarationListEmitMode, DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig, makeBindingParser, parseTemplate, R3ComponentMetadata, R3DeclareComponentMetadata, R3PartialDeclaration, R3UsedDirectiveMetadata} from '@angular/compiler';
|
||||
import {compileComponentFromMetadata, ConstantPool, DeclarationListEmitMode, DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig, makeBindingParser, parseTemplate, R3ComponentMetadata, R3DeclareComponentMetadata, R3DeclareUsedDirectiveMetadata, R3PartialDeclaration, R3UsedDirectiveMetadata} from '@angular/compiler';
|
||||
import {ChangeDetectionStrategy, ViewEncapsulation} from '@angular/compiler/src/core';
|
||||
import * as o from '@angular/compiler/src/output/output_ast';
|
||||
|
||||
|
@ -74,34 +74,42 @@ export class PartialComponentLinkerVersion1<TStatement, TExpression> implements
|
|||
|
||||
let declarationListEmitMode = DeclarationListEmitMode.Direct;
|
||||
|
||||
let directives: R3UsedDirectiveMetadata[] = [];
|
||||
if (metaObj.has('directives')) {
|
||||
directives = metaObj.getArray('directives').map(directive => {
|
||||
const directiveExpr = directive.getObject();
|
||||
const type = directiveExpr.getValue('type');
|
||||
const selector = directiveExpr.getString('selector');
|
||||
const collectUsedDirectives =
|
||||
(directives: AstValue<R3DeclareUsedDirectiveMetadata, TExpression>[]) => {
|
||||
return directives.map(directive => {
|
||||
const directiveExpr = directive.getObject();
|
||||
const type = directiveExpr.getValue('type');
|
||||
const selector = directiveExpr.getString('selector');
|
||||
|
||||
let typeExpr = type.getOpaque();
|
||||
const forwardRefType = extractForwardRef(type);
|
||||
if (forwardRefType !== null) {
|
||||
typeExpr = forwardRefType;
|
||||
declarationListEmitMode = DeclarationListEmitMode.Closure;
|
||||
}
|
||||
let typeExpr = type.getOpaque();
|
||||
const forwardRefType = extractForwardRef(type);
|
||||
if (forwardRefType !== null) {
|
||||
typeExpr = forwardRefType;
|
||||
declarationListEmitMode = DeclarationListEmitMode.Closure;
|
||||
}
|
||||
|
||||
return {
|
||||
type: typeExpr,
|
||||
selector: selector,
|
||||
inputs: directiveExpr.has('inputs') ?
|
||||
directiveExpr.getArray('inputs').map(input => input.getString()) :
|
||||
[],
|
||||
outputs: directiveExpr.has('outputs') ?
|
||||
directiveExpr.getArray('outputs').map(input => input.getString()) :
|
||||
[],
|
||||
exportAs: directiveExpr.has('exportAs') ?
|
||||
directiveExpr.getArray('exportAs').map(exportAs => exportAs.getString()) :
|
||||
null,
|
||||
return {
|
||||
type: typeExpr,
|
||||
selector: selector,
|
||||
inputs: directiveExpr.has('inputs') ?
|
||||
directiveExpr.getArray('inputs').map(input => input.getString()) :
|
||||
[],
|
||||
outputs: directiveExpr.has('outputs') ?
|
||||
directiveExpr.getArray('outputs').map(input => input.getString()) :
|
||||
[],
|
||||
exportAs: directiveExpr.has('exportAs') ?
|
||||
directiveExpr.getArray('exportAs').map(exportAs => exportAs.getString()) :
|
||||
null,
|
||||
};
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
let directives: R3UsedDirectiveMetadata[] = [];
|
||||
if (metaObj.has('components')) {
|
||||
directives.push(...collectUsedDirectives(metaObj.getArray('components')));
|
||||
}
|
||||
if (metaObj.has('directives')) {
|
||||
directives.push(...collectUsedDirectives(metaObj.getArray('directives')));
|
||||
}
|
||||
|
||||
let pipes = new Map<string, o.Expression>();
|
||||
|
|
|
@ -181,7 +181,7 @@ SomeComp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type:
|
|||
export class MyApp {
|
||||
}
|
||||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: '<some-comp [prop]="{}" [otherProp]="{a: 1, b: 2}"></some-comp>', isInline: true, directives: [{ type: SomeComp, selector: "some-comp", inputs: ["prop", "otherProp"] }] });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: '<some-comp [prop]="{}" [otherProp]="{a: 1, b: 2}"></some-comp>', isInline: true, components: [{ type: SomeComp, selector: "some-comp", inputs: ["prop", "otherProp"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{ template: '<some-comp [prop]="{}" [otherProp]="{a: 1, b: 2}"></some-comp>' }]
|
||||
|
@ -236,7 +236,7 @@ SomeComp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type:
|
|||
export class MyApp {
|
||||
}
|
||||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: '<some-comp [prop]="[]" [otherProp]="[0, 1, 2]"></some-comp>', isInline: true, directives: [{ type: SomeComp, selector: "some-comp", inputs: ["prop", "otherProp"] }] });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "ng-component", ngImport: i0, template: '<some-comp [prop]="[]" [otherProp]="[0, 1, 2]"></some-comp>', isInline: true, components: [{ type: SomeComp, selector: "some-comp", inputs: ["prop", "otherProp"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{ template: '<some-comp [prop]="[]" [otherProp]="[0, 1, 2]"></some-comp>' }]
|
||||
|
|
|
@ -29,7 +29,7 @@ ComplexComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER
|
|||
export class MyApp {
|
||||
}
|
||||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '<simple>content</simple> <complex></complex>', isInline: true, directives: [{ type: SimpleComponent, selector: "simple" }, { type: ComplexComponent, selector: "complex" }] });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '<simple>content</simple> <complex></complex>', isInline: true, components: [{ type: SimpleComponent, selector: "simple" }, { type: ComplexComponent, selector: "complex" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{ selector: 'my-app', template: '<simple>content</simple> <complex></complex>' }]
|
||||
|
@ -224,7 +224,7 @@ SimpleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER"
|
|||
export class MyApp {
|
||||
}
|
||||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '<simple><h1 ngProjectAs="[title]"></h1></simple>', isInline: true, directives: [{ type: SimpleComponent, selector: "simple" }] });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '<simple><h1 ngProjectAs="[title]"></h1></simple>', isInline: true, components: [{ type: SimpleComponent, selector: "simple" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{ selector: 'my-app', template: '<simple><h1 ngProjectAs="[title]"></h1></simple>' }]
|
||||
|
@ -273,7 +273,7 @@ SimpleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER"
|
|||
export class MyApp {
|
||||
}
|
||||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '<simple><h1 ngProjectAs="[title],[header]"></h1></simple>', isInline: true, directives: [{ type: SimpleComponent, selector: "simple" }] });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '<simple><h1 ngProjectAs="[title],[header]"></h1></simple>', isInline: true, components: [{ type: SimpleComponent, selector: "simple" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{ selector: 'my-app', template: '<simple><h1 ngProjectAs="[title],[header]"></h1></simple>' }]
|
||||
|
|
|
@ -211,7 +211,7 @@ SimpleLayout.ɵfac = function SimpleLayout_Factory(t) { return new (t || SimpleL
|
|||
SimpleLayout.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: SimpleLayout, selector: "simple-layout", ngImport: i0, template: `
|
||||
<lifecycle-comp [name]="name1"></lifecycle-comp>
|
||||
<lifecycle-comp [name]="name2"></lifecycle-comp>
|
||||
`, isInline: true, directives: [{ type: LifecycleComp, selector: "lifecycle-comp", inputs: ["name"] }] });
|
||||
`, isInline: true, components: [{ type: LifecycleComp, selector: "lifecycle-comp", inputs: ["name"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SimpleLayout, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -365,7 +365,7 @@ MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: My
|
|||
<content-query-component>
|
||||
<div someDir></div>
|
||||
</content-query-component>
|
||||
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }, { type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
|
||||
`, isInline: true, components: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }], directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -524,7 +524,7 @@ MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: My
|
|||
<content-query-component>
|
||||
<div someDir></div>
|
||||
</content-query-component>
|
||||
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }, { type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
|
||||
`, isInline: true, components: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }], directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -22,7 +22,7 @@ SomeDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: "0.0.0-PLACEHOLDER",
|
|||
export class MyComponent {
|
||||
}
|
||||
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: '<child some-directive></child>!', isInline: true, directives: [{ type: ChildComponent, selector: "child" }, { type: SomeDirective, selector: "[some-directive]" }] });
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: '<child some-directive></child>!', isInline: true, components: [{ type: ChildComponent, selector: "child" }], directives: [{ type: SomeDirective, selector: "[some-directive]" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{ selector: 'my-component', template: '<child some-directive></child>!' }]
|
||||
|
@ -329,7 +329,7 @@ export class MyApp {
|
|||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: `
|
||||
<my-comp [names]="['Nancy', customName]"></my-comp>
|
||||
`, isInline: true, directives: [{ type: MyComp, selector: "my-comp", inputs: ["names"] }] });
|
||||
`, isInline: true, components: [{ type: MyComp, selector: "my-comp", inputs: ["names"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -428,7 +428,7 @@ MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
|||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: `
|
||||
<my-comp [names]="['start-', n0, n1, n2, n3, n4, '-middle-', n5, n6, n7, n8, '-end']">
|
||||
</my-comp>
|
||||
`, isInline: true, directives: [{ type: MyComp, selector: "my-comp", inputs: ["names"] }] });
|
||||
`, isInline: true, components: [{ type: MyComp, selector: "my-comp", inputs: ["names"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -509,7 +509,7 @@ export class MyApp {
|
|||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: `
|
||||
<object-comp [config]="{'duration': 500, animation: name}"></object-comp>
|
||||
`, isInline: true, directives: [{ type: ObjectComp, selector: "object-comp", inputs: ["config"] }] });
|
||||
`, isInline: true, components: [{ type: ObjectComp, selector: "object-comp", inputs: ["config"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
@ -587,7 +587,7 @@ MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
|||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: `
|
||||
<nested-comp [config]="{animation: name, actions: [{ opacity: 0, duration: 0}, {opacity: 1, duration: duration }]}">
|
||||
</nested-comp>
|
||||
`, isInline: true, directives: [{ type: NestedComp, selector: "nested-comp", inputs: ["config"] }] });
|
||||
`, isInline: true, components: [{ type: NestedComp, selector: "nested-comp", inputs: ["config"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -62,7 +62,7 @@ InfinityCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty
|
|||
export class MyComponent {
|
||||
}
|
||||
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: '<div class="my-app" title="Hello"><math><infinity/></math><p>test</p></div>', isInline: true, directives: [{ type: MathCmp, selector: "math" }, { type: InfinityCmp, selector: "infinity" }] });
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: '<div class="my-app" title="Hello"><math><infinity/></math><p>test</p></div>', isInline: true, components: [{ type: MathCmp, selector: "math" }, { type: InfinityCmp, selector: "infinity" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -9,7 +9,7 @@ export class MyApp {
|
|||
}
|
||||
}
|
||||
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '<todo [data]="list"></todo>', isInline: true, directives: [{ type: i0.forwardRef(function () { return TodoComponent; }), selector: "todo", inputs: ["data"] }] });
|
||||
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '<todo [data]="list"></todo>', isInline: true, components: [{ type: i0.forwardRef(function () { return TodoComponent; }), selector: "todo", inputs: ["data"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
|
||||
type: Component,
|
||||
args: [{ selector: 'my-app', template: '<todo [data]="list"></todo>' }]
|
||||
|
|
|
@ -158,7 +158,7 @@ MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty
|
|||
<button [attr.title]="myTitle" [attr.id]="buttonId" [attr.tabindex]="1"></button>
|
||||
<span [attr.id]="1" [attr.title]="'hello'" [attr.some-attr]="1 + 2"></span>
|
||||
<custom-element [attr.some-attr]="'one'" [attr.some-other-attr]="2"></custom-element>
|
||||
`, isInline: true, directives: [{ type: CustomEl, selector: "custom-element" }] });
|
||||
`, isInline: true, components: [{ type: CustomEl, selector: "custom-element" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -519,7 +519,7 @@ MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty
|
|||
<button [title]="myTitle" [id]="buttonId" [tabindex]="1"></button>
|
||||
<span [id]="1" [title]="'hello'" [someProp]="1 + 2"></span>
|
||||
<custom-element [prop]="'one'" [otherProp]="2"></custom-element>
|
||||
`, isInline: true, directives: [{ type: SpanDir, selector: "span", inputs: ["someProp"] }, { type: CustomEl, selector: "custom-element", inputs: ["prop", "otherProp"] }] });
|
||||
`, isInline: true, components: [{ type: CustomEl, selector: "custom-element", inputs: ["prop", "otherProp"] }], directives: [{ type: SpanDir, selector: "span", inputs: ["someProp"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -54,7 +54,7 @@ export class MyComponent {
|
|||
onClick(event) { }
|
||||
}
|
||||
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: `<my-app (click)="onClick($event);"></my-app>`, isInline: true, directives: [{ type: MyApp, selector: "my-app" }] });
|
||||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: `<my-app (click)="onClick($event);"></my-app>`, isInline: true, components: [{ type: MyApp, selector: "my-app" }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{ selector: 'my-component', template: `<my-app (click)="onClick($event);"></my-app>` }]
|
||||
|
@ -268,7 +268,7 @@ MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyCompone
|
|||
MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyComponent, selector: "my-component", ngImport: i0, template: `
|
||||
<div (click)="click()" (change)="change()"></div>
|
||||
<some-comp (update)="update()" (delete)="delete()"></some-comp>
|
||||
`, isInline: true, directives: [{ type: SomeComp, selector: "some-comp", outputs: ["update", "delete"] }] });
|
||||
`, isInline: true, components: [{ type: SomeComp, selector: "some-comp", outputs: ["update", "delete"] }] });
|
||||
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
|
||||
type: Component,
|
||||
args: [{
|
||||
|
|
|
@ -133,39 +133,21 @@ export interface R3DeclareComponentMetadata extends R3DeclareDirectiveMetadata {
|
|||
*/
|
||||
styles?: string[];
|
||||
|
||||
/**
|
||||
* List of components which matched in the template, including sufficient
|
||||
* metadata for each directive to attribute bindings and references within
|
||||
* the template to each directive specifically, if the runtime instructions
|
||||
* support this.
|
||||
*/
|
||||
components?: R3DeclareUsedDirectiveMetadata[];
|
||||
|
||||
/**
|
||||
* List of directives which matched in the template, including sufficient
|
||||
* metadata for each directive to attribute bindings and references within
|
||||
* the template to each directive specifically, if the runtime instructions
|
||||
* support this.
|
||||
*/
|
||||
directives?: {
|
||||
/**
|
||||
* Selector of the directive.
|
||||
*/
|
||||
selector: string;
|
||||
|
||||
/**
|
||||
* Reference to the directive class (possibly a forward reference wrapped in a `forwardRef`
|
||||
* invocation).
|
||||
*/
|
||||
type: o.Expression | (() => o.Expression);
|
||||
|
||||
/**
|
||||
* Property names of the directive's inputs.
|
||||
*/
|
||||
inputs?: string[];
|
||||
|
||||
/**
|
||||
* Event names of the directive's outputs.
|
||||
*/
|
||||
outputs?: string[];
|
||||
|
||||
/**
|
||||
* Names by which this directive exports itself for references.
|
||||
*/
|
||||
exportAs?: string[];
|
||||
}[];
|
||||
directives?: R3DeclareUsedDirectiveMetadata[];
|
||||
|
||||
/**
|
||||
* A map of pipe names to an expression referencing the pipe type (possibly a forward reference
|
||||
|
@ -206,6 +188,34 @@ export interface R3DeclareComponentMetadata extends R3DeclareDirectiveMetadata {
|
|||
preserveWhitespaces?: boolean;
|
||||
}
|
||||
|
||||
export interface R3DeclareUsedDirectiveMetadata {
|
||||
/**
|
||||
* Selector of the directive.
|
||||
*/
|
||||
selector: string;
|
||||
|
||||
/**
|
||||
* Reference to the directive class (possibly a forward reference wrapped in a `forwardRef`
|
||||
* invocation).
|
||||
*/
|
||||
type: o.Expression|(() => o.Expression);
|
||||
|
||||
/**
|
||||
* Property names of the directive's inputs.
|
||||
*/
|
||||
inputs?: string[];
|
||||
|
||||
/**
|
||||
* Event names of the directive's outputs.
|
||||
*/
|
||||
outputs?: string[];
|
||||
|
||||
/**
|
||||
* Names by which this directive exports itself for references.
|
||||
*/
|
||||
exportAs?: string[];
|
||||
}
|
||||
|
||||
export interface R3DeclareQueryMetadata {
|
||||
/**
|
||||
* Name of the property on the class to update with query results.
|
||||
|
|
|
@ -16,7 +16,7 @@ import {createComponentType} from '../view/compiler';
|
|||
import {ParsedTemplate} from '../view/template';
|
||||
import {DefinitionMap} from '../view/util';
|
||||
|
||||
import {R3DeclareComponentMetadata} from './api';
|
||||
import {R3DeclareComponentMetadata, R3DeclareUsedDirectiveMetadata} from './api';
|
||||
import {createDirectiveDefinitionMap} from './directive';
|
||||
import {toOptionalLiteralArray} from './util';
|
||||
|
||||
|
@ -48,7 +48,12 @@ export function createComponentDefinitionMap(meta: R3ComponentMetadata, template
|
|||
}
|
||||
|
||||
definitionMap.set('styles', toOptionalLiteralArray(meta.styles, o.literal));
|
||||
definitionMap.set('directives', compileUsedDirectiveMetadata(meta));
|
||||
definitionMap.set(
|
||||
'components',
|
||||
compileUsedDirectiveMetadata(meta, directive => directive.isComponent === true));
|
||||
definitionMap.set(
|
||||
'directives',
|
||||
compileUsedDirectiveMetadata(meta, directive => directive.isComponent !== true));
|
||||
definitionMap.set('pipes', compileUsedPipeMetadata(meta));
|
||||
definitionMap.set('viewProviders', meta.viewProviders);
|
||||
definitionMap.set('animations', meta.animations);
|
||||
|
@ -119,13 +124,16 @@ function computeEndLocation(file: ParseSourceFile, contents: string): ParseLocat
|
|||
* Compiles the directives as registered in the component metadata into an array literal of the
|
||||
* individual directives. If the component does not use any directives, then null is returned.
|
||||
*/
|
||||
function compileUsedDirectiveMetadata(meta: R3ComponentMetadata): o.LiteralArrayExpr|null {
|
||||
function compileUsedDirectiveMetadata(
|
||||
meta: R3ComponentMetadata,
|
||||
predicate: (directive: R3UsedDirectiveMetadata) => boolean): o.LiteralArrayExpr|null {
|
||||
const wrapType = meta.declarationListEmitMode !== DeclarationListEmitMode.Direct ?
|
||||
generateForwardRef :
|
||||
(expr: o.Expression) => expr;
|
||||
|
||||
return toOptionalLiteralArray(meta.directives, directive => {
|
||||
const dirMeta = new DefinitionMap<R3UsedDirectiveMetadata>();
|
||||
const directives = meta.directives.filter(predicate);
|
||||
return toOptionalLiteralArray(directives, directive => {
|
||||
const dirMeta = new DefinitionMap<R3DeclareUsedDirectiveMetadata>();
|
||||
dirMeta.set('type', wrapType(directive.type));
|
||||
dirMeta.set('selector', o.literal(directive.selector));
|
||||
dirMeta.set('inputs', toOptionalLiteralArray(directive.inputs, o.literal));
|
||||
|
|
Loading…
Reference in New Issue