fix(ivy): make metadata calls side-effect free in Closure (#29947)

When compiling Angular classes, the compiler may decide to append statements with specific metadata that's only required for JIT. This includes things like decorator metadata as well as NgModule scope data.

When the compiler generates such calls, the call sites are marked with Uglify's PURE annotation, so the optimizer will remove them in production builds. However, Closure does not have the PURE (or similar) annotation. We have a utility function `noSideEffects` in the runtime for this purpose. This commit wraps `setClassMetadata` and `setNgModuleScope` function bodies in `noSideEffect` closures to allow Closure remove them.

PR Close #29947
This commit is contained in:
Andrew Kushnir 2019-04-16 18:11:28 -07:00 committed by Ben Lesh
parent 5fee9daa5b
commit 696e520842
2 changed files with 40 additions and 35 deletions

View File

@ -402,10 +402,12 @@ export function ɵɵsetNgModuleScope(type: any, scope: {
*/
exports?: Type<any>[] | (() => Type<any>[]);
}): void {
return noSideEffects(() => {
const ngModuleDef = getNgModuleDef(type, true);
ngModuleDef.declarations = scope.declarations || EMPTY_ARRAY;
ngModuleDef.imports = scope.imports || EMPTY_ARRAY;
ngModuleDef.exports = scope.exports || EMPTY_ARRAY;
}) as never;
}
/**

View File

@ -7,6 +7,7 @@
*/
import {Type} from '../interface/type';
import {noSideEffects} from '../util/closure';
interface TypeWithMetadata extends Type<any> {
decorators?: any[];
@ -26,6 +27,7 @@ interface TypeWithMetadata extends Type<any> {
export function setClassMetadata(
type: Type<any>, decorators: any[] | null, ctorParameters: (() => any[]) | null,
propDecorators: {[field: string]: any} | null): void {
return noSideEffects(() => {
const clazz = type as TypeWithMetadata;
// We determine whether a class has its own metadata by taking the metadata from the parent
@ -61,4 +63,5 @@ export function setClassMetadata(
clazz.propDecorators = propDecorators;
}
}
}) as never;
}