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
This commit is contained in:
parent
4e9f2e5895
commit
4dfa71f018
|
@ -185,9 +185,13 @@ class ExpressionTranslatorVisitor implements ExpressionVisitor, StatementVisitor
|
||||||
}
|
}
|
||||||
|
|
||||||
visitInvokeFunctionExpr(ast: InvokeFunctionExpr, context: Context): ts.CallExpression {
|
visitInvokeFunctionExpr(ast: InvokeFunctionExpr, context: Context): ts.CallExpression {
|
||||||
return ts.createCall(
|
const expr = ts.createCall(
|
||||||
ast.fn.visitExpression(this, context), undefined,
|
ast.fn.visitExpression(this, context), undefined,
|
||||||
ast.args.map(arg => arg.visitExpression(this, context)));
|
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 {
|
visitInstantiateExpr(ast: InstantiateExpr, context: Context): ts.NewExpression {
|
||||||
|
|
|
@ -424,13 +424,13 @@ export class InvokeMethodExpr extends Expression {
|
||||||
export class InvokeFunctionExpr extends Expression {
|
export class InvokeFunctionExpr extends Expression {
|
||||||
constructor(
|
constructor(
|
||||||
public fn: Expression, public args: Expression[], type?: Type|null,
|
public fn: Expression, public args: Expression[], type?: Type|null,
|
||||||
sourceSpan?: ParseSourceSpan|null) {
|
sourceSpan?: ParseSourceSpan|null, public pure = false) {
|
||||||
super(type, sourceSpan);
|
super(type, sourceSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
isEquivalent(e: Expression): boolean {
|
isEquivalent(e: Expression): boolean {
|
||||||
return e instanceof InvokeFunctionExpr && this.fn.isEquivalent(e.fn) &&
|
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; }
|
isConstant() { return false; }
|
||||||
|
|
Loading…
Reference in New Issue