fix(ivy): correctly bind `targetToIdentifier` to the TemplateVisitor (#31861)

`TemplateVisitor#visitBoundAttribute` currently has to invoke visiting
expressions manually (this is fixed in #31813). Previously, it did not
bind `targetToIdentifier` to the visitor before deferring to the
expression visitor, which breaks the `targetToIdentifier` code. This
fixes that and adds a test to ensure the closure processed correctly.

This change is urgent; without it, many indexing targets in g3 are
broken.

PR Close #31861
This commit is contained in:
Ayaz Hafiz 2019-07-26 10:49:34 -07:00 committed by Andrew Kushnir
parent 30673090ec
commit 859ebdd836
2 changed files with 27 additions and 1 deletions

View File

@ -201,7 +201,7 @@ class TemplateVisitor extends TmplAstRecursiveVisitor {
const identifiers = ExpressionVisitor.getIdentifiers( const identifiers = ExpressionVisitor.getIdentifiers(
attribute.value, expressionSrc, expressionAbsolutePosition, this.boundTemplate, attribute.value, expressionSrc, expressionAbsolutePosition, this.boundTemplate,
this.targetToIdentifier); this.targetToIdentifier.bind(this));
identifiers.forEach(id => this.identifiers.add(id)); identifiers.forEach(id => this.identifiers.add(id));
} }
visitBoundEvent(attribute: TmplAstBoundEvent) { this.visitExpression(attribute.handler); } visitBoundEvent(attribute: TmplAstBoundEvent) { this.visitExpression(attribute.handler); }

View File

@ -124,6 +124,32 @@ runInEachFileSystem(() => {
}); });
}); });
it('should discover variables in bound attributes', () => {
const template = '<div #div [value]="div.innerText"></div>';
const refs = getTemplateIdentifiers(bind(template));
const elementReference: ElementIdentifier = {
name: 'div',
kind: IdentifierKind.Element,
span: new AbsoluteSourceSpan(1, 4),
attributes: new Set(),
usedDirectives: new Set(),
};
const reference: ReferenceIdentifier = {
name: 'div',
kind: IdentifierKind.Reference,
span: new AbsoluteSourceSpan(6, 9),
target: {node: elementReference, directive: null},
};
const refArr = Array.from(refs);
expect(refArr).toContain({
name: 'div',
kind: IdentifierKind.Property,
span: new AbsoluteSourceSpan(19, 22),
target: reference,
});
});
it('should discover properties in template expressions', () => { it('should discover properties in template expressions', () => {
const template = '<div [bar]="bar ? bar1 : bar2"></div>'; const template = '<div [bar]="bar ? bar1 : bar2"></div>';
const refs = getTemplateIdentifiers(bind(template)); const refs = getTemplateIdentifiers(bind(template));