Skip to content

Commit eb74a96

Browse files
JoostKthePunderWoman
authored andcommitted
refactor(compiler-cli): separate used components from used directives in partial declaration (angular#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 angular#41104
1 parent 98de4cb commit eb74a96

File tree

13 files changed

+104
-78
lines changed

13 files changed

+104
-78
lines changed

packages/compiler-cli/linker/src/file_linker/partial_linkers/partial_component_linker_1.ts

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
* Use of this source code is governed by an MIT-style license that can be
66
* found in the LICENSE file at https://angular.io/license
77
*/
8-
import {compileComponentFromMetadata, ConstantPool, DeclarationListEmitMode, DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig, makeBindingParser, parseTemplate, R3ComponentMetadata, R3DeclareComponentMetadata, R3PartialDeclaration, R3UsedDirectiveMetadata} from '@angular/compiler';
8+
import {compileComponentFromMetadata, ConstantPool, DeclarationListEmitMode, DEFAULT_INTERPOLATION_CONFIG, InterpolationConfig, makeBindingParser, parseTemplate, R3ComponentMetadata, R3DeclareComponentMetadata, R3DeclareUsedDirectiveMetadata, R3PartialDeclaration, R3UsedDirectiveMetadata} from '@angular/compiler';
99
import {ChangeDetectionStrategy, ViewEncapsulation} from '@angular/compiler/src/core';
1010
import * as o from '@angular/compiler/src/output/output_ast';
1111

@@ -74,34 +74,42 @@ export class PartialComponentLinkerVersion1<TStatement, TExpression> implements
7474

7575
let declarationListEmitMode = DeclarationListEmitMode.Direct;
7676

77+
const collectUsedDirectives =
78+
(directives: AstValue<R3DeclareUsedDirectiveMetadata, TExpression>[]) => {
79+
return directives.map(directive => {
80+
const directiveExpr = directive.getObject();
81+
const type = directiveExpr.getValue('type');
82+
const selector = directiveExpr.getString('selector');
83+
84+
let typeExpr = type.getOpaque();
85+
const forwardRefType = extractForwardRef(type);
86+
if (forwardRefType !== null) {
87+
typeExpr = forwardRefType;
88+
declarationListEmitMode = DeclarationListEmitMode.Closure;
89+
}
90+
91+
return {
92+
type: typeExpr,
93+
selector: selector,
94+
inputs: directiveExpr.has('inputs') ?
95+
directiveExpr.getArray('inputs').map(input => input.getString()) :
96+
[],
97+
outputs: directiveExpr.has('outputs') ?
98+
directiveExpr.getArray('outputs').map(input => input.getString()) :
99+
[],
100+
exportAs: directiveExpr.has('exportAs') ?
101+
directiveExpr.getArray('exportAs').map(exportAs => exportAs.getString()) :
102+
null,
103+
};
104+
});
105+
};
106+
77107
let directives: R3UsedDirectiveMetadata[] = [];
108+
if (metaObj.has('components')) {
109+
directives.push(...collectUsedDirectives(metaObj.getArray('components')));
110+
}
78111
if (metaObj.has('directives')) {
79-
directives = metaObj.getArray('directives').map(directive => {
80-
const directiveExpr = directive.getObject();
81-
const type = directiveExpr.getValue('type');
82-
const selector = directiveExpr.getString('selector');
83-
84-
let typeExpr = type.getOpaque();
85-
const forwardRefType = extractForwardRef(type);
86-
if (forwardRefType !== null) {
87-
typeExpr = forwardRefType;
88-
declarationListEmitMode = DeclarationListEmitMode.Closure;
89-
}
90-
91-
return {
92-
type: typeExpr,
93-
selector: selector,
94-
inputs: directiveExpr.has('inputs') ?
95-
directiveExpr.getArray('inputs').map(input => input.getString()) :
96-
[],
97-
outputs: directiveExpr.has('outputs') ?
98-
directiveExpr.getArray('outputs').map(input => input.getString()) :
99-
[],
100-
exportAs: directiveExpr.has('exportAs') ?
101-
directiveExpr.getArray('exportAs').map(exportAs => exportAs.getString()) :
102-
null,
103-
};
104-
});
112+
directives.push(...collectUsedDirectives(metaObj.getArray('directives')));
105113
}
106114

107115
let pipes = new Map<string, o.Expression>();

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/GOLDEN_PARTIAL.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ SomeComp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type:
181181
export class MyApp {
182182
}
183183
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
184-
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"] }] });
184+
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"] }] });
185185
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
186186
type: Component,
187187
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:
236236
export class MyApp {
237237
}
238238
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
239-
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"] }] });
239+
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"] }] });
240240
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
241241
type: Component,
242242
args: [{ template: '<some-comp [prop]="[]" [otherProp]="[0, 1, 2]"></some-comp>' }]

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/content_projection/GOLDEN_PARTIAL.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ ComplexComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER
2929
export class MyApp {
3030
}
3131
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
32-
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" }] });
32+
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" }] });
3333
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
3434
type: Component,
3535
args: [{ selector: 'my-app', template: '<simple>content</simple> <complex></complex>' }]
@@ -224,7 +224,7 @@ SimpleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER"
224224
export class MyApp {
225225
}
226226
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
227-
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" }] });
227+
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" }] });
228228
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
229229
type: Component,
230230
args: [{ selector: 'my-app', template: '<simple><h1 ngProjectAs="[title]"></h1></simple>' }]
@@ -273,7 +273,7 @@ SimpleComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER"
273273
export class MyApp {
274274
}
275275
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
276-
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" }] });
276+
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" }] });
277277
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
278278
type: Component,
279279
args: [{ selector: 'my-app', template: '<simple><h1 ngProjectAs="[title],[header]"></h1></simple>' }]

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/lifecycle_hooks/GOLDEN_PARTIAL.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ SimpleLayout.ɵfac = function SimpleLayout_Factory(t) { return new (t || SimpleL
211211
SimpleLayout.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: SimpleLayout, selector: "simple-layout", ngImport: i0, template: `
212212
<lifecycle-comp [name]="name1"></lifecycle-comp>
213213
<lifecycle-comp [name]="name2"></lifecycle-comp>
214-
`, isInline: true, directives: [{ type: LifecycleComp, selector: "lifecycle-comp", inputs: ["name"] }] });
214+
`, isInline: true, components: [{ type: LifecycleComp, selector: "lifecycle-comp", inputs: ["name"] }] });
215215
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SimpleLayout, [{
216216
type: Component,
217217
args: [{

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: My
365365
<content-query-component>
366366
<div someDir></div>
367367
</content-query-component>
368-
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }, { type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
368+
`, isInline: true, components: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }], directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
369369
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
370370
type: Component,
371371
args: [{
@@ -524,7 +524,7 @@ MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: My
524524
<content-query-component>
525525
<div someDir></div>
526526
</content-query-component>
527-
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }, { type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
527+
`, isInline: true, components: [{ type: i0.forwardRef(function () { return ContentQueryComponent; }), selector: "content-query-component" }], directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
528528
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
529529
type: Component,
530530
args: [{

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ SomeDirective.ɵdir = i0.ɵɵngDeclareDirective({ version: "0.0.0-PLACEHOLDER",
2222
export class MyComponent {
2323
}
2424
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
25-
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]" }] });
25+
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]" }] });
2626
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
2727
type: Component,
2828
args: [{ selector: 'my-component', template: '<child some-directive></child>!' }]
@@ -329,7 +329,7 @@ export class MyApp {
329329
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
330330
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: `
331331
<my-comp [names]="['Nancy', customName]"></my-comp>
332-
`, isInline: true, directives: [{ type: MyComp, selector: "my-comp", inputs: ["names"] }] });
332+
`, isInline: true, components: [{ type: MyComp, selector: "my-comp", inputs: ["names"] }] });
333333
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
334334
type: Component,
335335
args: [{
@@ -428,7 +428,7 @@ MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
428428
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: `
429429
<my-comp [names]="['start-', n0, n1, n2, n3, n4, '-middle-', n5, n6, n7, n8, '-end']">
430430
</my-comp>
431-
`, isInline: true, directives: [{ type: MyComp, selector: "my-comp", inputs: ["names"] }] });
431+
`, isInline: true, components: [{ type: MyComp, selector: "my-comp", inputs: ["names"] }] });
432432
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
433433
type: Component,
434434
args: [{
@@ -509,7 +509,7 @@ export class MyApp {
509509
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
510510
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: `
511511
<object-comp [config]="{'duration': 500, animation: name}"></object-comp>
512-
`, isInline: true, directives: [{ type: ObjectComp, selector: "object-comp", inputs: ["config"] }] });
512+
`, isInline: true, components: [{ type: ObjectComp, selector: "object-comp", inputs: ["config"] }] });
513513
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
514514
type: Component,
515515
args: [{
@@ -587,7 +587,7 @@ MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
587587
MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: `
588588
<nested-comp [config]="{animation: name, actions: [{ opacity: 0, duration: 0}, {opacity: 1, duration: duration }]}">
589589
</nested-comp>
590-
`, isInline: true, directives: [{ type: NestedComp, selector: "nested-comp", inputs: ["config"] }] });
590+
`, isInline: true, components: [{ type: NestedComp, selector: "nested-comp", inputs: ["config"] }] });
591591
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
592592
type: Component,
593593
args: [{

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ InfinityCmp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty
6262
export class MyComponent {
6363
}
6464
MyComponent.ɵfac = function MyComponent_Factory(t) { return new (t || MyComponent)(); };
65-
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" }] });
65+
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" }] });
6666
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
6767
type: Component,
6868
args: [{

packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export class MyApp {
99
}
1010
}
1111
MyApp.ɵfac = function MyApp_Factory(t) { return new (t || MyApp)(); };
12-
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"] }] });
12+
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"] }] });
1313
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{
1414
type: Component,
1515
args: [{ selector: 'my-app', template: '<todo [data]="list"></todo>' }]

packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty
158158
<button [attr.title]="myTitle" [attr.id]="buttonId" [attr.tabindex]="1"></button>
159159
<span [attr.id]="1" [attr.title]="'hello'" [attr.some-attr]="1 + 2"></span>
160160
<custom-element [attr.some-attr]="'one'" [attr.some-other-attr]="2"></custom-element>
161-
`, isInline: true, directives: [{ type: CustomEl, selector: "custom-element" }] });
161+
`, isInline: true, components: [{ type: CustomEl, selector: "custom-element" }] });
162162
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
163163
type: Component,
164164
args: [{

packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/GOLDEN_PARTIAL.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty
519519
<button [title]="myTitle" [id]="buttonId" [tabindex]="1"></button>
520520
<span [id]="1" [title]="'hello'" [someProp]="1 + 2"></span>
521521
<custom-element [prop]="'one'" [otherProp]="2"></custom-element>
522-
`, isInline: true, directives: [{ type: SpanDir, selector: "span", inputs: ["someProp"] }, { type: CustomEl, selector: "custom-element", inputs: ["prop", "otherProp"] }] });
522+
`, isInline: true, components: [{ type: CustomEl, selector: "custom-element", inputs: ["prop", "otherProp"] }], directives: [{ type: SpanDir, selector: "span", inputs: ["someProp"] }] });
523523
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{
524524
type: Component,
525525
args: [{

0 commit comments

Comments
 (0)