diff --git a/packages/compiler-cli/linker/src/file_linker/partial_linkers/partial_component_linker_1.ts b/packages/compiler-cli/linker/src/file_linker/partial_linkers/partial_component_linker_1.ts index 014ac0024d..d2d0d09f00 100644 --- a/packages/compiler-cli/linker/src/file_linker/partial_linkers/partial_component_linker_1.ts +++ b/packages/compiler-cli/linker/src/file_linker/partial_linkers/partial_component_linker_1.ts @@ -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 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[]) => { + 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(); diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/GOLDEN_PARTIAL.js index faba87db8b..8af31a6ed5 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/GOLDEN_PARTIAL.js @@ -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: '', 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: '', isInline: true, components: [{ type: SomeComp, selector: "some-comp", inputs: ["prop", "otherProp"] }] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{ type: Component, args: [{ template: '' }] @@ -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: '', 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: '', isInline: true, components: [{ type: SomeComp, selector: "some-comp", inputs: ["prop", "otherProp"] }] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{ type: Component, args: [{ template: '' }] diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/content_projection/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/content_projection/GOLDEN_PARTIAL.js index 0c1d56d7dc..b79831460d 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/content_projection/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/content_projection/GOLDEN_PARTIAL.js @@ -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: 'content ', 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: 'content ', 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: 'content ' }] @@ -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: '

', isInline: true, directives: [{ type: SimpleComponent, selector: "simple" }] }); +MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '

', isInline: true, components: [{ type: SimpleComponent, selector: "simple" }] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{ type: Component, args: [{ selector: 'my-app', template: '

' }] @@ -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: '

', isInline: true, directives: [{ type: SimpleComponent, selector: "simple" }] }); +MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: MyApp, selector: "my-app", ngImport: i0, template: '

', isInline: true, components: [{ type: SimpleComponent, selector: "simple" }] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyApp, [{ type: Component, args: [{ selector: 'my-app', template: '

' }] diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/lifecycle_hooks/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/lifecycle_hooks/GOLDEN_PARTIAL.js index 3bc72ebaa5..3f5de1ea6f 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/lifecycle_hooks/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/lifecycle_hooks/GOLDEN_PARTIAL.js @@ -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: ` - `, 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: [{ diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js index efd702fb5e..b7cbcb9b75 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js @@ -365,7 +365,7 @@ MyApp.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: My
- `, 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
- `, 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: [{ diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js index 80010dc803..b47646b927 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/value_composition/GOLDEN_PARTIAL.js @@ -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: '!', 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: '!', 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: '!' }] @@ -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: ` -`, 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: ` -`, 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: ` -`, 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: ` -`, 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: [{ diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js index 1803fcba88..7f38d8cf9d 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/elements/GOLDEN_PARTIAL.js @@ -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: '

test

', 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: '

test

', isInline: true, components: [{ type: MathCmp, selector: "math" }, { type: InfinityCmp, selector: "infinity" }] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{ type: Component, args: [{ diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js index b431ff126e..715b3fc61a 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler/GOLDEN_PARTIAL.js @@ -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: '', 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: '', 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: '' }] diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js index 3918059f50..27a2235efd 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/attribute_bindings/GOLDEN_PARTIAL.js @@ -158,7 +158,7 @@ MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty - `, 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: [{ diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/GOLDEN_PARTIAL.js index b56b395681..1be3bd8735 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_bindings/property_bindings/GOLDEN_PARTIAL.js @@ -519,7 +519,7 @@ MyComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", ty - `, 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: [{ diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/GOLDEN_PARTIAL.js index e3813aacd0..f96b4a7bca 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_view_compiler_listener/GOLDEN_PARTIAL.js @@ -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: ``, 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: ``, isInline: true, components: [{ type: MyApp, selector: "my-app" }] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MyComponent, [{ type: Component, args: [{ selector: 'my-component', template: `` }] @@ -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: `
- `, 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: [{ diff --git a/packages/compiler/src/render3/partial/api.ts b/packages/compiler/src/render3/partial/api.ts index fabc62dd77..fa9e4d5895 100644 --- a/packages/compiler/src/render3/partial/api.ts +++ b/packages/compiler/src/render3/partial/api.ts @@ -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. diff --git a/packages/compiler/src/render3/partial/component.ts b/packages/compiler/src/render3/partial/component.ts index 74080d082b..d54f1e7b84 100644 --- a/packages/compiler/src/render3/partial/component.ts +++ b/packages/compiler/src/render3/partial/component.ts @@ -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(); + const directives = meta.directives.filter(predicate); + return toOptionalLiteralArray(directives, directive => { + const dirMeta = new DefinitionMap(); dirMeta.set('type', wrapType(directive.type)); dirMeta.set('selector', o.literal(directive.selector)); dirMeta.set('inputs', toOptionalLiteralArray(directive.inputs, o.literal));