From be5737b261e154cd21c4b98f5f866be95a792bb3 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Sun, 13 Oct 2019 12:04:42 +0200 Subject: [PATCH] perf(ivy): move local references into consts array Follow-up from #32798. Moves the local references array into the component def's `consts` in order to make it compress better. Before: ``` const _c0 = ['foo', '']; SomeComp.ngComponentDef = defineComponent({ template: function() { element(0, 'div', null, _c0); } }); ``` After: ``` SomeComp.ngComponentDef = defineComponent({ consts: [['foo', '']], template: function() { element(0, 'div', null, 0); } }); ``` --- .../compliance/r3_compiler_compliance_spec.ts | 38 +++++++--------- .../r3_view_compiler_binding_spec.ts | 5 +-- .../r3_view_compiler_listener_spec.ts | 5 +-- .../r3_view_compiler_template_spec.ts | 6 +-- .../compiler/src/render3/view/template.ts | 38 ++++++++-------- packages/core/src/render3/definition.ts | 2 +- .../src/render3/instructions/container.ts | 11 +++-- .../core/src/render3/instructions/element.ts | 43 +++++++++++-------- .../render3/instructions/element_container.ts | 28 ++++++------ .../src/render3/instructions/lview_debug.ts | 2 +- .../core/src/render3/instructions/shared.ts | 6 +-- .../core/src/render3/interfaces/definition.ts | 2 +- packages/core/src/render3/interfaces/view.ts | 2 +- tools/public_api_guard/core/core.d.ts | 12 +++--- 14 files changed, 103 insertions(+), 97 deletions(-) diff --git a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts index df4e0fc67eed8..692d5e8abfdec 100644 --- a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts @@ -797,7 +797,6 @@ describe('compiler compliance', () => { `IfDirective.ngFactoryDef = function IfDirective_Factory(t) { return new (t || IfDirective)($r3$.ɵɵdirectiveInject($i$.TemplateRef)); };`; const MyComponentDefinition = ` - const $c1$ = ["foo", ""]; function MyComponent_li_2_Template(rf, ctx) { if (rf & 1) { $r3$.ɵɵelementStart(0, "li"); @@ -817,16 +816,16 @@ describe('compiler compliance', () => { selectors: [["my-component"]], decls: 3, vars: 0, - consts: [[${AttributeMarker.Template}, "if"]], + consts: [["foo", ""], [${AttributeMarker.Template}, "if"]], template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵɵelementStart(0, "ul", null, $c1$); - $r3$.ɵɵtemplate(2, MyComponent_li_2_Template, 2, 2, "li", 0); + $r3$.ɵɵelementStart(0, "ul", null, 0); + $r3$.ɵɵtemplate(2, MyComponent_li_2_Template, 2, 2, "li", 1); $r3$.ɵɵelementEnd(); } }, - directives:[IfDirective], - encapsulation: 2 + directives: [IfDirective], + encapsulation: 2 });`; const MyComponentFactory = @@ -2232,16 +2231,16 @@ describe('compiler compliance', () => { }; const MyComponentDefinition = ` - const $c1$ = ["user", ""]; … MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ type: MyComponent, selectors: [["my-component"]], decls: 3, vars: 1, + consts: [["user", ""]], template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵɵelement(0, "input", null, $c1$); + $r3$.ɵɵelement(0, "input", null, 0); $r3$.ɵɵtext(2); } if (rf & 2) { @@ -2293,9 +2292,6 @@ describe('compiler compliance', () => { }; const MyComponentDefinition = ` - const $c1$ = ["foo", ""]; - const $c3$ = ["baz", ""]; - const $c4$ = ["bar", ""]; function MyComponent_div_3_span_2_Template(rf, ctx) { if (rf & 1) { $r3$.ɵɵelementStart(0, "span"); @@ -2316,8 +2312,8 @@ describe('compiler compliance', () => { if (rf & 1) { $r3$.ɵɵelementStart(0, "div"); $r3$.ɵɵtext(1); - $r3$.ɵɵtemplate(2, MyComponent_div_3_span_2_Template, 2, 3, "span", 0); - $r3$.ɵɵelement(3, "span", null, $c4$); + $r3$.ɵɵtemplate(2, MyComponent_div_3_span_2_Template, 2, 3, "span", 1); + $r3$.ɵɵelement(3, "span", null, 3); $r3$.ɵɵelementEnd(); } if (rf & 2) { @@ -2334,13 +2330,13 @@ describe('compiler compliance', () => { selectors: [["my-component"]], decls: 6, vars: 1, - consts: [[${AttributeMarker.Template}, "if"]], + consts: [["foo", ""], [${AttributeMarker.Template}, "if"], ["baz", ""], ["bar", ""]], template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $r3$.ɵɵelement(0, "div", null, $c1$); + $r3$.ɵɵelement(0, "div", null, 0); $r3$.ɵɵtext(2); - $r3$.ɵɵtemplate(3, MyComponent_div_3_Template, 5, 2, "div", 0); - $r3$.ɵɵelement(4, "div", null, $c3$); + $r3$.ɵɵtemplate(3, MyComponent_div_3_Template, 5, 2, "div", 1); + $r3$.ɵɵelement(4, "div", null, 2); } if (rf & 2) { const $foo$ = $r3$.ɵɵreference(1); @@ -2382,8 +2378,6 @@ describe('compiler compliance', () => { }; const template = ` - const $c1$ = ["foo", ""]; - function MyComponent_div_0_span_3_Template(rf, ctx) { if (rf & 1) { $i0$.ɵɵelementStart(0, "span"); @@ -2401,8 +2395,8 @@ describe('compiler compliance', () => { function MyComponent_div_0_Template(rf, ctx) { if (rf & 1) { $i0$.ɵɵelementStart(0, "div"); - $i0$.ɵɵelement(1, "div", null, $c1$); - $i0$.ɵɵtemplate(3, MyComponent_div_0_span_3_Template, 2, 2, "span", 1); + $i0$.ɵɵelement(1, "div", null, 1); + $i0$.ɵɵtemplate(3, MyComponent_div_0_span_3_Template, 2, 2, "span", 2); $i0$.ɵɵelementEnd(); } if (rf & 2) { @@ -2413,7 +2407,7 @@ describe('compiler compliance', () => { } // ... - consts: [[${AttributeMarker.Template}, "ngFor", "ngForOf"], [${AttributeMarker.Template}, "ngIf"]], + consts: [[${AttributeMarker.Template}, "ngFor", "ngForOf"], ["foo", ""], [${AttributeMarker.Template}, "ngIf"]], template:function MyComponent_Template(rf, ctx){ if (rf & 1) { $i0$.ɵɵtemplate(0, MyComponent_div_0_Template, 4, 1, "div", 0); diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts index 42316c2efc13b..f647d6b2d0415 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_binding_spec.ts @@ -1251,12 +1251,11 @@ describe('compiler compliance: bindings', () => { `); const template = ` - const $_c1$ = ["myRef", ""]; … - consts: [["id", "my-id"]], + consts: [["id", "my-id"], ["myRef", ""]], template:function MyComponent_Template(rf, $ctx$){ if (rf & 1) { - $i0$.ɵɵelementStart(0, "b", 0, $_c1$); + $i0$.ɵɵelementStart(0, "b", 0, 1); $i0$.ɵɵdisableBindings(); $i0$.ɵɵelementStart(2, "i"); $i0$.ɵɵtext(3, "Hello {{ name }}!"); diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts index 200cc5d1feaee..cfe68461ee7bc 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_listener_spec.ts @@ -193,14 +193,13 @@ describe('compiler compliance: listen()', () => { }; const MyComponentDefinition = ` - const $e2_refs$ = ["user", ""]; … MyComponent.ɵcmp = $r3$.ɵɵdefineComponent({ type: MyComponent, selectors: [["my-component"]], decls: 4, vars: 0, - consts: [[${AttributeMarker.Bindings}, "click"]], + consts: [[${AttributeMarker.Bindings}, "click"], ["user", ""]], template: function MyComponent_Template(rf, ctx) { if (rf & 1) { const $s$ = $r3$.ɵɵgetCurrentView(); @@ -212,7 +211,7 @@ describe('compiler compliance: listen()', () => { }); $r3$.ɵɵtext(1, "Save"); $r3$.ɵɵelementEnd(); - $r3$.ɵɵelement(2, "input", null, $e2_refs$); + $r3$.ɵɵelement(2, "input", null, 1); } }, encapsulation: 2 diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts index 7ea9a3e0e96a5..dc8ac26d34476 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts @@ -491,8 +491,6 @@ describe('compiler compliance: template', () => { }; const template = ` - const $t0_refs$ = ["foo", ""]; - function MyComponent_ng_template_0_Template(rf, ctx) { if (rf & 1) { $i0$.ɵɵtext(0, "some-content"); @@ -500,10 +498,10 @@ describe('compiler compliance: template', () => { } // ... - + consts: [["foo", ""]], template: function MyComponent_Template(rf, ctx) { if (rf & 1) { - $i0$.ɵɵtemplate(0, MyComponent_ng_template_0_Template, 1, 0, "ng-template", null, $t0_refs$, $i0$.ɵɵtemplateRefExtractor); + $i0$.ɵɵtemplate(0, MyComponent_ng_template_0_Template, 1, 0, "ng-template", null, 0, $i0$.ɵɵtemplateRefExtractor); } }`; diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index 5786805778c10..e41a1ef9b4db1 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -606,10 +606,11 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver // add attributes for directive and projection matching purposes attributes.push(...this.prepareNonRenderAttrs( allOtherInputs, element.outputs, stylingBuilder, [], i18nAttrs, ngProjectAsAttr)); - parameters.push(this.addConstants(attributes)); + parameters.push(this.addAttrsToConsts(attributes)); // local refs (ex.:
) - parameters.push(this.prepareRefsParameter(element.references)); + const refs = this.prepareRefsArray(element.references); + parameters.push(this.addToConsts(refs)); const wasInNamespace = this._namespace; const currentNamespace = this.getNamespaceInstruction(namespaceKey); @@ -869,11 +870,12 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver (a: t.TextAttribute) => { attrsExprs.push(asLiteral(a.name), asLiteral(a.value)); }); attrsExprs.push(...this.prepareNonRenderAttrs( template.inputs, template.outputs, undefined, template.templateAttrs)); - parameters.push(this.addConstants(attrsExprs)); + parameters.push(this.addAttrsToConsts(attrsExprs)); // local refs (ex.: ) if (template.references && template.references.length) { - parameters.push(this.prepareRefsParameter(template.references)); + const refs = this.prepareRefsArray(template.references); + parameters.push(this.addToConsts(refs)); parameters.push(o.importExpr(R3.templateRefExtractor)); } @@ -1294,24 +1296,26 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver return attrExprs; } - private addConstants(constExprs: o.Expression[]): o.LiteralExpr { - if (constExprs.length > 0) { - const literal = o.literalArr(constExprs); + private addToConsts(expression: o.Expression): o.LiteralExpr { + if (o.isNull(expression)) { + return o.TYPED_NULL_EXPR; + } - // Try to reuse a literal that's already in the array, if possible. - for (let i = 0; i < this._constants.length; i++) { - if (this._constants[i].isEquivalent(literal)) { - return o.literal(i); - } + // Try to reuse a literal that's already in the array, if possible. + for (let i = 0; i < this._constants.length; i++) { + if (this._constants[i].isEquivalent(expression)) { + return o.literal(i); } - - return o.literal(this._constants.push(literal) - 1); } - return o.TYPED_NULL_EXPR; + return o.literal(this._constants.push(expression) - 1); + } + + private addAttrsToConsts(attrs: o.Expression[]): o.LiteralExpr { + return attrs.length > 0 ? this.addToConsts(o.literalArr(attrs)) : o.TYPED_NULL_EXPR; } - private prepareRefsParameter(references: t.Reference[]): o.Expression { + private prepareRefsArray(references: t.Reference[]): o.Expression { if (!references || references.length === 0) { return o.TYPED_NULL_EXPR; } @@ -1336,7 +1340,7 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver return [reference.name, reference.value]; })); - return this.constantPool.getConstLiteral(asLiteral(refsParam), true); + return asLiteral(refsParam); } private prepareListenerParameter(tagName: string, outputAst: t.BoundEvent, index: number): diff --git a/packages/core/src/render3/definition.ts b/packages/core/src/render3/definition.ts index f71737daf9f4e..31185762b0020 100644 --- a/packages/core/src/render3/definition.ts +++ b/packages/core/src/render3/definition.ts @@ -173,7 +173,7 @@ export function ɵɵdefineComponent(componentDefinition: { template: ComponentTemplate; /** Constants for the nodes in the component's view. */ - consts?: TAttributes[]; + consts?: (TAttributes | string)[]; /** * An array of `ngContent[selector]` values that were found in the template. diff --git a/packages/core/src/render3/instructions/container.ts b/packages/core/src/render3/instructions/container.ts index 1a2375786f209..4841d7307c3ab 100644 --- a/packages/core/src/render3/instructions/container.ts +++ b/packages/core/src/render3/instructions/container.ts @@ -57,7 +57,7 @@ export function ɵɵcontainer(index: number): void { * @param vars The number of bindings for this template * @param tagName The name of the container element, if applicable * @param constsIndex Index of template in the `consts` array. - * @param localRefs A set of local reference bindings on the element. + * @param localRefs Index of the local refenreces in the `consts` array. * @param localRefExtractor A function which extracts local-refs values from the template. * Defaults to the current element associated with the local-ref. * @@ -65,7 +65,7 @@ export function ɵɵcontainer(index: number): void { */ export function ɵɵtemplate( index: number, templateFn: ComponentTemplate| null, decls: number, vars: number, - tagName?: string | null, constsIndex?: number | null, localRefs?: string[] | null, + tagName?: string | null, constsIndex?: number | null, localRefsIndex?: number | null, localRefExtractor?: LocalRefExtractor) { const lView = getLView(); const tView = lView[TVIEW]; @@ -74,10 +74,13 @@ export function ɵɵtemplate( // TODO: consider a separate node type for templates const tContainerNode = containerInternal( lView, index, tagName || null, - tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex]); + tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex] as TAttributes); + const localRefs = tViewConsts === null || localRefsIndex == null ? + null : + tViewConsts[localRefsIndex] as string[]; if (tView.firstTemplatePass) { ngDevMode && ngDevMode.firstTemplatePass++; - resolveDirectives(tView, lView, tContainerNode, localRefs || null); + resolveDirectives(tView, lView, tContainerNode, localRefs); registerPostOrderHooks(tView, tContainerNode); const embeddedTView = tContainerNode.tViews = createTView( diff --git a/packages/core/src/render3/instructions/element.ts b/packages/core/src/render3/instructions/element.ts index 5e1c9c99362f5..3d600dafa7ea9 100644 --- a/packages/core/src/render3/instructions/element.ts +++ b/packages/core/src/render3/instructions/element.ts @@ -32,8 +32,8 @@ import {registerInitialStylingOnTNode} from './styling'; * * @param index Index of the element in the LView array * @param name Name of the DOM Node - * @param constsIndex Index of the element in the `consts` array. - * @param localRefs A set of local reference bindings on the element. + * @param attrsIndex Index of the element's attributes in the `consts` array. + * @param localRefsIndex Index of the element's local references in the `consts` array. * * Attributes and localRefs are passed as an array of strings where elements with an even index * hold an attribute name and elements with an odd index hold an attribute value, ex.: @@ -42,25 +42,30 @@ import {registerInitialStylingOnTNode} from './styling'; * @codeGenApi */ export function ɵɵelementStart( - index: number, name: string, constsIndex?: number | null, localRefs?: string[] | null): void { + index: number, name: string, attrsIndex?: number | null, localRefsIndex?: number): void { const lView = getLView(); const tView = lView[TVIEW]; const tViewConsts = tView.consts; - const consts = tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex]; - ngDevMode && assertEqual( - lView[BINDING_INDEX], tView.bindingStartIndex, - 'elements should be created before any bindings'); - - ngDevMode && ngDevMode.rendererCreateElement++; - ngDevMode && assertDataInRange(lView, index + HEADER_OFFSET); + const attrs = + tViewConsts === null || attrsIndex == null ? null : tViewConsts[attrsIndex] as TAttributes; + const localRefs = tViewConsts === null || localRefsIndex === undefined ? + null : + tViewConsts[localRefsIndex] as string[]; + if (ngDevMode) { + assertEqual( + lView[BINDING_INDEX], tView.bindingStartIndex, + 'elements should be created before any bindings'); + ngDevMode.rendererCreateElement++; + assertDataInRange(lView, index + HEADER_OFFSET); + } const renderer = lView[RENDERER]; const native = lView[index + HEADER_OFFSET] = elementCreate(name, renderer, getNamespace()); - const tNode = getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.Element, name, consts); + const tNode = getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.Element, name, attrs); - if (consts != null) { - const lastAttrIndex = setUpAttributes(renderer, native, consts); + if (attrs != null) { + const lastAttrIndex = setUpAttributes(renderer, native, attrs); if (tView.firstTemplatePass) { - registerInitialStylingOnTNode(tNode, consts, lastAttrIndex); + registerInitialStylingOnTNode(tNode, attrs, lastAttrIndex); } } @@ -84,7 +89,7 @@ export function ɵɵelementStart( // and `[class]` bindings work for multiple directives.) if (tView.firstTemplatePass) { ngDevMode && ngDevMode.firstTemplatePass++; - resolveDirectives(tView, lView, tNode, localRefs || null); + resolveDirectives(tView, lView, tNode, localRefs); if (tView.queries !== null) { tView.queries.elementStart(tView, tNode); @@ -146,14 +151,14 @@ export function ɵɵelementEnd(): void { * * @param index Index of the element in the data array * @param name Name of the DOM Node - * @param constsIndex Index of the element in the `consts` array. - * @param localRefs A set of local reference bindings on the element. + * @param attrsIndex Index of the element's attributes in the `consts` array. + * @param localRefsIndex Index of the element's local references in the `consts` array. * * @codeGenApi */ export function ɵɵelement( - index: number, name: string, constsIndex?: number | null, localRefs?: string[] | null): void { - ɵɵelementStart(index, name, constsIndex, localRefs); + index: number, name: string, attrsIndex?: number | null, localRefsIndex?: number): void { + ɵɵelementStart(index, name, attrsIndex, localRefsIndex); ɵɵelementEnd(); } diff --git a/packages/core/src/render3/instructions/element_container.ts b/packages/core/src/render3/instructions/element_container.ts index 92b8392039958..85ee585127991 100644 --- a/packages/core/src/render3/instructions/element_container.ts +++ b/packages/core/src/render3/instructions/element_container.ts @@ -26,8 +26,8 @@ import {registerInitialStylingOnTNode} from './styling'; * The instruction must later be followed by `elementContainerEnd()` call. * * @param index Index of the element in the LView array - * @param constsIndex Index of the container in the `consts` array. - * @param localRefs A set of local reference bindings on the element. + * @param attrsIndex Index of the container attributes in the `consts` array. + * @param localRefsIndex Index of the container's local references in the `consts` array. * * Even if this instruction accepts a set of attributes no actual attribute values are propagated to * the DOM (as a comment node can't have attributes). Attributes are here only for directive @@ -36,13 +36,17 @@ import {registerInitialStylingOnTNode} from './styling'; * @codeGenApi */ export function ɵɵelementContainerStart( - index: number, constsIndex?: number | null, localRefs?: string[] | null): void { + index: number, attrsIndex?: number | null, localRefsIndex?: number): void { const lView = getLView(); const tView = lView[TVIEW]; const renderer = lView[RENDERER]; const tagName = 'ng-container'; const tViewConsts = tView.consts; - const consts = tViewConsts === null || constsIndex == null ? null : tViewConsts[constsIndex]; + const attrs = + tViewConsts === null || attrsIndex == null ? null : tViewConsts[attrsIndex] as TAttributes; + const localRefs = tViewConsts === null || localRefsIndex === undefined ? + null : + tViewConsts[localRefsIndex] as string[]; ngDevMode && assertEqual( lView[BINDING_INDEX], tView.bindingStartIndex, 'element containers should be created before any bindings'); @@ -53,12 +57,12 @@ export function ɵɵelementContainerStart( ngDevMode && assertDataInRange(lView, index - 1); const tNode = - getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.ElementContainer, tagName, consts); + getOrCreateTNode(tView, lView[T_HOST], index, TNodeType.ElementContainer, tagName, attrs); - if (consts && tView.firstTemplatePass) { + if (attrs && tView.firstTemplatePass) { // While ng-container doesn't necessarily support styling, we use the style context to identify // and execute directives on the ng-container. - registerInitialStylingOnTNode(tNode, consts as TAttributes, 0); + registerInitialStylingOnTNode(tNode, attrs, 0); } appendChild(native, tNode, lView); @@ -66,7 +70,7 @@ export function ɵɵelementContainerStart( if (tView.firstTemplatePass) { ngDevMode && ngDevMode.firstTemplatePass++; - resolveDirectives(tView, lView, tNode, localRefs || null); + resolveDirectives(tView, lView, tNode, localRefs); if (tView.queries) { tView.queries.elementStart(tView, tNode); } @@ -114,13 +118,13 @@ export function ɵɵelementContainerEnd(): void { * and {@link elementContainerEnd} * * @param index Index of the element in the LView array - * @param constsIndex Index of the container in the `consts` array. - * @param localRefs A set of local reference bindings on the element. + * @param constsIndex Index of the container attributes in the `consts` array. + * @param localRefsIndex Index of the container's local references in the `consts` array. * * @codeGenApi */ export function ɵɵelementContainer( - index: number, constsIndex?: number | null, localRefs?: string[] | null): void { - ɵɵelementContainerStart(index, constsIndex, localRefs); + index: number, constsIndex?: number | null, localRefsIndex?: number): void { + ɵɵelementContainerStart(index, constsIndex, localRefsIndex); ɵɵelementContainerEnd(); } diff --git a/packages/core/src/render3/instructions/lview_debug.ts b/packages/core/src/render3/instructions/lview_debug.ts index 1b99765ad32d8..754b8b97dce32 100644 --- a/packages/core/src/render3/instructions/lview_debug.ts +++ b/packages/core/src/render3/instructions/lview_debug.ts @@ -102,7 +102,7 @@ export const TViewConstructor = class TView implements ITView { public pipeRegistry: PipeDefList|null, // public firstChild: TNode|null, // public schemas: SchemaMetadata[]|null, // - public consts: TAttributes[]|null, // + public consts: (TAttributes|string)[]|null, // ) {} get template_(): string { diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index 5d21b2ba90015..920525d767a55 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -592,7 +592,7 @@ export function createTView( viewIndex: number, templateFn: ComponentTemplate| null, decls: number, vars: number, directives: DirectiveDefListOrFactory | null, pipes: PipeDefListOrFactory | null, viewQuery: ViewQueriesFunction| null, schemas: SchemaMetadata[] | null, - consts: TAttributes[] | null): TView { + consts: (TAttributes | string)[] | null): TView { ngDevMode && ngDevMode.tView++; const bindingStartIndex = HEADER_OFFSET + decls; // This length does not yet contain host bindings from child directives because at this point, @@ -631,7 +631,7 @@ export function createTView( typeof pipes === 'function' ? pipes() : pipes, // pipeRegistry: PipeDefList|null, null, // firstChild: TNode|null, schemas, // schemas: SchemaMetadata[]|null, - consts) : // consts: TAttributes[] + consts) : // consts: (TAttributes|string)[]|null { id: viewIndex, blueprint: blueprint, @@ -1044,7 +1044,7 @@ export function resolveDirectives( if (!getBindingsEnabled()) return; const directives: DirectiveDef[]|null = findDirectiveMatches(tView, lView, tNode); - const exportsMap: ({[key: string]: number} | null) = localRefs ? {'': -1} : null; + const exportsMap: ({[key: string]: number} | null) = localRefs === null ? null : {'': -1}; if (directives) { initNodeFlags(tNode, tView.data.length, directives.length); diff --git a/packages/core/src/render3/interfaces/definition.ts b/packages/core/src/render3/interfaces/definition.ts index 1789867568518..4bb29a39bce23 100644 --- a/packages/core/src/render3/interfaces/definition.ts +++ b/packages/core/src/render3/interfaces/definition.ts @@ -244,7 +244,7 @@ export interface ComponentDef extends DirectiveDef { readonly template: ComponentTemplate; /** Constants associated with the component's view. */ - readonly consts: TAttributes[]|null; + readonly consts: (TAttributes|string)[]|null; /** * An array of `ngContent[selector]` values that were found in the template. diff --git a/packages/core/src/render3/interfaces/view.ts b/packages/core/src/render3/interfaces/view.ts index 7c0aab9196b3a..fe15a7ee12f1e 100644 --- a/packages/core/src/render3/interfaces/view.ts +++ b/packages/core/src/render3/interfaces/view.ts @@ -566,7 +566,7 @@ export interface TView { * Array of attributes for all of the elements in the view. Used * for directive matching and attribute bindings. */ - consts: TAttributes[]|null; + consts: (TAttributes|string)[]|null; } export const enum RootContextFlags {Empty = 0b00, DetectChanges = 0b01, FlushPlayers = 0b10} diff --git a/tools/public_api_guard/core/core.d.ts b/tools/public_api_guard/core/core.d.ts index ded0c9951d70b..7871f34c1a8fa 100644 --- a/tools/public_api_guard/core/core.d.ts +++ b/tools/public_api_guard/core/core.d.ts @@ -784,7 +784,7 @@ export declare function ɵɵdefineComponent(componentDefinition: { contentQueries?: ContentQueriesFunction; exportAs?: string[]; template: ComponentTemplate; - consts?: TAttributes[]; + consts?: (TAttributes | string)[]; ngContentSelectors?: string[]; viewQuery?: ViewQueriesFunction | null; features?: ComponentDefFeature[]; @@ -850,19 +850,19 @@ export declare function ɵɵdirectiveInject(token: Type | InjectionToken | null, decls: number, vars: number, tagName?: string | null, constsIndex?: number | null, localRefs?: string[] | null, localRefExtractor?: LocalRefExtractor): void; +export declare function ɵɵtemplate(index: number, templateFn: ComponentTemplate | null, decls: number, vars: number, tagName?: string | null, constsIndex?: number | null, localRefsIndex?: number | null, localRefExtractor?: LocalRefExtractor): void; export declare function ɵɵtemplateRefExtractor(tNode: TNode, currentView: LView): ViewEngine_TemplateRef | null;