From 09af7ea4f56b43ae3133f2ae3b0514326f2f1518 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Thu, 31 Jan 2019 14:19:29 -0800 Subject: [PATCH] fix(compiler): fix two existing expression transformer issues (#28523) Testing of Ivy revealed two bugs in the AstMemoryEfficientTransformer class, a part of existing View Engine compiler infrastructure that's reused in Ivy. These bugs cause AST expressions not to be transformed under certain circumstances. The fix is simple, and tests are added to ensure the specific expression forms that trigger the issue compile properly under Ivy. PR Close #28523 --- .../compiler-cli/test/ngtsc/ngtsc_spec.ts | 43 +++++++++++++++++++ .../compiler/src/expression_parser/ast.ts | 5 ++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 8e6e9daf12..2aa6e01a7f 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -624,6 +624,49 @@ describe('ngtsc behavioral tests', () => { 'i0.ɵNgModuleDefWithMeta'); }); + describe('former View Engine AST transform bugs', () => { + it('should compile array literals behind conditionals', () => { + env.tsconfig(); + env.write('test.ts', ` + import {Component} from '@angular/core'; + + @Component({ + selector: 'test', + template: '{{value ? "yes" : [no]}}', + }) + class TestCmp { + value = true; + no = 'no'; + } + `); + + env.driveMain(); + expect(env.getContents('test.js')).toContain('i0.ɵpureFunction1'); + }); + + it('should compile array literals inside function arguments', () => { + env.tsconfig(); + env.write('test.ts', ` + import {Component} from '@angular/core'; + + @Component({ + selector: 'test', + template: '{{fn([test])}}', + }) + class TestCmp { + fn(arg: any): string { + return 'test'; + } + + test = 'test'; + } + `); + + env.driveMain(); + expect(env.getContents('test.js')).toContain('i0.ɵpureFunction1'); + }); + }); + describe('unwrapping ModuleWithProviders functions', () => { it('should extract the generic type and include it in the module\'s declaration', () => { env.tsconfig(); diff --git a/packages/compiler/src/expression_parser/ast.ts b/packages/compiler/src/expression_parser/ast.ts index 825138ad83..208cda0ca2 100644 --- a/packages/compiler/src/expression_parser/ast.ts +++ b/packages/compiler/src/expression_parser/ast.ts @@ -477,8 +477,9 @@ export class AstMemoryEfficientTransformer implements AstVisitor { visitMethodCall(ast: MethodCall, context: any): AST { const receiver = ast.receiver.visit(this); - if (receiver !== ast.receiver) { - return new MethodCall(ast.span, receiver, ast.name, this.visitAll(ast.args)); + const args = this.visitAll(ast.args); + if (receiver !== ast.receiver || args !== ast.args) { + return new MethodCall(ast.span, receiver, ast.name, args); } return ast; }