Skip to content

Commit fe14f18

Browse files
karaIgorMinar
authored andcommitted
fix(compiler): update compiler to flatten nested template fns (angular#24943)
PR Close angular#24943
1 parent 8741909 commit fe14f18

19 files changed

+848
-542
lines changed

packages/compiler-cli/test/compliance/r3_compiler_compliance_spec.ts

Lines changed: 153 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,17 @@ describe('compiler compliance', () => {
541541
const MyComponentDefinition = `
542542
const $c1$ = ["foo", ""];
543543
const $c2$ = ["if", ""];
544+
function MyComponent_li_Template_2(rf, ctx0, ctx) {
545+
if (rf & 1) {
546+
$r3$.ɵE(0, "li");
547+
$r3$.ɵT(1);
548+
$r3$.ɵe();
549+
}
550+
if (rf & 2) {
551+
const $foo$ = $r3$.ɵr(1, 1);
552+
$r3$.ɵt(1, $r3$.ɵi2("", ctx.salutation, " ", $foo$, ""));
553+
}
554+
}
544555
545556
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
546557
type: MyComponent,
@@ -552,17 +563,6 @@ describe('compiler compliance', () => {
552563
$r3$.ɵC(2, MyComponent_li_Template_2, null, $c2$);
553564
$r3$.ɵe();
554565
}
555-
const $foo$ = $r3$.ɵld(1);
556-
function MyComponent_li_Template_2(rf, ctx0) {
557-
if (rf & 1) {
558-
$r3$.ɵE(0, "li");
559-
$r3$.ɵT(1);
560-
$r3$.ɵe();
561-
}
562-
if (rf & 2) {
563-
$r3$.ɵt(1, $r3$.ɵi2("", ctx.salutation, " ", $foo$, ""));
564-
}
565-
}
566566
},
567567
directives:[IfDirective]
568568
});`;
@@ -1173,8 +1173,8 @@ describe('compiler compliance', () => {
11731173
$r3$.ɵEe(0, "input", null, $c1$);
11741174
$r3$.ɵT(2);
11751175
}
1176-
const $user$ = $r3$.ɵld(1);
11771176
if (rf & 2) {
1177+
const $user$ = $r3$.ɵld(1);
11781178
$r3$.ɵt(2, $r3$.ɵi1("Hello ", $user$.value, "!"));
11791179
}
11801180
}
@@ -1187,6 +1187,97 @@ describe('compiler compliance', () => {
11871187
expectEmit(source, MyComponentDefinition, 'Incorrect MyComponent.ngComponentDef');
11881188
});
11891189

1190+
it('local references in nested views', () => {
1191+
const files = {
1192+
app: {
1193+
'spec.ts': `
1194+
import {Component, Directive, NgModule, TemplateRef} from '@angular/core';
1195+
1196+
@Directive({selector: '[if]'})
1197+
export class IfDirective {
1198+
constructor(template: TemplateRef<any>) { }
1199+
}
1200+
1201+
@Component({
1202+
selector: 'my-component',
1203+
template: \`
1204+
<div #foo></div>
1205+
{{foo}}
1206+
<div *if>
1207+
{{foo}}-{{bar}}
1208+
<span *if>{{foo}}-{{bar}}-{{baz}}</span>
1209+
<span #bar></span>
1210+
</div>
1211+
<div #baz></div>
1212+
\`
1213+
})
1214+
export class MyComponent {}
1215+
1216+
@NgModule({declarations: [IfDirective, MyComponent]})
1217+
export class MyModule {}
1218+
`
1219+
}
1220+
};
1221+
1222+
const MyComponentDefinition = `
1223+
const $c1$ = ["foo", ""];
1224+
const $c2$ = ["if", ""];
1225+
const $c3$ = ["baz", ""];
1226+
const $c4$ = ["bar", ""];
1227+
function MyComponent_div_span_Template_2(rf, ctx1, ctx0, ctx) {
1228+
if (rf & 1) {
1229+
$r3$.ɵE(0, "span");
1230+
$r3$.ɵT(1);
1231+
$r3$.ɵe();
1232+
}
1233+
if (rf & 2) {
1234+
const $foo$ = $r3$.ɵr(2, 1);
1235+
const $bar$ = $r3$.ɵr(1, 4);
1236+
const $baz$ = $r3$.ɵr(2, 5);
1237+
$r3$.ɵt(1, $r3$.ɵi3("", $foo$, "-", $bar$, "-", $baz$, ""));
1238+
}
1239+
}
1240+
function MyComponent_div_Template_3(rf, ctx0, ctx) {
1241+
if (rf & 1) {
1242+
$r3$.ɵE(0, "div");
1243+
$r3$.ɵT(1);
1244+
$r3$.ɵC(2, MyComponent_div_span_Template_2, null, $c2$);
1245+
$r3$.ɵEe(3, "span", null, $c4$);
1246+
$r3$.ɵe();
1247+
}
1248+
if (rf & 2) {
1249+
const $foo$ = $r3$.ɵr(1, 1);
1250+
const $bar$ = $r3$.ɵld(4);
1251+
$r3$.ɵt(1, $r3$.ɵi2(" ", $foo$, "-", $bar$, " "));
1252+
}
1253+
}
1254+
1255+
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
1256+
type: MyComponent,
1257+
selectors: [["my-component"]],
1258+
factory: function MyComponent_Factory() { return new MyComponent(); },
1259+
template: function MyComponent_Template(rf, ctx) {
1260+
if (rf & 1) {
1261+
$r3$.ɵEe(0, "div", null, $c1$);
1262+
$r3$.ɵT(2);
1263+
$r3$.ɵC(3, MyComponent_div_Template_3, null, $c2$);
1264+
$r3$.ɵEe(4, "div", null, $c3$);
1265+
}
1266+
if (rf & 2) {
1267+
const $foo$ = $r3$.ɵld(1);
1268+
$r3$.ɵt(2, $r3$.ɵi1(" ", $foo$, " "));
1269+
}
1270+
},
1271+
directives:[IfDirective]
1272+
});`;
1273+
1274+
const result = compile(files, angularFiles);
1275+
const source = result.source;
1276+
1277+
expectEmit(source, MyComponentDefinition, 'Incorrect MyComponent.ngComponentDef');
1278+
1279+
});
1280+
11901281
describe('lifecycle hooks', () => {
11911282
const files = {
11921283
app: {
@@ -1361,6 +1452,14 @@ describe('compiler compliance', () => {
13611452

13621453
const MyComponentDefinition = `
13631454
const $_c0$ = ["for","","forOf",""];
1455+
function MyComponent__svg_g_Template_1(rf, ctx0, ctx) {
1456+
if (rf & 1) {
1457+
$r3$.ɵNS();
1458+
$r3$.ɵE(0,"g");
1459+
$r3$.ɵEe(1,"circle");
1460+
$r3$.ɵe();
1461+
}
1462+
}
13641463
13651464
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
13661465
type: MyComponent,
@@ -1374,14 +1473,6 @@ describe('compiler compliance', () => {
13741473
$r3$.ɵe();
13751474
}
13761475
if (rf & 2) { $r3$.ɵp(1,"forOf",$r3$.ɵb(ctx.items)); }
1377-
function MyComponent__svg_g_Template_1(rf, ctx0) {
1378-
if (rf & 1) {
1379-
$r3$.ɵNS();
1380-
$r3$.ɵE(0,"g");
1381-
$r3$.ɵEe(1,"circle");
1382-
$r3$.ɵe();
1383-
}
1384-
}
13851476
},
13861477
directives: [ForOfDirective]
13871478
});
@@ -1434,6 +1525,17 @@ describe('compiler compliance', () => {
14341525

14351526
const MyComponentDefinition = `
14361527
const $_c0$ = ["for","","forOf",""];
1528+
function MyComponent_li_Template_1(rf, ctx0, ctx) {
1529+
if (rf & 1) {
1530+
$r3$.ɵE(0, "li");
1531+
$r3$.ɵT(1);
1532+
$r3$.ɵe();
1533+
}
1534+
if (rf & 2) {
1535+
const $item$ = ctx0.$implicit;
1536+
$r3$.ɵt(1, $r3$.ɵi1("", $item$.name, ""));
1537+
}
1538+
}
14371539
14381540
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
14391541
type: MyComponent,
@@ -1448,18 +1550,6 @@ describe('compiler compliance', () => {
14481550
if (rf & 2) {
14491551
$r3$.ɵp(1, "forOf", $r3$.ɵb(ctx.items));
14501552
}
1451-
1452-
function MyComponent_li_Template_1(rf, ctx0) {
1453-
if (rf & 1) {
1454-
$r3$.ɵE(0, "li");
1455-
$r3$.ɵT(1);
1456-
$r3$.ɵe();
1457-
}
1458-
if (rf & 2) {
1459-
const $item$ = ctx0.$implicit;
1460-
$r3$.ɵt(1, $r3$.ɵi1("", $item$.name, ""));
1461-
}
1462-
}
14631553
},
14641554
directives: [ForOfDirective]
14651555
});
@@ -1512,6 +1602,37 @@ describe('compiler compliance', () => {
15121602

15131603
const MyComponentDefinition = `
15141604
const $c1$ = ["for", "", "forOf", ""];
1605+
function MyComponent_li_li_Template_4(rf, ctx1, ctx0, ctx) {
1606+
if (rf & 1) {
1607+
$r3$.ɵE(0, "li");
1608+
$r3$.ɵT(1);
1609+
$r3$.ɵe();
1610+
}
1611+
if (rf & 2) {
1612+
const $item$ = ctx0.$implicit;
1613+
const $info$ = ctx1.$implicit;
1614+
$r3$.ɵt(1, $r3$.ɵi2(" ", $item$.name, ": ", $info$.description, " "));
1615+
}
1616+
}
1617+
1618+
function MyComponent_li_Template_1(rf, ctx0, ctx) {
1619+
if (rf & 1) {
1620+
$r3$.ɵE(0, "li");
1621+
$r3$.ɵE(1, "div");
1622+
$r3$.ɵT(2);
1623+
$r3$.ɵe();
1624+
$r3$.ɵE(3, "ul");
1625+
$r3$.ɵC(4, MyComponent_li_li_Template_4, null, $c1$);
1626+
$r3$.ɵe();
1627+
$r3$.ɵe();
1628+
}
1629+
if (rf & 2) {
1630+
const $item$ = ctx0.$implicit;
1631+
$r3$.ɵt(2, $r3$.ɵi1("", IDENT.name, ""));
1632+
$r3$.ɵp(4, "forOf", $r3$.ɵb(IDENT.infos));
1633+
}
1634+
}
1635+
15151636
15161637
MyComponent.ngComponentDef = $r3$.ɵdefineComponent({
15171638
type: MyComponent,
@@ -1526,37 +1647,6 @@ describe('compiler compliance', () => {
15261647
if (rf & 2) {
15271648
$r3$.ɵp(1, "forOf", $r3$.ɵb(ctx.items));
15281649
}
1529-
1530-
function MyComponent_li_Template_1(rf, ctx0) {
1531-
if (rf & 1) {
1532-
$r3$.ɵE(0, "li");
1533-
$r3$.ɵE(1, "div");
1534-
$r3$.ɵT(2);
1535-
$r3$.ɵe();
1536-
$r3$.ɵE(3, "ul");
1537-
$r3$.ɵC(4, MyComponent_li_li_Template_4, null, $c1$);
1538-
$r3$.ɵe();
1539-
$r3$.ɵe();
1540-
}
1541-
if (rf & 2) {
1542-
const $item$ = ctx0.$implicit;
1543-
$r3$.ɵt(2, $r3$.ɵi1("", IDENT.name, ""));
1544-
$r3$.ɵp(4, "forOf", $r3$.ɵb(IDENT.infos));
1545-
}
1546-
1547-
function MyComponent_li_li_Template_4(rf, ctx1) {
1548-
if (rf & 1) {
1549-
$r3$.ɵE(0, "li");
1550-
$r3$.ɵT(1);
1551-
$r3$.ɵe();
1552-
}
1553-
if (rf & 2) {
1554-
const $item$ = ctx0.$implicit;
1555-
const $info$ = ctx1.$implicit;
1556-
$r3$.ɵt(1, $r3$.ɵi2(" ", $item$.name, ": ", $info$.description, " "));
1557-
}
1558-
}
1559-
}
15601650
},
15611651
directives: [ForOfDirective]
15621652
});`;

packages/compiler-cli/test/compliance/r3_view_compiler_template_spec.ts

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,49 @@ describe('compiler compliance: template', () => {
5252
// The template should look like this (where IDENT is a wild card for an identifier):
5353
const template = `
5454
const $c0$ = ["ngFor","","ngForOf",""];
55+
function MyComponent_ul_li_div_Template_1(rf, $ctx2$, $ctx1$, $ctx0$, $ctx$) {
56+
if (rf & 1) {
57+
$i0$.ɵE(0, "div");
58+
$i0$.ɵL("click", function MyComponent_ul_li_div_Template_1_div_click_listener($event){
59+
const $outer$ = $ctx0$.$implicit;
60+
const $middle$ = $ctx1$.$implicit;
61+
const $inner$ = $ctx2$.$implicit;
62+
return ctx.onClick($outer$, $middle$, $inner$);
63+
});
64+
$i0$.ɵT(1);
65+
$i0$.ɵe();
66+
}
67+
if (rf & 2) {
68+
const $outer$ = $ctx0$.$implicit;
69+
const $middle$ = $ctx1$.$implicit;
70+
const $inner$ = $ctx2$.$implicit;
71+
$i0$.ɵp(0, "title", $i0$.ɵb(ctx.format($outer$, $middle$, $inner$, $ctx$.component)));
72+
$i0$.ɵt(1, $i0$.ɵi1(" ", ctx.format($outer$, $middle$, $inner$, $ctx$.component), " "));
73+
}
74+
}
75+
76+
function MyComponent_ul_li_Template_1(rf, $ctx1$, $ctx0$, $ctx$) {
77+
if (rf & 1) {
78+
$i0$.ɵE(0, "li");
79+
$i0$.ɵC(1, MyComponent_ul_li_div_Template_1, null, _c0);
80+
$i0$.ɵe();
81+
}
82+
if (rf & 2) {
83+
$i0$.ɵp(1, "ngForOf", $i0$.ɵb($ctx$.items));
84+
}
85+
}
86+
87+
function MyComponent_ul_Template_0(rf, $ctx0$, $ctx$) {
88+
if (rf & 1) {
89+
$i0$.ɵE(0, "ul");
90+
$i0$.ɵC(1, MyComponent_ul_li_Template_1, null, _c0);
91+
$i0$.ɵe();
92+
}
93+
if (rf & 2) {
94+
const $outer$ = $ctx0$.$implicit;
95+
$i0$.ɵp(1, "ngForOf", $i0$.ɵb($outer$.items));
96+
}
97+
}
5598
// ...
5699
template:function MyComponent_Template(rf, $ctx$){
57100
if (rf & 1) {
@@ -60,48 +103,6 @@ describe('compiler compliance: template', () => {
60103
if (rf & 2) {
61104
$i0$.ɵp(0, "ngForOf", $i0$.ɵb($ctx$.items));
62105
}
63-
64-
function MyComponent_ul_Template_0(rf, $ctx0$) {
65-
if (rf & 1) {
66-
$i0$.ɵE(0, "ul");
67-
$i0$.ɵC(1, MyComponent_ul_li_Template_1, null, _c0);
68-
$i0$.ɵe();
69-
}
70-
if (rf & 2) {
71-
const $outer$ = $ctx0$.$implicit;
72-
$i0$.ɵp(1, "ngForOf", $i0$.ɵb($outer$.items));
73-
}
74-
function MyComponent_ul_li_Template_1(rf, $ctx1$) {
75-
if (rf & 1) {
76-
$i0$.ɵE(0, "li");
77-
$i0$.ɵC(1, MyComponent_ul_li_div_Template_1, null, _c0);
78-
$i0$.ɵe();
79-
}
80-
if (rf & 2) {
81-
$i0$.ɵp(1, "ngForOf", $i0$.ɵb($ctx$.items));
82-
}
83-
function MyComponent_ul_li_div_Template_1(rf, $ctx2$) {
84-
if (rf & 1) {
85-
$i0$.ɵE(0, "div");
86-
$i0$.ɵL("click", function MyComponent_ul_li_div_Template_1_div_click_listener($event){
87-
const $outer$ = $ctx0$.$implicit;
88-
const $middle$ = $ctx1$.$implicit;
89-
const $inner$ = $ctx2$.$implicit;
90-
return ctx.onClick($outer$, $middle$, $inner$);
91-
});
92-
$i0$.ɵT(1);
93-
$i0$.ɵe();
94-
}
95-
if (rf & 2) {
96-
const $outer$ = $ctx0$.$implicit;
97-
const $middle$ = $ctx1$.$implicit;
98-
const $inner$ = $ctx2$.$implicit;
99-
$i0$.ɵp(0, "title", $i0$.ɵb(ctx.format($outer$, $middle$, $inner$, $ctx$.component)));
100-
$i0$.ɵt(1, $i0$.ɵi1(" ", ctx.format($outer$, $middle$, $inner$, $ctx$.component), " "));
101-
}
102-
}
103-
}
104-
}
105106
}`;
106107

107108
const result = compile(files, angularFiles);

packages/compiler/src/render3/r3_identifiers.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ export class Identifiers {
8787
static projection: o.ExternalReference = {name: 'ɵP', moduleName: CORE};
8888
static projectionDef: o.ExternalReference = {name: 'ɵpD', moduleName: CORE};
8989

90+
static reference: o.ExternalReference = {name: 'ɵr', moduleName: CORE};
91+
9092
static inject: o.ExternalReference = {name: 'inject', moduleName: CORE};
9193

9294
static injectAttribute: o.ExternalReference = {name: 'ɵinjectAttribute', moduleName: CORE};

0 commit comments

Comments
 (0)