From 6f6102d8ad6627fd65133d1686e0e637a3f9990b Mon Sep 17 00:00:00 2001 From: Charles Lyding <19598772+clydin@users.noreply.github.com> Date: Wed, 29 Jul 2020 15:31:27 -0400 Subject: [PATCH] fix(compiler): add PURE annotation to getInheritedFactory calls (#38291) Currently the `getInheritedFactory` function is implemented to allow closure to remove the call if the base factory is unused. However, this method does not work with terser. By adding the PURE annotation, terser will also be able to remove the call when unused. PR Close #38291 --- integration/ngcc/test.sh | 4 ++-- packages/compiler-cli/test/ngtsc/ngtsc_spec.ts | 6 ++++-- packages/compiler/src/output/output_ast.ts | 5 +++-- packages/compiler/src/render3/r3_factory.ts | 4 +++- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/integration/ngcc/test.sh b/integration/ngcc/test.sh index aea0d8ea53..93448d1db3 100755 --- a/integration/ngcc/test.sh +++ b/integration/ngcc/test.sh @@ -104,10 +104,10 @@ assertSucceeded "Expected 'ngcc' to log 'Compiling'." # Did it generate a base factory call for synthesized constructors correctly? - grep "const ɵMatTable_BaseFactory = ɵngcc0.ɵɵgetInheritedFactory(MatTable);" node_modules/@angular/material/esm2015/table/table.js + grep "const ɵMatTable_BaseFactory = /\*@__PURE__\*/ ɵngcc0.ɵɵgetInheritedFactory(MatTable);" node_modules/@angular/material/esm2015/table/table.js assertSucceeded "Expected 'ngcc' to generate a base factory for 'MatTable' in '@angular/material' (esm2015)." - grep "var ɵMatTable_BaseFactory = ɵngcc0.ɵɵgetInheritedFactory(MatTable);" node_modules/@angular/material/esm5/table/table.js + grep "var ɵMatTable_BaseFactory = /\*@__PURE__\*/ ɵngcc0.ɵɵgetInheritedFactory(MatTable);" node_modules/@angular/material/esm5/table/table.js assertSucceeded "Expected 'ngcc' to generate a base factory for 'MatTable' in '@angular/material' (esm5)." diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 6e6848a80d..886e364fbc 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -3822,7 +3822,8 @@ runInEachFileSystem(os => { expect(jsContents) .toContain('function Base_Factory(t) { return new (t || Base)(i0.ɵɵinject(Dep)); }'); - expect(jsContents).toContain('var \u0275Child_BaseFactory = i0.ɵɵgetInheritedFactory(Child)'); + expect(jsContents) + .toContain('var \u0275Child_BaseFactory = /*@__PURE__*/ i0.ɵɵgetInheritedFactory(Child)'); expect(jsContents) .toContain('function Child_Factory(t) { return \u0275Child_BaseFactory(t || Child); }'); expect(jsContents) @@ -3849,7 +3850,8 @@ runInEachFileSystem(os => { env.driveMain(); const jsContents = env.getContents('test.js'); - expect(jsContents).toContain('var \u0275Dir_BaseFactory = i0.ɵɵgetInheritedFactory(Dir)'); + expect(jsContents) + .toContain('var \u0275Dir_BaseFactory = /*@__PURE__*/ i0.ɵɵgetInheritedFactory(Dir)'); }); it('should wrap "directives" in component metadata in a closure when forward references are present', diff --git a/packages/compiler/src/output/output_ast.ts b/packages/compiler/src/output/output_ast.ts index 7a3465447a..dfac81e170 100644 --- a/packages/compiler/src/output/output_ast.ts +++ b/packages/compiler/src/output/output_ast.ts @@ -176,8 +176,9 @@ export abstract class Expression { return new InvokeMethodExpr(this, name, params, null, sourceSpan); } - callFn(params: Expression[], sourceSpan?: ParseSourceSpan|null): InvokeFunctionExpr { - return new InvokeFunctionExpr(this, params, null, sourceSpan); + callFn(params: Expression[], sourceSpan?: ParseSourceSpan|null, pure?: boolean): + InvokeFunctionExpr { + return new InvokeFunctionExpr(this, params, null, sourceSpan, pure); } instantiate(params: Expression[], type?: Type|null, sourceSpan?: ParseSourceSpan|null): diff --git a/packages/compiler/src/render3/r3_factory.ts b/packages/compiler/src/render3/r3_factory.ts index fe2f6d2073..c1cb7c923b 100644 --- a/packages/compiler/src/render3/r3_factory.ts +++ b/packages/compiler/src/render3/r3_factory.ts @@ -212,7 +212,9 @@ export function compileFactoryFunction(meta: R3FactoryMetadata): R3FactoryFn { const baseFactory = o.variable(`ɵ${meta.name}_BaseFactory`); const getInheritedFactory = o.importExpr(R3.getInheritedFactory); const baseFactoryStmt = - baseFactory.set(getInheritedFactory.callFn([meta.internalType])) + baseFactory + .set(getInheritedFactory.callFn( + [meta.internalType], /* sourceSpan */ undefined, /* pure */ true)) .toDeclStmt(o.INFERRED_TYPE, [o.StmtModifier.Exported, o.StmtModifier.Final]); statements.push(baseFactoryStmt);