fix(ivy): proper slot allocation for pure functions in `hostBindings` function (#27587)

Prior to this update, we always returned the number of host vars defined in @Component definition as a value for `allocatePureFunctionsSlot` callback in ValueConverter. As a result, pure function arguments were not accounted for, thus leasing to incorrect slot offsets in `pureFunction` calls. Now we update and return total # of host vars, so the offsets are defined correctly.

PR Close #27587
This commit is contained in:
Andrew Kushnir 2018-12-10 14:53:10 -08:00 committed by Alex Rickabaugh
parent 3cb6dad6d5
commit ceb14deb60
2 changed files with 80 additions and 2 deletions

View File

@ -383,6 +383,84 @@ describe('compiler compliance', () => {
expectEmit(result.source, template, 'Incorrect template');
});
it('should reserve slots for pure functions in host binding function', () => {
const files = {
app: {
'spec.ts': `
import {Component, NgModule, Input} from '@angular/core';
@Component({
selector: 'my-component',
template: '...',
host: {
'[@expansionHeight]': \`{
value: getExpandedState(),
params: {
collapsedHeight: collapsedHeight,
expandedHeight: expandedHeight
}
}\`,
'[@expansionWidth]': \`{
value: getExpandedState(),
params: {
collapsedWidth: collapsedWidth,
expandedWidth: expandedWidth
}
}\`
}
})
export class MyComponent {
@Input() expandedHeight: string;
@Input() collapsedHeight: string;
@Input() expandedWidth: string;
@Input() collapsedWidth: string;
getExpandedState() {
return 'expanded';
}
}
@NgModule({
declarations: [MyComponent]
})
export class MyModule {}
`
}
};
const hostBindingsDef = `
const $_c0$ = function (a0, a1) { return { collapsedHeight: a0, expandedHeight: a1 }; };
const $_c1$ = function (a0, a1) { return { value: a0, params: a1 }; };
const $_c2$ = function (a0, a1) { return { collapsedWidth: a0, expandedWidth: a1 }; };
hostBindings: function MyComponent_HostBindings(rf, ctx, elIndex) {
if (rf & 1) {
$r3$.ɵallocHostVars(14);
}
if (rf & 2) {
$r3$.ɵelementProperty(elIndex, "expansionHeight",
$r3$.ɵbind(
$r3$.ɵpureFunction2(5, $_c1$, ctx.getExpandedState(),
$r3$.ɵpureFunction2(2, $_c0$, ctx.collapsedHeight, ctx.expandedHeight)
)
)
);
$r3$.ɵelementProperty(elIndex, "expansionWidth",
$r3$.ɵbind(
$r3$.ɵpureFunction2(11, $_c1$, ctx.getExpandedState(),
$r3$.ɵpureFunction2(8, $_c2$, ctx.collapsedWidth, ctx.expandedWidth)
)
)
);
}
},
`;
const result = compile(files, angularFiles);
expectEmit(result.source, hostBindingsDef, 'Incorrect "hostBindings" function');
});
it('should bind to class and style names', () => {
const files = {
app: {

View File

@ -666,11 +666,11 @@ function createHostBindingsFunction(
return convertPropertyBinding(
null, implicit, value, 'b', BindingForm.TrySimple, () => error('Unexpected interpolation'));
};
if (bindings) {
const hostVarsCountFn = (numSlots: number): number => {
const originalVarsCount = totalHostVarsCount;
totalHostVarsCount += numSlots;
return hostVarsCount;
return originalVarsCount;
};
const valueConverter = new ValueConverter(
constantPool,