From 4ede190571595c4a74abe2b320f5a4dc3c61a967 Mon Sep 17 00:00:00 2001 From: Andrew Scott Date: Tue, 6 Oct 2020 15:02:19 -0700 Subject: [PATCH] refactor(compiler-cli): wrap RHS of property write in parens (#39143) The right needs to be wrapped in parens or we cannot accurately match its span to just the RHS. For example, the span in `e = $event /*0,10*/` is ambiguous. It could refer to either the whole binary expression or just the RHS. We should instead generate `e = ($event /*0,10*/)` so we know the span 0,10 matches RHS. This is specifically needed for the TemplateTypeChecker/Language Service when mapping template positions to items in the TCB. PR Close #39143 --- .../compiler-cli/src/ngtsc/typecheck/src/expression.ts | 9 ++++++++- .../src/ngtsc/typecheck/test/span_comments_spec.ts | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/compiler-cli/src/ngtsc/typecheck/src/expression.ts b/packages/compiler-cli/src/ngtsc/typecheck/src/expression.ts index 6001896b5e..f462987f84 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/src/expression.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/src/expression.ts @@ -251,7 +251,14 @@ class AstTranslator implements AstVisitor { // ^ nameSpan const leftWithPath = wrapForDiagnostics(left); addParseSpanInfo(leftWithPath, ast.sourceSpan); - const right = this.translate(ast.value); + let right = this.translate(ast.value); + // The right needs to be wrapped in parens as well or we cannot accurately match its + // span to just the RHS. For example, the span in `e = $event /*0,10*/` is ambiguous. + // It could refer to either the whole binary expression or just the RHS. + // We should instead generate `e = ($event /*0,10*/)` so we know the span 0,10 matches RHS. + if (!ts.isParenthesizedExpression(right)) { + right = wrapForTypeChecker(right); + } const node = wrapForDiagnostics(ts.createBinary(leftWithPath, ts.SyntaxKind.EqualsToken, right)); addParseSpanInfo(node, ast.sourceSpan); diff --git a/packages/compiler-cli/src/ngtsc/typecheck/test/span_comments_spec.ts b/packages/compiler-cli/src/ngtsc/typecheck/test/span_comments_spec.ts index ef4465cca2..8408789547 100644 --- a/packages/compiler-cli/src/ngtsc/typecheck/test/span_comments_spec.ts +++ b/packages/compiler-cli/src/ngtsc/typecheck/test/span_comments_spec.ts @@ -94,6 +94,12 @@ describe('type check blocks diagnostics', () => { '(((((((ctx).a /*14,15*/) /*14,15*/).b /*16,17*/) /*14,17*/).c /*18,19*/) /*14,23*/ = ((ctx).d /*22,23*/) /*22,23*/) /*14,23*/'); }); + it('should $event property writes', () => { + const TEMPLATE = `
`; + expect(tcbWithSpans(TEMPLATE)) + .toContain('(((ctx).a /*14,15*/) /*14,24*/ = ($event /*18,24*/)) /*14,24*/;'); + }); + it('should annotate keyed property access', () => { const TEMPLATE = `{{ a[b] }}`; expect(tcbWithSpans(TEMPLATE))