From c0386757b1d4a4f1e9eaf190819abe358342b9ad Mon Sep 17 00:00:00 2001 From: Ben Lesh Date: Mon, 3 Jun 2019 10:29:14 -0700 Subject: [PATCH] =?UTF-8?q?refactor(ivy):=20inherently=20call=20=C9=B5?= =?UTF-8?q?=C9=B5select(0)=20(#30830)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Refactors compiler to stop generating `ɵɵselect(0)` instructions - Alters template execution to always call the equivalent of `ɵɵselect(0)` before running a template in update mode - Updates tests to not check for or call `ɵɵselect(0)`. The goal here is to reduce the size of generated templates PR Close #30830 --- .../ngcc/test/rendering/renderer_spec.ts | 1 - .../compliance/r3_compiler_compliance_spec.ts | 12 -------- .../r3_view_compiler_binding_spec.ts | 5 ---- .../r3_view_compiler_directives_spec.ts | 3 -- .../compliance/r3_view_compiler_i18n_spec.ts | 22 +------------- .../r3_view_compiler_listener_spec.ts | 1 - .../test/compliance/r3_view_compiler_spec.ts | 3 -- .../r3_view_compiler_styling_spec.ts | 20 ------------- .../r3_view_compiler_template_spec.ts | 8 ----- .../compiler/src/render3/view/template.ts | 4 ++- .../core/src/render3/instructions/select.ts | 7 ++++- .../core/src/render3/instructions/shared.ts | 19 +++++++----- .../cyclic_import/bundle.golden_symbols.json | 3 ++ .../hello_world/bundle.golden_symbols.json | 3 ++ .../bundling/todo/bundle.golden_symbols.json | 3 ++ .../core/test/render3/instructions_spec.ts | 29 ++----------------- .../core/test/render3/integration_spec.ts | 1 - .../styling/class_and_style_bindings_spec.ts | 6 ---- .../core/test/render3/styling/players_spec.ts | 1 - 19 files changed, 33 insertions(+), 118 deletions(-) diff --git a/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts b/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts index a20e13174b..56546265de 100644 --- a/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts @@ -167,7 +167,6 @@ describe('Renderer', () => { `A.ngComponentDef = ɵngcc0.ɵɵdefineComponent({ type: A, selectors: [["a"]], factory: function A_Factory(t) { return new (t || A)(); }, consts: 1, vars: 1, template: function A_Template(rf, ctx) { if (rf & 1) { ɵngcc0.ɵɵtext(0); } if (rf & 2) { - ɵngcc0.ɵɵselect(0); ɵngcc0.ɵɵtextInterpolate(ctx.person.name); } }, encapsulation: 2 }); /*@__PURE__*/ ɵngcc0.ɵsetClassMetadata(A, [{ 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 78b52bc5a4..4890c89868 100644 --- a/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts @@ -316,7 +316,6 @@ describe('compiler compliance', () => { $r3$.ɵɵelement(0, "div", $e0_attrs$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("id", ctx.id); } } @@ -372,7 +371,6 @@ describe('compiler compliance', () => { $r3$.ɵɵpipe(1,"pipe"); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("ternary", ctx.cond ? $r3$.ɵɵpureFunction1(8, $c0$, ctx.a): $c1$); $r3$.ɵɵproperty("pipe", $r3$.ɵɵpipeBind3(1, 4, ctx.value, 1, 2)); $r3$.ɵɵproperty("and", ctx.cond && $r3$.ɵɵpureFunction1(10, $c0$, ctx.b)); @@ -504,7 +502,6 @@ describe('compiler compliance', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleProp(0, ctx.color); $r3$.ɵɵclassProp(0, ctx.error); $r3$.ɵɵstylingApply(); @@ -886,7 +883,6 @@ describe('compiler compliance', () => { $r3$.ɵɵelement(0, "my-comp", $e0_attrs$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("names", $r3$.ɵɵpureFunction1(1, $e0_ff$, ctx.customName)); } }, @@ -969,7 +965,6 @@ describe('compiler compliance', () => { $r3$.ɵɵelement(0, "my-comp", $e0_attr$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("names", $r3$.ɵɵpureFunctionV(1, $e0_ff$, [ctx.n0, ctx.n1, ctx.n2, ctx.n3, ctx.n4, ctx.n5, ctx.n6, ctx.n7, ctx.n8])); } @@ -1033,7 +1028,6 @@ describe('compiler compliance', () => { $r3$.ɵɵelement(0, "object-comp", $e0_attrs$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("config", $r3$.ɵɵpureFunction1(1, $e0_ff$, ctx.name)); } }, @@ -1102,7 +1096,6 @@ describe('compiler compliance', () => { $r3$.ɵɵelement(0, "nested-comp", $e0_attrs$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty( "config", $r3$.ɵɵpureFunction2(5, $e0_ff_2$, ctx.name, $r3$.ɵɵpureFunction1(3, $e0_ff_1$, $r3$.ɵɵpureFunction1(1, $e0_ff$, ctx.duration)))); @@ -1314,7 +1307,6 @@ describe('compiler compliance', () => { $r3$.ɵɵtemplate(2, Cmp_ng_template_2_Template, 2, 0, "ng-template"); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("ngIf", ctx.visible); $r3$.ɵɵselect(1); $r3$.ɵɵproperty("ngIf", ctx.visible); @@ -2119,7 +2111,6 @@ describe('compiler compliance', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵtextInterpolate($r3$.ɵɵpipeBind2(1, 3, $r3$.ɵɵpipeBind2(2, 6, ctx.name, ctx.size), ctx.size)); $r3$.ɵɵselect(4); $r3$.ɵɵtextInterpolate2("", $r3$.ɵɵpipeBindV(5, 9, $r3$.ɵɵpureFunction1(18, $c0$, ctx.name)), " ", ctx.name ? 1 : $r3$.ɵɵpipeBind1(6, 16, 2), ""); @@ -2184,7 +2175,6 @@ describe('compiler compliance', () => { $r3$.ɵɵpipe(5, "myPipe"); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵtextInterpolate5( "0:", i0.ɵɵpipeBind1(1, 5, ctx.name), "1:", i0.ɵɵpipeBind2(2, 7, ctx.name, 1), @@ -2412,7 +2402,6 @@ describe('compiler compliance', () => { $i0$.ɵɵtemplate(0, MyComponent_div_0_Template, 4, 1, "div", $c0$); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("ngForOf", ctx.items); } }`; @@ -2493,7 +2482,6 @@ describe('compiler compliance', () => { $r3$.ɵɵelement(1, "lifecycle-comp", $e1_attrs$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("name", ctx.name1); $r3$.ɵɵselect(1); $r3$.ɵɵproperty("name", ctx.name2); 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 3bd84d27c8..4faccf475c 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 @@ -81,7 +81,6 @@ describe('compiler compliance: bindings', () => { $i0$.ɵɵelement(0, "a", $e0_attrs$); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("title", $ctx$.title); } }`; @@ -116,7 +115,6 @@ describe('compiler compliance: bindings', () => { $i0$.ɵɵelement(0, "a", $e0_attrs$); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵpropertyInterpolate1("title", "Hello ", $ctx$.name, ""); } }`; @@ -173,7 +171,6 @@ describe('compiler compliance: bindings', () => { $i0$.ɵɵelement(0, "label", _c0); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("for", ctx.forValue); } }`; @@ -469,7 +466,6 @@ describe('compiler compliance: bindings', () => { const template = ` … if (rf & 2) { - i0.ɵɵselect(0); i0.ɵɵpropertyInterpolateV("title", ["a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i", ctx.nine, "j"]); i0.ɵɵselect(1); i0.ɵɵpropertyInterpolate8("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i"); @@ -514,7 +510,6 @@ describe('compiler compliance: bindings', () => { const template = ` … if (rf & 2) { - i0.ɵɵselect(0); i0.ɵɵattributeInterpolateV("title", ["a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i", ctx.nine, "j"]); i0.ɵɵselect(1); i0.ɵɵattributeInterpolate8("title", "a", ctx.one, "b", ctx.two, "c", ctx.three, "d", ctx.four, "e", ctx.five, "f", ctx.six, "g", ctx.seven, "h", ctx.eight, "i"); diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts index 6ef22fdcf0..c4c81049b1 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_directives_spec.ts @@ -139,7 +139,6 @@ describe('compiler compliance: directives', () => { $r3$.ɵɵelement(0, "div", _c0); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("someDirective", true); } }, @@ -254,7 +253,6 @@ describe('compiler compliance: directives', () => { $r3$.ɵɵtemplate(0, MyComponent_ng_container_0_Template, 2, 0, "ng-container", $_c0$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("ngIf", ctx.showing); } }, @@ -302,7 +300,6 @@ describe('compiler compliance: directives', () => { $r3$.ɵɵtemplate(0, MyComponent_ng_template_0_Template, 0, 0, "ng-template", $c0_a0$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("someDirective", true); } }, diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts index 6f5a741f96..583f0e11cd 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_i18n_spec.ts @@ -464,7 +464,6 @@ describe('i18n support in the view compiler', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($r3$.ɵɵpipeBind1(1, 6, ctx.valueA))); $r3$.ɵɵi18nExp($r3$.ɵɵbind(ctx.valueB)); $r3$.ɵɵi18nApply(2); @@ -514,7 +513,6 @@ describe('i18n support in the view compiler', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($r3$.ɵɵpipeBind1(1, 1, ctx.valueA))); $r3$.ɵɵi18nApply(2); } @@ -574,7 +572,6 @@ describe('i18n support in the view compiler', () => { $r3$.ɵɵtemplate(0, MyComponent_div_0_Template, 4, 3, "div", $_c0$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("ngForOf", ctx.items); } } @@ -598,7 +595,7 @@ describe('i18n support in the view compiler', () => { const output = String.raw ` const $_c0$ = [ - "id", "dynamic-1", + "id", "dynamic-1", ${AttributeMarker.I18n}, "aria-roledescription", "title", "aria-label" ]; var $I18N_1$; @@ -693,7 +690,6 @@ describe('i18n support in the view compiler', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($r3$.ɵɵpipeBind1(1, 6, ctx.valueA))); $r3$.ɵɵi18nExp($r3$.ɵɵbind(ctx.valueB)); $r3$.ɵɵi18nApply(2); @@ -761,7 +757,6 @@ describe('i18n support in the view compiler', () => { $r3$.ɵɵtemplate(0, MyComponent_div_0_Template, 4, 3, "div", $_c0$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("ngForOf", ctx.items); } } @@ -1470,7 +1465,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r1$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r1$.id)); $r3$.ɵɵi18nApply(1); } @@ -1533,7 +1527,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r2$ = $r3$.ɵɵnextContext(2); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r2$.valueC)); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r2$.valueD)); $r3$.ɵɵi18nApply(0); @@ -1603,7 +1596,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r1$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r1$.valueE + $ctx_r1$.valueF)); $r3$.ɵɵi18nExp($r3$.ɵɵbind($r3$.ɵɵpipeBind1(3, 2, $ctx_r1$.valueG))); $r3$.ɵɵi18nApply(0); @@ -1680,7 +1672,6 @@ describe('i18n support in the view compiler', () => { $r3$.ɵɵtemplate(0, MyComponent_div_0_Template, 3, 1, "div", $_c0$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("ngIf", ctx.visible); } } @@ -1934,7 +1925,6 @@ describe('i18n support in the view compiler', () => { $r3$.ɵɵpipe(1, "uppercase"); } if (rf & 2) { const $ctx_r0$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($r3$.ɵɵpipeBind1(1, 1, $ctx_r0$.valueA))); $r3$.ɵɵi18nApply(0); } @@ -1990,7 +1980,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r0$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($r3$.ɵɵpipeBind1(1, 1, $ctx_r0$.valueA))); $r3$.ɵɵi18nApply(0); } @@ -2055,7 +2044,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r0$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r0$.gender)); $r3$.ɵɵi18nApply(0); } @@ -2103,7 +2091,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r2$ = $r3$.ɵɵnextContext(3); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r2$.valueC)); $r3$.ɵɵi18nApply(0); } @@ -2116,7 +2103,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r1$ = $r3$.ɵɵnextContext(2); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r1$.valueB)); $r3$.ɵɵi18nApply(0); } @@ -2151,7 +2137,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r0$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($r3$.ɵɵpipeBind1(1, 1, $ctx_r0$.valueA))); $r3$.ɵɵi18nApply(0); } @@ -2208,7 +2193,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r0$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r0$.age)); $r3$.ɵɵi18nApply(0); } @@ -2484,7 +2468,6 @@ describe('i18n support in the view compiler', () => { $r3$.ɵɵi18n(0, $I18N_0$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind(ctx.age)); $r3$.ɵɵi18nApply(0); } @@ -2912,7 +2895,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r0$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r0$.gender)); $r3$.ɵɵi18nApply(0); } @@ -3053,7 +3035,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r0$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r0$.age)); $r3$.ɵɵi18nApply(0); } @@ -3151,7 +3132,6 @@ describe('i18n support in the view compiler', () => { } if (rf & 2) { const $ctx_r0$ = $r3$.ɵɵnextContext(); - $r3$.ɵɵselect(0); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r0$.age)); $r3$.ɵɵi18nExp($r3$.ɵɵbind($ctx_r0$.otherAge)); $r3$.ɵɵi18nApply(0); 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 e40d62ad52..9f695ca116 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 @@ -163,7 +163,6 @@ describe('compiler compliance: listen()', () => { $r3$.ɵɵtemplate(0, MyComponent_div_0_Template, 3, 0, "div", $c0$); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("ngIf", ctx.showing); } } diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_spec.ts index 57b0e0b71e..22e570148e 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_spec.ts @@ -119,7 +119,6 @@ describe('r3_view_compiler', () => { $i0$.ɵɵtext(0); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵtextInterpolateV([" ", ctx.list[0], " ", ctx.list[1], " ", ctx.list[2], " ", ctx.list[3], " ", ctx.list[4], " ", ctx.list[5], " ", ctx.list[6], " ", ctx.list[7], " ", ctx.list[8], " "]); } } @@ -155,7 +154,6 @@ describe('r3_view_compiler', () => { $i0$.ɵɵelement(0, "div"); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("@attr", …); $i0$.ɵɵproperty("@binding", …); } @@ -187,7 +185,6 @@ describe('r3_view_compiler', () => { if (rf & 1) { $i0$.ɵɵelementStart(0, "div"); … - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("@mySelector", …); } }`; diff --git a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts index 8ac751f5f9..8fa503900f 100644 --- a/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts +++ b/packages/compiler-cli/test/compliance/r3_view_compiler_styling_spec.ts @@ -228,7 +228,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelement(2, "div"); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("@foo", ctx.exp); $r3$.ɵɵselect(1); $r3$.ɵɵproperty("@bar", undefined); @@ -290,7 +289,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵlistener("@myAnimation.done", function MyComponent_Template_div_animation_myAnimation_done_0_listener($event) { return ctx.onDone($event); }); $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("@myAnimation", ctx.exp); } }, @@ -391,7 +389,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleMap($ctx$.myStyleExp); $r3$.ɵɵstylingApply(); } @@ -457,7 +454,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵclassMap($r3$.ɵɵinterpolation1("foo foo-", $ctx$.fooId, "")); $r3$.ɵɵstylingApply(); } @@ -472,7 +468,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵclassMap($r3$.ɵɵinterpolation2("foo foo-", $ctx$.fooId, "-", $ctx$.fooUsername, "")); $r3$.ɵɵstylingApply(); } @@ -487,7 +482,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵclassMap($ctx$.exp); $r3$.ɵɵstylingApply(); } @@ -544,7 +538,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleMap($ctx$.myStyleExp); $r3$.ɵɵstyleProp(0, $ctx$.myWidth); $r3$.ɵɵstyleProp(1, $ctx$.myHeight); @@ -604,7 +597,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleProp(0, ctx.myImage); $r3$.ɵɵstylingApply(); } @@ -646,7 +638,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleProp(0, 12, "px"); $r3$.ɵɵstylingApply(); } @@ -712,7 +703,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵclassMap($ctx$.myClassExp); $r3$.ɵɵstylingApply(); } @@ -769,7 +759,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵclassMap($ctx$.myClassExp); $r3$.ɵɵclassProp(0, $ctx$.yesToApple); $r3$.ɵɵclassProp(1, $ctx$.yesToOrange); @@ -823,7 +812,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelement(0, "div", $e0_attrs$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵattribute("class", "round"); $r3$.ɵɵattribute("style", "height:100px", $r3$.ɵɵsanitizeStyle); } @@ -891,7 +879,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleMap($ctx$.myStyleExp); $r3$.ɵɵclassMap($ctx$.myClassExp); $r3$.ɵɵstylingApply(); @@ -935,7 +922,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleMap($r3$.ɵɵpipeBind1(1, 0, $ctx$.myStyleExp)); $r3$.ɵɵclassMap($r3$.ɵɵpipeBind1(2, 2, $ctx$.myClassExp)); $r3$.ɵɵstylingApply(); @@ -993,7 +979,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleMap($r3$.ɵɵpipeBind2(1, 1, $ctx$.myStyleExp, 1000)); $r3$.ɵɵclassMap($e2_styling$); $r3$.ɵɵstyleProp(0, $r3$.ɵɵpipeBind2(2, 4, $ctx$.barExp, 3000)); @@ -1043,7 +1028,6 @@ describe('compiler compliance: styling', () => { template: function MyComponent_Template(rf, $ctx$) { … if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleProp(0, $ctx$.w1); $r3$.ɵɵstylingApply(); $r3$.ɵɵselect(1); @@ -1236,7 +1220,6 @@ describe('compiler compliance: styling', () => { $r3$.ɵɵelementEnd(); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleMap(ctx.myStyleExp); $r3$.ɵɵclassMap(ctx.myClassExp); $r3$.ɵɵstyleProp(0, ctx.myHeightExp, null, true); @@ -1495,7 +1478,6 @@ describe('compiler compliance: styling', () => { template: function MyAppComp_Template(rf, ctx) { … if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleSanitizer($r3$.ɵɵdefaultStyleSanitizer); $r3$.ɵɵstyleProp(0, ctx.bgExp); $r3$.ɵɵstylingApply(); @@ -1532,7 +1514,6 @@ describe('compiler compliance: styling', () => { template: function MyAppComp_Template(rf, ctx) { … if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵstyleSanitizer($r3$.ɵɵdefaultStyleSanitizer); $r3$.ɵɵstyleMap(ctx.mapExp); $r3$.ɵɵstylingApply(); @@ -1570,7 +1551,6 @@ describe('compiler compliance: styling', () => { template: function MyAppComp_Template(rf, ctx) { … if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵclassMap(ctx.mapExp); $r3$.ɵɵclassProp(0, ctx.nameExp); $r3$.ɵɵstylingApply(); 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 0f54733b7f..89d54b6cc5 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 @@ -75,7 +75,6 @@ describe('compiler compliance: template', () => { const $middle1$ = $i0$.ɵɵnextContext().$implicit; const $outer1$ = $i0$.ɵɵnextContext().$implicit; const $myComp1$ = $i0$.ɵɵnextContext(); - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("title", $myComp1$.format($outer1$, $middle1$, $inner1$, $myComp1$.component)); $r3$.ɵɵselect(1); $i0$.ɵɵtextInterpolate1(" ", $myComp1$.format($outer1$, $middle1$, $inner1$, $myComp1$.component), " "); @@ -113,7 +112,6 @@ describe('compiler compliance: template', () => { $i0$.ɵɵtemplate(0, MyComponent_ul_0_Template, 2, 1, "ul", $c0$); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("ngForOf", ctx.items); } }`; @@ -170,7 +168,6 @@ describe('compiler compliance: template', () => { $r3$.ɵɵtemplate(0, MyComponent_div_0_Template, 1, 0, "div", $t0_attrs$); } if (rf & 2) { - $r3$.ɵɵselect(0); $r3$.ɵɵproperty("ngForOf", ctx._data); } } @@ -224,7 +221,6 @@ describe('compiler compliance: template', () => { $i0$.ɵɵtemplate(0, MyComponent_span_0_Template, 2, 2, "span", _c0); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("ngForOf", ctx.items); } }`; @@ -295,7 +291,6 @@ describe('compiler compliance: template', () => { $i0$.ɵɵtemplate(0, MyComponent_div_0_Template, 2, 1, "div", $c0$); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("ngForOf", ctx.items); } }`; @@ -378,7 +373,6 @@ describe('compiler compliance: template', () => { $i0$.ɵɵtemplate(0, MyComponent_div_0_Template, 2, 1, "div", $c0$); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("ngForOf", ctx.items); } }`; @@ -425,7 +419,6 @@ describe('compiler compliance: template', () => { $i0$.ɵɵtemplate(0, MyComponent_ng_template_0_Template, 1, 0, "ng-template", $c0$); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("boundAttr", ctx.b); } }`; @@ -716,7 +709,6 @@ describe('compiler compliance: template', () => { $i0$.ɵɵtemplate(0, MyComponent_div_0_Template, 1, 0, "div", $c0$); $i0$.ɵɵpipe(1, "pipe"); } if (rf & 2) { - $i0$.ɵɵselect(0); $i0$.ɵɵproperty("ngIf", $i0$.ɵɵpipeBind1(1, 1, ctx.val)); } }`; diff --git a/packages/compiler/src/render3/view/template.ts b/packages/compiler/src/render3/view/template.ts index 2a742933b4..61477223e5 100644 --- a/packages/compiler/src/render3/view/template.ts +++ b/packages/compiler/src/render3/view/template.ts @@ -1072,7 +1072,9 @@ export class TemplateDefinitionBuilder implements t.Visitor, LocalResolver nodeIndex: number, span: ParseSourceSpan|null, reference: o.ExternalReference, paramsOrFn?: o.Expression[]|(() => o.Expression[])) { if (this._lastNodeIndexWithFlush < nodeIndex) { - this.instructionFn(this._updateCodeFns, span, R3.select, [o.literal(nodeIndex)]); + if (nodeIndex > 0) { + this.instructionFn(this._updateCodeFns, span, R3.select, [o.literal(nodeIndex)]); + } this._lastNodeIndexWithFlush = nodeIndex; } this.instructionFn(this._updateCodeFns, span, reference, paramsOrFn || []); diff --git a/packages/core/src/render3/instructions/select.ts b/packages/core/src/render3/instructions/select.ts index 1c77ac0176..e24f7c77bb 100644 --- a/packages/core/src/render3/instructions/select.ts +++ b/packages/core/src/render3/instructions/select.ts @@ -7,9 +7,10 @@ */ import {assertGreaterThan, assertLessThan} from '../../util/assert'; import {executePreOrderHooks} from '../hooks'; -import {HEADER_OFFSET, TVIEW} from '../interfaces/view'; +import {HEADER_OFFSET, LView, TVIEW} from '../interfaces/view'; import {getCheckNoChangesMode, getLView, setSelectedIndex} from '../state'; + /** * Selects an element for later binding instructions. * @@ -37,7 +38,11 @@ export function ɵɵselect(index: number): void { assertLessThan( index, getLView().length - HEADER_OFFSET, 'Should be within range for the view data'); const lView = getLView(); + selectInternal(lView, index); +} + +export function selectInternal(lView: LView, index: number) { // Flush the initial hooks for elements in the view that have been added up to this point. executePreOrderHooks(lView, lView[TVIEW], getCheckNoChangesMode(), index); diff --git a/packages/core/src/render3/instructions/shared.ts b/packages/core/src/render3/instructions/shared.ts index d787f19107..b04fad12bc 100644 --- a/packages/core/src/render3/instructions/shared.ts +++ b/packages/core/src/render3/instructions/shared.ts @@ -38,9 +38,8 @@ import {attrsStylingIndexOf} from '../util/attrs_utils'; import {INTERPOLATION_DELIMITER, renderStringify, stringifyForError} from '../util/misc_utils'; import {getLViewParent, getRootContext} from '../util/view_traversal_utils'; import {getComponentViewByIndex, getNativeByIndex, getNativeByTNode, getTNode, isComponent, isComponentDef, isContentQueryHost, isLContainer, isRootView, readPatchedLView, resetPreOrderHookFlags, unwrapRNode, viewAttachedToChangeDetector} from '../util/view_utils'; - import {LCleanup, LViewBlueprint, MatchesArray, TCleanup, TNodeInitialData, TNodeInitialInputs, TNodeLocalNames, TViewComponents, TViewConstructor, attachLContainerDebug, attachLViewDebug, cloneToLView, cloneToTViewData} from './lview_debug'; - +import {selectInternal} from './select'; /** @@ -394,7 +393,7 @@ export function renderEmbeddedTemplate(viewToRender: LView, tView: TView, con oldView = enterView(viewToRender, viewToRender[T_HOST]); resetPreOrderHookFlags(viewToRender); - executeTemplate(tView.template !, getRenderFlags(viewToRender), context); + executeTemplate(viewToRender, tView.template !, getRenderFlags(viewToRender), context); // This must be set to false immediately after the first creation run because in an // ngFor loop, all the views will be created together before update mode runs and turns @@ -423,7 +422,7 @@ export function renderComponentOrTemplate( if (creationModeIsActive) { // creation mode pass - templateFn && executeTemplate(templateFn, RenderFlags.Create, context); + templateFn && executeTemplate(hostView, templateFn, RenderFlags.Create, context); refreshDescendantViews(hostView); hostView[FLAGS] &= ~LViewFlags.CreationMode; @@ -431,7 +430,7 @@ export function renderComponentOrTemplate( // update mode pass resetPreOrderHookFlags(hostView); - templateFn && executeTemplate(templateFn, RenderFlags.Update, context); + templateFn && executeTemplate(hostView, templateFn, RenderFlags.Update, context); refreshDescendantViews(hostView); } finally { if (normalExecutionPath && !creationModeIsActive && rendererFactory.end) { @@ -441,11 +440,17 @@ export function renderComponentOrTemplate( } } -function executeTemplate(templateFn: ComponentTemplate, rf: RenderFlags, context: T) { +function executeTemplate( + lView: LView, templateFn: ComponentTemplate, rf: RenderFlags, context: T) { ɵɵnamespaceHTML(); const prevSelectedIndex = getSelectedIndex(); try { setActiveHostElement(null); + if (rf & RenderFlags.Update) { + // When we're updating, have an inherent ɵɵselect(0) so we don't have to generate that + // instruction for most update blocks + selectInternal(lView, 0); + } templateFn(rf, context); } finally { setSelectedIndex(prevSelectedIndex); @@ -1719,7 +1724,7 @@ export function checkView(hostView: LView, component: T) { try { resetPreOrderHookFlags(hostView); creationMode && executeViewQueryFn(RenderFlags.Create, hostTView, component); - executeTemplate(templateFn, getRenderFlags(hostView), component); + executeTemplate(hostView, templateFn, getRenderFlags(hostView), component); refreshDescendantViews(hostView); // Only check view queries again in creation mode if there are static view queries if (!creationMode || hostTView.staticViewQueries) { diff --git a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json index 5fd56e86c8..ad90414efd 100644 --- a/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json +++ b/packages/core/test/bundling/cyclic_import/bundle.golden_symbols.json @@ -683,6 +683,9 @@ { "name": "saveResolvedLocalsInData" }, + { + "name": "selectInternal" + }, { "name": "setActiveHostElement" }, diff --git a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json index e11a3baabb..ba58c7eaae 100644 --- a/packages/core/test/bundling/hello_world/bundle.golden_symbols.json +++ b/packages/core/test/bundling/hello_world/bundle.golden_symbols.json @@ -452,6 +452,9 @@ { "name": "resetPreOrderHookFlags" }, + { + "name": "selectInternal" + }, { "name": "setActiveHostElement" }, diff --git a/packages/core/test/bundling/todo/bundle.golden_symbols.json b/packages/core/test/bundling/todo/bundle.golden_symbols.json index b96cca104a..07fe02cca9 100644 --- a/packages/core/test/bundling/todo/bundle.golden_symbols.json +++ b/packages/core/test/bundling/todo/bundle.golden_symbols.json @@ -1385,6 +1385,9 @@ { "name": "searchTokensOnInjector" }, + { + "name": "selectInternal" + }, { "name": "setActiveHostElement" }, diff --git a/packages/core/test/render3/instructions_spec.ts b/packages/core/test/render3/instructions_spec.ts index ee6e856108..42b066b528 100644 --- a/packages/core/test/render3/instructions_spec.ts +++ b/packages/core/test/render3/instructions_spec.ts @@ -50,7 +50,6 @@ describe('instructions', () => { const t = new TemplateFixture(createDiv, () => {}, 1, 0); expect(() => { t.update(() => { ɵɵselect(-1); }); }).toThrow(); expect(() => { t.update(() => { ɵɵselect(1); }); }).toThrow(); - expect(() => { t.update(() => { ɵɵselect(0); }); }).not.toThrow(); }); }); @@ -153,15 +152,9 @@ describe('instructions', () => { it('should chain', () => { //
const t = new TemplateFixture(createDiv, () => {}, 1, 2); - t.update(() => { - ɵɵselect(0); - ɵɵproperty('title', 'one')('accessKey', 'A'); - }); + t.update(() => { ɵɵproperty('title', 'one')('accessKey', 'A'); }); expect(t.html).toEqual('
'); - t.update(() => { - ɵɵselect(0); - ɵɵproperty('title', 'two')('accessKey', 'B'); - }); + t.update(() => { ɵɵproperty('title', 'two')('accessKey', 'B'); }); expect(t.html).toEqual('
'); expect(ngDevMode).toHaveProperties({ firstTemplatePass: 1, @@ -171,17 +164,6 @@ describe('instructions', () => { rendererSetProperty: 4, }); }); - - it('should error in dev mode if ɵɵselect was not called prior', () => { - const t = new TemplateFixture(createDiv, () => {}, 1, 1); - expect(() => { t.update(() => { ɵɵproperty('title', 'test'); }); }).toThrow(); - expect(() => { - t.update(() => { - ɵɵselect(0); - ɵɵproperty('title', 'test'); - }); - }).not.toThrow(); - }); }); describe('styleProp', () => { @@ -190,7 +172,6 @@ describe('instructions', () => { return createDiv(null, null, null, ['background-image'], ɵɵdefaultStyleSanitizer); }, () => {}, 1); t.update(() => { - ɵɵselect(0); ɵɵstyleProp(0, 'url("http://server")'); ɵɵstylingApply(); }); @@ -198,7 +179,6 @@ describe('instructions', () => { expect(t.html).toEqual('
'); t.update(() => { - ɵɵselect(0); ɵɵstyleProp(0, bypassSanitizationTrustStyle('url("http://server2")')); ɵɵstylingApply(); }); @@ -214,7 +194,6 @@ describe('instructions', () => { 1, sanitizerInterceptor); t.update(() => { - ɵɵselect(0); ɵɵstyleProp(0, bypassSanitizationTrustStyle('apple')); ɵɵstylingApply(); }); @@ -223,7 +202,6 @@ describe('instructions', () => { sanitizerInterceptor.lastValue = null; t.update(() => { - ɵɵselect(0); ɵɵstyleProp(0, bypassSanitizationTrustStyle('apple')); ɵɵstylingApply(); }); @@ -241,7 +219,6 @@ describe('instructions', () => { it('should add style', () => { const fixture = new TemplateFixture(createDivWithStyle, () => {}, 1); fixture.update(() => { - ɵɵselect(0); ɵɵstyleMap({'background-color': 'red'}); ɵɵstylingApply(); }); @@ -257,7 +234,6 @@ describe('instructions', () => { sanitizerInterceptor); fixture.update(() => { - ɵɵselect(0); ɵɵstyleMap({ 'background-image': 'background-image', 'background': 'background', @@ -287,7 +263,6 @@ describe('instructions', () => { it('should add class', () => { const fixture = new TemplateFixture(createDivWithStyling, () => {}, 1); fixture.update(() => { - ɵɵselect(0); ɵɵclassMap('multiple classes'); ɵɵstylingApply(); }); diff --git a/packages/core/test/render3/integration_spec.ts b/packages/core/test/render3/integration_spec.ts index 2bf250c4e7..a5fbbb508a 100644 --- a/packages/core/test/render3/integration_spec.ts +++ b/packages/core/test/render3/integration_spec.ts @@ -637,7 +637,6 @@ describe('element discovery', () => { ɵɵelementEnd(); } if (rf & RenderFlags.Update) { - ɵɵselect(0); ɵɵstylingApply(); } } diff --git a/packages/core/test/render3/styling/class_and_style_bindings_spec.ts b/packages/core/test/render3/styling/class_and_style_bindings_spec.ts index 4f6120edd2..c39b62f5fb 100644 --- a/packages/core/test/render3/styling/class_and_style_bindings_spec.ts +++ b/packages/core/test/render3/styling/class_and_style_bindings_spec.ts @@ -396,7 +396,6 @@ describe('style and class based bindings', () => { ɵɵelementEnd(); } if (rf & RenderFlags.Update) { - ɵɵselect(0); ɵɵstyleMap(ctx.myStyles); ɵɵstyleProp(0, ctx.myWidth); ɵɵstylingApply(); @@ -435,7 +434,6 @@ describe('style and class based bindings', () => { ɵɵelementEnd(); } if (rf & RenderFlags.Update) { - ɵɵselect(0); ɵɵstyleProp(0, ctx.diameter, 'px'); ɵɵstyleProp(1, ctx.diameter, 'px'); ɵɵstylingApply(); @@ -475,7 +473,6 @@ describe('style and class based bindings', () => { ɵɵelementEnd(); } if (rf & RenderFlags.Update) { - ɵɵselect(0); ɵɵstyleProp(0, ctx.borderWidth); ɵɵstyleProp(1, ctx.borderColor); ɵɵstylingApply(); @@ -3118,7 +3115,6 @@ describe('style and class based bindings', () => { ɵɵelementEnd(); } if (rf & RenderFlags.Update) { - ɵɵselect(0); ɵɵstyleMap(styleMapFactory); ɵɵclassMap(classMapFactory); ɵɵstyleProp(0, widthFactory); @@ -3193,7 +3189,6 @@ describe('style and class based bindings', () => { ɵɵelementEnd(); } if (rf & RenderFlags.Update) { - ɵɵselect(0); ɵɵstyleMap(styleMapFactory); ɵɵclassMap(classMapFactory); ɵɵstyleProp(0, widthFactory); @@ -3291,7 +3286,6 @@ describe('style and class based bindings', () => { ɵɵelementEnd(); } if (rf & RenderFlags.Update) { - ɵɵselect(0); ɵɵstyleProp(0, ctx.widthFactory); ɵɵclassProp(0, ctx.fooFactory); ɵɵstylingApply(); diff --git a/packages/core/test/render3/styling/players_spec.ts b/packages/core/test/render3/styling/players_spec.ts index f0b494ddf5..c8010f1bbe 100644 --- a/packages/core/test/render3/styling/players_spec.ts +++ b/packages/core/test/render3/styling/players_spec.ts @@ -262,7 +262,6 @@ class CompWithStyling { ɵɵelementEnd(); } if (rf & RenderFlags.Update) { - ɵɵselect(0); ɵɵstylingApply(); } }