fix(compiler): source span for microsyntax text att should be key span (#38766)
In a microsyntax expressions, some attributes are not bound after desugaring. For example, ```html <div *ngFor="let item of items"> </div> ``` gets desugared to ```html <ng-template ngFor let-items [ngForOf]="items"> </ngtemplate> ``` In this case, `ngFor` should be a literal attribute with no RHS value. Therefore, its source span should be just the `keySpan` and not the source span of the original template node. This allows language service to precisely pinpoint different spans in a microsyntax to provide accurate information. PR Close #38766
This commit is contained in:
parent
19598b47ca
commit
8f349b2375
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -174,7 +174,7 @@ describe('R3 AST source spans', () => {
|
|||
it('is correct for * directives', () => {
|
||||
expectFromHtml('<div *ngIf></div>').toEqual([
|
||||
['Template', '0:17', '0:11', '11:17'],
|
||||
['TextAttribute', '5:10', '<empty>'],
|
||||
['TextAttribute', '6:10', '<empty>'], // ngIf
|
||||
['Element', '0:17', '0:11', '11:17'],
|
||||
]);
|
||||
});
|
||||
|
@ -237,7 +237,7 @@ describe('R3 AST source spans', () => {
|
|||
// </ng-template>
|
||||
expectFromHtml('<div *ngFor="let item of items"></div>').toEqual([
|
||||
['Template', '0:38', '0:32', '32:38'],
|
||||
['TextAttribute', '5:31', '<empty>'],
|
||||
['TextAttribute', '6:11', '<empty>'], // ngFor
|
||||
['BoundAttribute', '5:31', '25:30'], // *ngFor="let item of items" -> items
|
||||
['Variable', '13:22', '<empty>'], // let item
|
||||
['Element', '0:38', '0:32', '32:38'],
|
||||
|
@ -260,7 +260,7 @@ describe('R3 AST source spans', () => {
|
|||
it('is correct for variables via let ...', () => {
|
||||
expectFromHtml('<div *ngIf="let a=b"></div>').toEqual([
|
||||
['Template', '0:27', '0:21', '21:27'],
|
||||
['TextAttribute', '5:20', '<empty>'],
|
||||
['TextAttribute', '6:10', '<empty>'], // ngIf
|
||||
['Variable', '12:19', '18:19'], // let a=b -> b
|
||||
['Element', '0:27', '0:21', '21:27'],
|
||||
]);
|
||||
|
|
|
@ -487,8 +487,9 @@ describe('findNodeAtPosition for microsyntax expression', () => {
|
|||
// <ng-template ngFor let-item [ngForOf]="items">
|
||||
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', () => {
|
||||
|
|
Loading…
Reference in New Issue