diff --git a/packages/compiler/src/template_parser/binding_parser.ts b/packages/compiler/src/template_parser/binding_parser.ts
index 1c19d69c9c..ca0001f44e 100644
--- a/packages/compiler/src/template_parser/binding_parser.ts
+++ b/packages/compiler/src/template_parser/binding_parser.ts
@@ -157,10 +157,12 @@ export class BindingParser {
this._parsePropertyAst(
key, binding.value, sourceSpan, valueSpan, targetMatchableAttrs, targetProps);
} else {
- targetMatchableAttrs.push([key, '']);
+ targetMatchableAttrs.push([key, '' /* value */]);
+ // Since this is a literal attribute with no RHS, source span should be
+ // just the key span.
this.parseLiteralAttr(
- key, null, sourceSpan, absoluteValueOffset, undefined, targetMatchableAttrs,
- targetProps);
+ key, null /* value */, keySpan, absoluteValueOffset, undefined /* valueSpan */,
+ targetMatchableAttrs, targetProps);
}
}
}
diff --git a/packages/compiler/test/render3/r3_ast_spans_spec.ts b/packages/compiler/test/render3/r3_ast_spans_spec.ts
index 6fc6b3003b..791b36021f 100644
--- a/packages/compiler/test/render3/r3_ast_spans_spec.ts
+++ b/packages/compiler/test/render3/r3_ast_spans_spec.ts
@@ -174,7 +174,7 @@ describe('R3 AST source spans', () => {
it('is correct for * directives', () => {
expectFromHtml('
').toEqual([
['Template', '0:17', '0:11', '11:17'],
- ['TextAttribute', '5:10', ''],
+ ['TextAttribute', '6:10', ''], // ngIf
['Element', '0:17', '0:11', '11:17'],
]);
});
@@ -237,9 +237,9 @@ describe('R3 AST source spans', () => {
//
expectFromHtml('').toEqual([
['Template', '0:38', '0:32', '32:38'],
- ['TextAttribute', '5:31', ''],
- ['BoundAttribute', '5:31', '25:30'], // *ngFor="let item of items" -> items
- ['Variable', '13:22', ''], // let item
+ ['TextAttribute', '6:11', ''], // ngFor
+ ['BoundAttribute', '5:31', '25:30'], // *ngFor="let item of items" -> items
+ ['Variable', '13:22', ''], // let item
['Element', '0:38', '0:32', '32:38'],
]);
@@ -260,8 +260,8 @@ describe('R3 AST source spans', () => {
it('is correct for variables via let ...', () => {
expectFromHtml('').toEqual([
['Template', '0:27', '0:21', '21:27'],
- ['TextAttribute', '5:20', ''],
- ['Variable', '12:19', '18:19'], // let a=b -> b
+ ['TextAttribute', '6:10', ''], // ngIf
+ ['Variable', '12:19', '18:19'], // let a=b -> b
['Element', '0:27', '0:21', '21:27'],
]);
});
diff --git a/packages/language-service/ivy/test/hybrid_visitor_spec.ts b/packages/language-service/ivy/test/hybrid_visitor_spec.ts
index 43820c7e45..8a9d06fc6e 100644
--- a/packages/language-service/ivy/test/hybrid_visitor_spec.ts
+++ b/packages/language-service/ivy/test/hybrid_visitor_spec.ts
@@ -487,8 +487,9 @@ describe('findNodeAtPosition for microsyntax expression', () => {
//
expect(errors).toBe(null);
const node = findNodeAtPosition(nodes, position);
- // TODO: this is currently wrong because it should point to ngFor text
- // attribute instead of ngForOf bound attribute
+ expect(isTemplateNode(node!)).toBeTrue();
+ expect(node).toBeInstanceOf(t.TextAttribute);
+ expect((node as t.TextAttribute).name).toBe('ngFor');
});
it('should locate not let keyword', () => {