fix(ivy): create LViewData from blueprint (#25587)

PR Close #25587
This commit is contained in:
Kara Erickson
2018-08-21 00:03:21 -07:00
committed by Matias Niemelä
parent f33dbf42fd
commit d5b70e0c66
24 changed files with 153 additions and 118 deletions

View File

@ -56,6 +56,9 @@
{
"name": "NG_PROJECT_AS_ATTR_NAME"
},
{
"name": "NO_CHANGE"
},
{
"name": "PARENT"
},
@ -72,7 +75,7 @@
"name": "RENDER_PARENT"
},
{
"name": "ROOT_DIRECTIVE_INDICES"
"name": "SANITIZER"
},
{
"name": "TVIEW"
@ -83,9 +86,6 @@
{
"name": "_CLEAN_PROMISE"
},
{
"name": "_ROOT_DIRECTIVE_INDICES"
},
{
"name": "_getComponentHostLElementNode"
},
@ -143,6 +143,9 @@
{
"name": "createTextNode"
},
{
"name": "createViewBlueprint"
},
{
"name": "createViewQuery"
},
@ -239,6 +242,9 @@
{
"name": "nextNgElementId"
},
{
"name": "queueHostBindingForCheck"
},
{
"name": "readElementValue"
},

View File

@ -131,9 +131,6 @@
{
"name": "RENDER_PARENT"
},
{
"name": "ROOT_DIRECTIVE_INDICES"
},
{
"name": "RecordViewTuple"
},
@ -203,9 +200,6 @@
{
"name": "_DuplicateMap"
},
{
"name": "_ROOT_DIRECTIVE_INDICES"
},
{
"name": "_THROW_IF_NOT_FOUND"
},
@ -413,6 +407,9 @@
{
"name": "createTextNode"
},
{
"name": "createViewBlueprint"
},
{
"name": "createViewQuery"
},

View File

@ -105,7 +105,7 @@ describe('change detection', () => {
selectors: [['my-comp']],
factory: () => comp = new MyComponent(),
consts: 2,
vars: 1,
vars: 2,
/**
* {{ doCheckCount }} - {{ name }}
* <button (click)="onClick()"></button>

View File

@ -109,7 +109,7 @@ describe('@angular/common integration', () => {
template: (rf: RenderFlags, ctx: MyApp) => {
if (rf & RenderFlags.Create) {
elementStart(0, 'ul');
{ template(1, liTemplate, 2, 1, undefined, ['ngForOf', '']); }
{ template(1, liTemplate, 2, 3, undefined, ['ngForOf', '']); }
elementEnd();
}
if (rf & RenderFlags.Update) {
@ -246,7 +246,7 @@ describe('@angular/common integration', () => {
function liTemplate(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementStart(0, 'li');
{ template(1, spanTemplate, 2, 1, null, ['ngForOf', '']); }
{ template(1, spanTemplate, 2, 3, null, ['ngForOf', '']); }
elementEnd();
}
if (rf & RenderFlags.Update) {
@ -335,7 +335,7 @@ describe('@angular/common integration', () => {
function divTemplate(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementStart(0, 'div');
{ template(1, pTemplate, 3, 1, null, ['ngForOf', '']); }
{ template(1, pTemplate, 3, 2, null, ['ngForOf', '']); }
elementEnd();
}
if (rf & RenderFlags.Update) {
@ -441,7 +441,7 @@ describe('@angular/common integration', () => {
function innerDivTemplate(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementStart(0, 'div');
{ template(1, spanTemplate, 2, 1, null, ['ngForOf', '']); }
{ template(1, spanTemplate, 2, 2, null, ['ngForOf', '']); }
elementEnd();
}
if (rf & RenderFlags.Update) {
@ -681,7 +681,7 @@ describe('@angular/common integration', () => {
function itemTemplate7(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
elementStart(0, 'span');
{ template(1, itemTemplate8, 2, 1, null, ['ngForOf', '']); }
{ template(1, itemTemplate8, 2, 10, null, ['ngForOf', '']); }
elementEnd();
}
if (rf & RenderFlags.Update) {

View File

@ -103,6 +103,7 @@ describe('components & directives', () => {
type: HostBindingDir,
selectors: [['', 'hostBindingDir', '']],
factory: function HostBindingDir_Factory() { return new HostBindingDir(); },
hostVars: 1,
hostBindings: function HostBindingDir_HostBindings(dirIndex: $number$, elIndex: $number$) {
$r3$.ɵelementProperty(
elIndex, 'id', $r3$.ɵbind($r3$.ɵloadDirective<HostBindingDir>(dirIndex).dirId));
@ -256,6 +257,7 @@ describe('components & directives', () => {
type: HostBindingDir,
selectors: [['', 'hostBindingDir', '']],
factory: function HostBindingDir_Factory() { return new HostBindingDir(); },
hostVars: 1,
hostBindings: function HostBindingDir_HostBindings(dirIndex: $number$, elIndex: $number$) {
$r3$.ɵelementAttribute(
elIndex, 'aria-label',
@ -446,7 +448,7 @@ describe('components & directives', () => {
selectors: [['my-array-comp']],
factory: function MyArrayComp_Factory() { return new MyArrayComp(); },
consts: 1,
vars: 1,
vars: 2,
template: function MyArrayComp_Template(rf: $RenderFlags$, ctx: $MyArrayComp$) {
if (rf & 1) {
$r3$.ɵtext(0);
@ -479,7 +481,7 @@ describe('components & directives', () => {
selectors: [['my-app']],
factory: function MyApp_Factory() { return new MyApp(); },
consts: 1,
vars: 1,
vars: 0,
template: function MyApp_Template(rf: $RenderFlags$, ctx: $MyApp$) {
if (rf & 1) {
$r3$.ɵelement(0, 'my-array-comp');

View File

@ -91,7 +91,7 @@ describe('elements', () => {
selectors: [['local-ref-comp']],
factory: function LocalRefComp_Factory() { return new LocalRefComp(); },
consts: 4,
vars: 1,
vars: 2,
template: function LocalRefComp_Template(rf: $RenderFlags$, ctx: $LocalRefComp$) {
if (rf & 1) {
$r3$.ɵelement(0, 'div', $e0_attrs$, $e0_locals$);
@ -135,7 +135,7 @@ describe('elements', () => {
type: ListenerComp,
selectors: [['listener-comp']],
factory: function ListenerComp_Factory() { return new ListenerComp(); },
consts: 1,
consts: 2,
vars: 0,
template: function ListenerComp_Template(rf: $RenderFlags$, ctx: $ListenerComp$) {
if (rf & 1) {

View File

@ -276,7 +276,7 @@ describe('encapsulation', () => {
static ngComponentDef = defineComponent({
type: LeafComponentwith,
selectors: [['leaf']],
consts: 1,
consts: 2,
vars: 0,
template: function(rf: RenderFlags, ctx: LeafComponentwith) {
if (rf & RenderFlags.Create) {

View File

@ -828,7 +828,7 @@ describe('di', () => {
const tmp2 = reference(2) as any;
textBinding(3, interpolation2('', tmp2.value, '-', tmp1.value, ''));
}
}, 4, 1, [Directive, DirectiveSameInstance]);
}, 4, 2, [Directive, DirectiveSameInstance]);
const fixture = new ComponentFixture(App);
expect(fixture.html).toEqual('<div dir="" dirsame="">ElementRef-true</div>');
@ -872,7 +872,7 @@ describe('di', () => {
const App = createComponent('app', function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
template(0, function() {
}, 0, 1, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
}, 0, 0, undefined, ['dir', '', 'dirSame', ''], ['dir', 'dir', 'dirSame', 'dirSame']);
text(3);
}
if (rf & RenderFlags.Update) {
@ -880,7 +880,7 @@ describe('di', () => {
const tmp2 = reference(2) as any;
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
}
}, 4, 1, [Directive, DirectiveSameInstance]);
}, 4, 2, [Directive, DirectiveSameInstance]);
const fixture = new ComponentFixture(App);
expect(fixture.html).toEqual('TemplateRef-true');
@ -933,7 +933,7 @@ describe('di', () => {
const tmp2 = reference(2) as any;
textBinding(3, interpolation2('', tmp1.value, '-', tmp2.value, ''));
}
}, 4, 1, [Directive, DirectiveSameInstance]);
}, 4, 2, [Directive, DirectiveSameInstance]);
const fixture = new ComponentFixture(App);
expect(fixture.html).toEqual('<div dir="" dirsame="">ViewContainerRef-true</div>');
@ -1217,7 +1217,7 @@ describe('di', () => {
exist = injectAttribute('exist');
nonExist = injectAttribute('nonExist');
}
});
}, 1);
new ComponentFixture(MyApp);
expect(exist).toEqual('existValue');
@ -1376,7 +1376,7 @@ describe('di', () => {
if (rf & RenderFlags.Update) {
containerRefreshStart(1);
{
let rf1 = embeddedViewStart(0, 4, 1);
let rf1 = embeddedViewStart(0, 4, 2);
if (rf1 & RenderFlags.Create) {
elementStart(
0, 'span', ['childDir', '', 'child2Dir', ''],
@ -1408,7 +1408,7 @@ describe('di', () => {
describe('getOrCreateNodeInjector', () => {
it('should handle initial undefined state', () => {
const contentView = createLViewData(
null !, createTView(-1, null, 0, 0, null, null, null), null, LViewFlags.CheckAlways);
null !, createTView(-1, null, 1, 0, null, null, null), null, LViewFlags.CheckAlways);
const oldView = enterView(contentView, null !);
try {
const parent = createLNode(0, TNodeType.Element, null, null, null, null);

View File

@ -365,7 +365,7 @@ describe('exports', () => {
if (rf & RenderFlags.Create) {
elementStart(0, 'input', ['value', 'one'], ['outerInput', '']);
elementEnd();
template(2, outerTemplate, 5, 0, '', [AttributeMarker.SelectOnly, 'ngIf']);
template(2, outerTemplate, 5, 2, '', [AttributeMarker.SelectOnly, 'ngIf']);
}
if (rf & RenderFlags.Update) {
elementProperty(2, 'ngIf', bind(app.outer));
@ -379,7 +379,7 @@ describe('exports', () => {
text(1);
elementStart(2, 'input', ['value', 'two'], ['innerInput', '']);
elementEnd();
template(4, innerTemplate, 2, 1, '', [AttributeMarker.SelectOnly, 'ngIf']);
template(4, innerTemplate, 2, 2, '', [AttributeMarker.SelectOnly, 'ngIf']);
}
elementEnd();
}

View File

@ -196,7 +196,7 @@ describe('Runtime i18n', () => {
factory: () => new MyApp(),
selectors: [['my-app']],
consts: 1,
vars: 1,
vars: 2,
// Initial template:
// <div i18n i18n-title title="{{exp1}}{{exp2}}"></div>
@ -1199,7 +1199,7 @@ describe('Runtime i18n', () => {
selectors: [['parent']],
directives: [Child],
factory: () => new Parent(),
consts: 4,
consts: 7,
vars: 2,
template: (rf: RenderFlags, cmp: Parent) => {
if (rf & RenderFlags.Create) {
@ -1512,7 +1512,7 @@ describe('Runtime i18n', () => {
factory: () => new MyApp(),
selectors: [['my-app']],
consts: 1,
vars: 1,
vars: 4,
// Initial template:
// <div i18n i18n-title title="{{exp1}}{{exp2}}"></div>
@ -1550,7 +1550,7 @@ describe('Runtime i18n', () => {
factory: () => new MyApp(),
selectors: [['my-app']],
consts: 1,
vars: 1,
vars: 3,
// Initial template:
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}"></div>
@ -1587,7 +1587,7 @@ describe('Runtime i18n', () => {
factory: () => new MyApp(),
selectors: [['my-app']],
consts: 1,
vars: 1,
vars: 4,
// Initial template:
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}"></div>
@ -1626,7 +1626,7 @@ describe('Runtime i18n', () => {
factory: () => new MyApp(),
selectors: [['my-app']],
consts: 1,
vars: 1,
vars: 5,
// Initial template:
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}"></div>
@ -1670,7 +1670,7 @@ describe('Runtime i18n', () => {
factory: () => new MyApp(),
selectors: [['my-app']],
consts: 1,
vars: 1,
vars: 6,
// Initial template:
// <div i18n i18n-title title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}"></div>
@ -1716,7 +1716,7 @@ describe('Runtime i18n', () => {
factory: () => new MyApp(),
selectors: [['my-app']],
consts: 1,
vars: 1,
vars: 7,
// Initial template:
// <div i18n i18n-title
// title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}{{exp7}}"></div>
@ -1771,7 +1771,7 @@ describe('Runtime i18n', () => {
factory: () => new MyApp(),
selectors: [['my-app']],
consts: 1,
vars: 1,
vars: 8,
// Initial template:
// <div i18n i18n-title
// title="{{exp1}}{{exp2}}{{exp3}}{{exp4}}{{exp5}}{{exp6}}{{exp7}}{{exp8}}"></div>

View File

@ -40,7 +40,7 @@ describe('instructions', () => {
describe('bind', () => {
it('should update bindings when value changes', () => {
const t = new TemplateFixture(createAnchor, () => {}, 1);
const t = new TemplateFixture(createAnchor, () => {}, 1, 1);
t.update(() => elementProperty(0, 'title', bind('Hello')));
expect(t.html).toEqual('<a title="Hello"></a>');

View File

@ -340,6 +340,7 @@ describe('render3 integration test', () => {
}
},
factory: () => cmptInstance = new TodoComponentHostBinding,
hostVars: 1,
hostBindings: function(directiveIndex: number, elementIndex: number): void {
// host bindings
elementProperty(
@ -930,7 +931,7 @@ describe('render3 integration test', () => {
containerRefreshStart(1);
{
for (let subTree of ctx.tree.subTrees || []) {
const rf0 = embeddedViewStart(0, 1, 0);
const rf0 = embeddedViewStart(0, 3, 0);
{ showTree(rf0, {tree: subTree}); }
embeddedViewEnd();
}
@ -967,14 +968,14 @@ describe('render3 integration test', () => {
if (rf & RenderFlags.Update) {
containerRefreshStart(0);
{
const rf0 = embeddedViewStart(0, 1, 0);
const rf0 = embeddedViewStart(0, 3, 0);
{ showTree(rf0, {tree: ctx.beforeTree}); }
embeddedViewEnd();
}
containerRefreshEnd();
containerRefreshStart(2);
{
const rf0 = embeddedViewStart(0, 1, 0);
const rf0 = embeddedViewStart(0, 3, 0);
{ showTree(rf0, {tree: ctx.afterTree}); }
embeddedViewEnd();
}
@ -997,7 +998,7 @@ describe('render3 integration test', () => {
elementProperty(0, 'afterTree', bind(ctx.afterTree));
containerRefreshStart(1);
{
const rf0 = embeddedViewStart(0, 1, 0);
const rf0 = embeddedViewStart(0, 3, 0);
{ showTree(rf0, {tree: ctx.projectedTree}); }
embeddedViewEnd();
}
@ -1109,15 +1110,15 @@ describe('render3 integration test', () => {
}
}
let args = ['(', 0, 'a', 1, 'b', 2, 'c', 3, 'd', 4, 'e', 5, 'f', 6, 'g', 7, ')'];
expect(renderToHtml(Template, args, 1, 10))
expect(renderToHtml(Template, args, 1, 54))
.toEqual(
'<b a="(0a1b2c3d4e5f6g7)" a0="0" a1="(0)" a2="(0a1)" a3="(0a1b2)" a4="(0a1b2c3)" a5="(0a1b2c3d4)" a6="(0a1b2c3d4e5)" a7="(0a1b2c3d4e5f6)" a8="(0a1b2c3d4e5f6g7)"></b>');
args = args.reverse();
expect(renderToHtml(Template, args, 1, 10))
expect(renderToHtml(Template, args, 1, 54))
.toEqual(
'<b a=")7g6f5e4d3c2b1a0(" a0="7" a1=")7(" a2=")7g6(" a3=")7g6f5(" a4=")7g6f5e4(" a5=")7g6f5e4d3(" a6=")7g6f5e4d3c2(" a7=")7g6f5e4d3c2b1(" a8=")7g6f5e4d3c2b1a0("></b>');
args = args.reverse();
expect(renderToHtml(Template, args, 1, 10))
expect(renderToHtml(Template, args, 1, 54))
.toEqual(
'<b a="(0a1b2c3d4e5f6g7)" a0="0" a1="(0)" a2="(0a1)" a3="(0a1b2)" a4="(0a1b2c3)" a5="(0a1b2c3d4)" a6="(0a1b2c3d4e5)" a7="(0a1b2c3d4e5f6)" a8="(0a1b2c3d4e5f6g7)"></b>');
});
@ -1136,14 +1137,16 @@ describe('render3 integration test', () => {
containerRefreshStart(1);
{
if (true) {
let rf1 = embeddedViewStart(1, 1, 0);
let rf1 = embeddedViewStart(1, 1, 1);
{
if (rf1 & RenderFlags.Create) {
elementStart(0, 'b');
{}
elementEnd();
}
elementAttribute(0, 'title', bind(ctx.title));
if (rf1 & RenderFlags.Update) {
elementAttribute(0, 'title', bind(ctx.title));
}
}
embeddedViewEnd();
}
@ -1182,6 +1185,7 @@ describe('render3 integration test', () => {
factory: function HostBindingDir_Factory() {
return hostBindingDir = new HostBindingDir();
},
hostVars: 1,
hostBindings: function HostBindingDir_HostBindings(dirIndex: number, elIndex: number) {
elementAttribute(
elIndex, 'aria-label', bind(loadDirective<HostBindingDir>(dirIndex).label));

View File

@ -41,7 +41,7 @@ describe('lifecycles', () => {
elementEnd();
}
}, 2);
let Parent = createOnInitComponent('parent', getParentTemplate('comp'), 1, [Comp]);
let Parent = createOnInitComponent('parent', getParentTemplate('comp'), 1, 1, [Comp]);
let ProjectedComp = createOnInitComponent('projected', (rf: RenderFlags, ctx: any) => {
if (rf & RenderFlags.Create) {
text(0, 'content');
@ -49,7 +49,8 @@ describe('lifecycles', () => {
}, 1);
function createOnInitComponent(
name: string, template: ComponentTemplate<any>, consts: number, directives: any[] = []) {
name: string, template: ComponentTemplate<any>, consts: number, vars: number = 0,
directives: any[] = []) {
return class Component {
val: string = '';
ngOnInit() {
@ -61,7 +62,7 @@ describe('lifecycles', () => {
type: Component,
selectors: [[name]],
consts: consts,
vars: 0,
vars: vars,
factory: () => new Component(),
inputs: {val: 'val'}, template,
directives: directives

View File

@ -236,7 +236,7 @@ describe('pipe', () => {
containerRefreshStart(4);
{
for (let i of [1, 2]) {
let rf1 = embeddedViewStart(1, 2, 0);
let rf1 = embeddedViewStart(1, 2, 3);
{
if (rf1 & RenderFlags.Create) {
elementStart(0, 'div');

View File

@ -510,7 +510,7 @@ describe('object literals', () => {
containerRefreshStart(0);
{
for (let i = 0; i < 2; i++) {
let rf1 = embeddedViewStart(0, 1, 0);
let rf1 = embeddedViewStart(0, 1, 4);
if (rf1 & RenderFlags.Create) {
elementStart(0, 'object-comp');
objectComps.push(loadDirective(0));
@ -531,12 +531,12 @@ describe('object literals', () => {
const e0_ff = (v1: any, v2: any) => { return {opacity: v1, duration: v2}; };
const configs = [{opacity: 0, duration: 500}, {opacity: 1, duration: 600}];
renderToHtml(Template, {configs}, 1, 4, defs);
renderToHtml(Template, {configs}, 1, 0, defs);
expect(objectComps[0].config).toEqual({opacity: 0, duration: 500});
expect(objectComps[1].config).toEqual({opacity: 1, duration: 600});
configs[0].duration = 1000;
renderToHtml(Template, {configs}, 1, 4, defs);
renderToHtml(Template, {configs}, 1, 0, defs);
expect(objectComps[0].config).toEqual({opacity: 0, duration: 1000});
expect(objectComps[1].config).toEqual({opacity: 1, duration: 600});
});

View File

@ -1148,7 +1148,7 @@ describe('query', () => {
}
},
7, 0, [ViewContainerManipulatorDirective], [],
9, 0, [ViewContainerManipulatorDirective], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
query(0, ['foo'], true, QUERY_READ_FROM_NODE);

View File

@ -89,7 +89,7 @@ export class TemplateFixture extends BaseFixture {
*/
update(updateBlock?: () => void): void {
renderTemplate(
this.hostNode.native, updateBlock || this.updateBlock, 0, null !, this.vars,
this.hostNode.native, updateBlock || this.updateBlock, 0, this.vars, null !,
this._rendererFactory, this.hostNode, this._directiveDefs, this._pipeDefs, this._sanitizer);
}
}

View File

@ -166,12 +166,12 @@ describe('styling', () => {
}
}
expect(renderToHtml(Template, {
myStyles: {width: '200px', height: '200px'},
myWidth: '300px'
})).toEqual('<span style="width: 300px; height: 200px; opacity: 0.5;"></span>');
expect(renderToHtml(
Template, {myStyles: {width: '200px', height: '200px'}, myWidth: '300px'}, 1))
.toEqual('<span style="width: 300px; height: 200px; opacity: 0.5;"></span>');
expect(renderToHtml(Template, {myStyles: {width: '200px', height: null}, myWidth: null}))
expect(
renderToHtml(Template, {myStyles: {width: '200px', height: null}, myWidth: null}, 1))
.toEqual('<span style="width: 200px; height: 100px; opacity: 0.5;"></span>');
});
});

View File

@ -123,7 +123,7 @@ describe('ViewContainerRef', () => {
}
const fixture = new TemplateFixture(
createTemplate, updateTemplate, 3, 1, [HeaderComponent, DirectiveWithVCRef]);
createTemplate, updateTemplate, 4, 1, [HeaderComponent, DirectiveWithVCRef]);
expect(fixture.html).toEqual('<header-cmp vcref=""></header-cmp><footer></footer>');
createView('A');
@ -643,7 +643,7 @@ describe('ViewContainerRef', () => {
function rowTemplate(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
template(0, cellTemplate, 2, 1, null, null, ['cellTemplate', ''], templateRefExtractor);
template(0, cellTemplate, 2, 3, null, null, ['cellTemplate', ''], templateRefExtractor);
element(2, 'loop-comp');
}