diff --git a/packages/compiler/src/template_parser/binding_parser.ts b/packages/compiler/src/template_parser/binding_parser.ts index b2e52327ab849..64c6438a59b80 100644 --- a/packages/compiler/src/template_parser/binding_parser.ts +++ b/packages/compiler/src/template_parser/binding_parser.ts @@ -118,7 +118,7 @@ export class BindingParser { tplKey: string, tplValue: string, sourceSpan: ParseSourceSpan, absoluteOffset: number, targetMatchableAttrs: string[][], targetProps: ParsedProperty[], targetVars: ParsedVariable[]) { - const bindings = this._parseTemplateBindings(tplKey, tplValue, sourceSpan); + const bindings = this._parseTemplateBindings(tplKey, tplValue, sourceSpan, absoluteOffset); for (let i = 0; i < bindings.length; i++) { const binding = bindings[i]; @@ -137,13 +137,14 @@ export class BindingParser { } } - private _parseTemplateBindings(tplKey: string, tplValue: string, sourceSpan: ParseSourceSpan): - TemplateBinding[] { + private _parseTemplateBindings( + tplKey: string, tplValue: string, sourceSpan: ParseSourceSpan, + absoluteOffset: number): TemplateBinding[] { const sourceInfo = sourceSpan.start.toString(); try { - const bindingsResult = this._exprParser.parseTemplateBindings( - tplKey, tplValue, sourceInfo, sourceSpan.start.offset); + const bindingsResult = + this._exprParser.parseTemplateBindings(tplKey, tplValue, sourceInfo, absoluteOffset); this._reportExpressionParserErrors(bindingsResult.errors, sourceSpan); bindingsResult.templateBindings.forEach((binding) => { if (binding.expression) { diff --git a/packages/compiler/test/render3/r3_ast_absolute_span_spec.ts b/packages/compiler/test/render3/r3_ast_absolute_span_spec.ts index 151e2906e0e9d..cc38497f26822 100644 --- a/packages/compiler/test/render3/r3_ast_absolute_span_spec.ts +++ b/packages/compiler/test/render3/r3_ast_absolute_span_spec.ts @@ -44,6 +44,12 @@ describe('expression AST absolute source spans', () => { .toContain(['condition ? true : false', new AbsoluteSourceSpan(22, 46)]); }); + it('should provide absolute offsets of an expression in a template attribute', () => { + expect(humanizeExpressionSource(parse('
').nodes)).toContain([ + '(value | async)', new AbsoluteSourceSpan(12, 25) + ]); + }); + describe('binary expression', () => { it('should provide absolute offsets of a binary expression', () => { expect(humanizeExpressionSource(parse('
{{1 + 2}}
').nodes)).toContain([ diff --git a/packages/compiler/test/render3/util/expression.ts b/packages/compiler/test/render3/util/expression.ts index 5ed2c4b7d7c18..12331d8636597 100644 --- a/packages/compiler/test/render3/util/expression.ts +++ b/packages/compiler/test/render3/util/expression.ts @@ -102,7 +102,10 @@ class ExpressionSourceHumanizer extends e.RecursiveAstVisitor implements t.Visit super.visitQuote(ast, null); } - visitTemplate(ast: t.Template) { t.visitAll(this, ast.children); } + visitTemplate(ast: t.Template) { + t.visitAll(this, ast.children); + t.visitAll(this, ast.templateAttrs); + } visitElement(ast: t.Element) { t.visitAll(this, ast.children); t.visitAll(this, ast.inputs);