fix(ivy): fix bug with banana-in-a-box expressions in nested templates (#25321)
Inside of a nested template, an attempt to generate code for a banana- in-a-box expression would cause a crash in the _AstToIrVisitor, as it was not handling the case where a write would be generated to a local variable. This change supports such a mode of operation. PR Close #25321
This commit is contained in:
parent
02e201ab1a
commit
fefc860f35
|
@ -640,4 +640,21 @@ describe('ngtsc behavioral tests', () => {
|
|||
expect(emptyFactory).toContain(`import * as i0 from '@angular/core';`);
|
||||
expect(emptyFactory).toContain(`export var ɵNonEmptyModule = true;`);
|
||||
});
|
||||
|
||||
it('should compile a banana-in-a-box inside of a template', () => {
|
||||
writeConfig();
|
||||
write('test.ts', `
|
||||
import {Component} from '@angular/core';
|
||||
|
||||
@Component({
|
||||
template: '<div *tmpl [(bananaInABox)]="prop"></div>',
|
||||
selector: 'test'
|
||||
})
|
||||
class TestCmp {}
|
||||
`);
|
||||
|
||||
const exitCode = main(['-p', basePath], errorSpy);
|
||||
expect(errorSpy).not.toHaveBeenCalled();
|
||||
expect(exitCode).toBe(0);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -449,14 +449,28 @@ class _AstToIrVisitor implements cdAst.AstVisitor {
|
|||
|
||||
visitPropertyWrite(ast: cdAst.PropertyWrite, mode: _Mode): any {
|
||||
const receiver: o.Expression = this._visit(ast.receiver, _Mode.Expression);
|
||||
|
||||
let varExpr: o.ReadPropExpr|null = null;
|
||||
if (receiver === this._implicitReceiver) {
|
||||
const varExpr = this._getLocal(ast.name);
|
||||
if (varExpr) {
|
||||
throw new Error('Cannot assign to a reference or variable!');
|
||||
const localExpr = this._getLocal(ast.name);
|
||||
if (localExpr) {
|
||||
if (localExpr instanceof o.ReadPropExpr) {
|
||||
// If the local variable is a property read expression, it's a reference
|
||||
// to a 'context.property' value and will be used as the target of the
|
||||
// write expression.
|
||||
varExpr = localExpr;
|
||||
} else {
|
||||
// Otherwise it's an error.
|
||||
throw new Error('Cannot assign to a reference or variable!');
|
||||
}
|
||||
}
|
||||
}
|
||||
return convertToStatementIfNeeded(
|
||||
mode, receiver.prop(ast.name).set(this._visit(ast.value, _Mode.Expression)));
|
||||
// If no local expression could be produced, use the original receiver's
|
||||
// property as the target.
|
||||
if (varExpr === null) {
|
||||
varExpr = receiver.prop(ast.name);
|
||||
}
|
||||
return convertToStatementIfNeeded(mode, varExpr.set(this._visit(ast.value, _Mode.Expression)));
|
||||
}
|
||||
|
||||
visitSafePropertyRead(ast: cdAst.SafePropertyRead, mode: _Mode): any {
|
||||
|
|
Loading…
Reference in New Issue