From 4dfa71f018cea6c9cce470aeecf0bbcac53a41c4 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Tue, 30 Oct 2018 10:05:12 -0700 Subject: [PATCH] feat(compiler): ability to mark an InvokeFunctionExpr as pure (#26860) Uglify and other tree-shakers attempt to determine if the invocation of a function is side-effectful, and remove it if so (and the result is unused). A /*@__PURE__*/ annotation on the call site can be used to hint to the optimizer that the invocation has no side effects and is safe to tree-shake away. This commit adds a 'pure' flag to the output AST function call node, which can be used to signal to downstream emitters that a pure annotation should be added. It also modifies ngtsc's emitter to emit an Uglify pure annotation when this flag is set. Testing strategy: this will be tested via its consumers, by asserting that pure functions are translated with the correct comment. PR Close #26860 --- .../compiler-cli/src/ngtsc/translator/src/translator.ts | 6 +++++- packages/compiler/src/output/output_ast.ts | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/compiler-cli/src/ngtsc/translator/src/translator.ts b/packages/compiler-cli/src/ngtsc/translator/src/translator.ts index e9d2780c7f..0005d506c8 100644 --- a/packages/compiler-cli/src/ngtsc/translator/src/translator.ts +++ b/packages/compiler-cli/src/ngtsc/translator/src/translator.ts @@ -185,9 +185,13 @@ class ExpressionTranslatorVisitor implements ExpressionVisitor, StatementVisitor } visitInvokeFunctionExpr(ast: InvokeFunctionExpr, context: Context): ts.CallExpression { - return ts.createCall( + const expr = ts.createCall( ast.fn.visitExpression(this, context), undefined, ast.args.map(arg => arg.visitExpression(this, context))); + if (ast.pure) { + ts.addSyntheticLeadingComment(expr, ts.SyntaxKind.MultiLineCommentTrivia, '@__PURE__', false); + } + return expr; } visitInstantiateExpr(ast: InstantiateExpr, context: Context): ts.NewExpression { diff --git a/packages/compiler/src/output/output_ast.ts b/packages/compiler/src/output/output_ast.ts index 7ab2775400..7b456e89d6 100644 --- a/packages/compiler/src/output/output_ast.ts +++ b/packages/compiler/src/output/output_ast.ts @@ -424,13 +424,13 @@ export class InvokeMethodExpr extends Expression { export class InvokeFunctionExpr extends Expression { constructor( public fn: Expression, public args: Expression[], type?: Type|null, - sourceSpan?: ParseSourceSpan|null) { + sourceSpan?: ParseSourceSpan|null, public pure = false) { super(type, sourceSpan); } isEquivalent(e: Expression): boolean { return e instanceof InvokeFunctionExpr && this.fn.isEquivalent(e.fn) && - areAllEquivalent(this.args, e.args); + areAllEquivalent(this.args, e.args) && this.pure === e.pure; } isConstant() { return false; }