diff --git a/packages/compiler/src/render3/r3_ast.ts b/packages/compiler/src/render3/r3_ast.ts index 33a86c629b..ef2d1a732a 100644 --- a/packages/compiler/src/render3/r3_ast.ts +++ b/packages/compiler/src/render3/r3_ast.ts @@ -118,7 +118,7 @@ export class Content implements Node { export class Variable implements Node { constructor( public name: string, public value: string, public sourceSpan: ParseSourceSpan, - public valueSpan?: ParseSourceSpan) {} + readonly keySpan: ParseSourceSpan, public valueSpan?: ParseSourceSpan) {} visit(visitor: Visitor): Result { return visitor.visitVariable(this); } diff --git a/packages/compiler/src/render3/r3_template_transform.ts b/packages/compiler/src/render3/r3_template_transform.ts index 61feb3bf4a..0018a68481 100644 --- a/packages/compiler/src/render3/r3_template_transform.ts +++ b/packages/compiler/src/render3/r3_template_transform.ts @@ -159,7 +159,7 @@ class HtmlAstToIvyAst implements html.Visitor { templateKey, templateValue, attribute.sourceSpan, absoluteValueOffset, [], templateParsedProperties, parsedVariables); templateVariables.push(...parsedVariables.map( - v => new t.Variable(v.name, v.value, v.sourceSpan, v.valueSpan))); + v => new t.Variable(v.name, v.value, v.sourceSpan, v.keySpan, v.valueSpan))); } else { // Check for variables, events, property bindings, interpolation hasBinding = this.parseAttribute( @@ -356,7 +356,8 @@ class HtmlAstToIvyAst implements html.Visitor { } else if (bindParts[KW_LET_IDX]) { if (isTemplateElement) { const identifier = bindParts[IDENT_KW_IDX]; - this.parseVariable(identifier, value, srcSpan, attribute.valueSpan, variables); + const keySpan = createKeySpan(srcSpan, bindParts[KW_LET_IDX], identifier); + this.parseVariable(identifier, value, srcSpan, keySpan, attribute.valueSpan, variables); } else { this.reportError(`"let-" is only supported on ng-template elements.`, srcSpan); } @@ -425,7 +426,7 @@ class HtmlAstToIvyAst implements html.Visitor { } private parseVariable( - identifier: string, value: string, sourceSpan: ParseSourceSpan, + identifier: string, value: string, sourceSpan: ParseSourceSpan, keySpan: ParseSourceSpan, valueSpan: ParseSourceSpan|undefined, variables: t.Variable[]) { if (identifier.indexOf('-') > -1) { this.reportError(`"-" is not allowed in variable names`, sourceSpan); @@ -433,7 +434,7 @@ class HtmlAstToIvyAst implements html.Visitor { this.reportError(`Variable does not have a name`, sourceSpan); } - variables.push(new t.Variable(identifier, value, sourceSpan, valueSpan)); + variables.push(new t.Variable(identifier, value, sourceSpan, keySpan, valueSpan)); } private parseReference( diff --git a/packages/compiler/test/render3/r3_ast_spans_spec.ts b/packages/compiler/test/render3/r3_ast_spans_spec.ts index 90268e5134..e74722c109 100644 --- a/packages/compiler/test/render3/r3_ast_spans_spec.ts +++ b/packages/compiler/test/render3/r3_ast_spans_spec.ts @@ -50,8 +50,12 @@ class R3AstSourceSpans implements t.Visitor { } visitVariable(variable: t.Variable) { - this.result.push( - ['Variable', humanizeSpan(variable.sourceSpan), humanizeSpan(variable.valueSpan)]); + this.result.push([ + 'Variable', + humanizeSpan(variable.sourceSpan), + humanizeSpan(variable.keySpan), + humanizeSpan(variable.valueSpan), + ]); } visitReference(reference: t.Reference) { @@ -233,7 +237,7 @@ describe('R3 AST source spans', () => { 'Template', '', '', '' ], - ['Variable', 'let-a="b"', 'b'], + ['Variable', 'let-a="b"', 'a', 'b'], ]); }); @@ -243,7 +247,7 @@ describe('R3 AST source spans', () => { 'Template', '', '', '' ], - ['Variable', 'data-let-a="b"', 'b'], + ['Variable', 'data-let-a="b"', 'a', 'b'], ]); }); @@ -282,7 +286,7 @@ describe('R3 AST source spans', () => { ], ['TextAttribute', 'ngFor', ''], ['BoundAttribute', '*ngFor="let item of items"', 'of', 'items'], - ['Variable', 'let item ', ''], + ['Variable', 'let item ', 'item', ''], [ 'Element', '
', '
', '
' @@ -314,7 +318,7 @@ describe('R3 AST source spans', () => { [ 'BoundAttribute', '*ngFor="let item of items; trackBy: trackByFn"', 'trackBy', 'trackByFn' ], - ['Variable', 'let item ', ''], + ['Variable', 'let item ', 'item', ''], [ 'Element', '
', '
', '
' @@ -327,7 +331,7 @@ describe('R3 AST source spans', () => { expectFromHtml('
').toEqual([ ['Template', '
', '
', '
'], ['TextAttribute', 'ngIf', ''], - ['Variable', 'let a=b', 'b'], + ['Variable', 'let a=b', 'a', 'b'], ['Element', '
', '
', '
'], ]); }); @@ -336,7 +340,7 @@ describe('R3 AST source spans', () => { expectFromHtml('
').toEqual([ ['Template', '
', '
', '
'], ['BoundAttribute', '*ngIf="expr as local"', 'ngIf', 'expr'], - ['Variable', 'ngIf="expr as local', 'ngIf'], + ['Variable', 'ngIf="expr as local', 'local', 'ngIf'], ['Element', '
', '
', '
'], ]); });