From 859ebdd836d1eb3fd07b5e4fa112a6749769131c Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Fri, 26 Jul 2019 10:49:34 -0700 Subject: [PATCH] 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 --- .../src/ngtsc/indexer/src/template.ts | 2 +- .../src/ngtsc/indexer/test/template_spec.ts | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/packages/compiler-cli/src/ngtsc/indexer/src/template.ts b/packages/compiler-cli/src/ngtsc/indexer/src/template.ts index aeb2551240..84d32411e9 100644 --- a/packages/compiler-cli/src/ngtsc/indexer/src/template.ts +++ b/packages/compiler-cli/src/ngtsc/indexer/src/template.ts @@ -201,7 +201,7 @@ class TemplateVisitor extends TmplAstRecursiveVisitor { const identifiers = ExpressionVisitor.getIdentifiers( attribute.value, expressionSrc, expressionAbsolutePosition, this.boundTemplate, - this.targetToIdentifier); + this.targetToIdentifier.bind(this)); identifiers.forEach(id => this.identifiers.add(id)); } visitBoundEvent(attribute: TmplAstBoundEvent) { this.visitExpression(attribute.handler); } diff --git a/packages/compiler-cli/src/ngtsc/indexer/test/template_spec.ts b/packages/compiler-cli/src/ngtsc/indexer/test/template_spec.ts index e02f5e96b2..831de6640f 100644 --- a/packages/compiler-cli/src/ngtsc/indexer/test/template_spec.ts +++ b/packages/compiler-cli/src/ngtsc/indexer/test/template_spec.ts @@ -124,6 +124,32 @@ runInEachFileSystem(() => { }); }); + it('should discover variables in bound attributes', () => { + const template = '
'; + 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', () => { const template = '
'; const refs = getTemplateIdentifiers(bind(template));