Files
angular/packages/compiler-cli/ngcc/src/rendering/esm5_rendering_formatter.ts
Pete Bacon Darwin c5400616f8 fix(ngcc): ensure that adjacent statements go after helper calls (#33689)
Previously the renderers were fixed so that they inserted extra
"adjacent" statements after the last static property of classes.

In order to help the build-optimizer (in Angular CLI) to be able to
tree-shake classes effectively, these statements should also appear
after any helper calls, such as `__decorate()`.

This commit moves the computation of this positioning into the
`NgccReflectionHost` via the `getEndOfClass()` method, which
returns the last statement that is related to the class.

FW-1668

PR Close #33689
2019-11-11 13:01:15 -08:00

39 lines
1.5 KiB
TypeScript

/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import MagicString from 'magic-string';
import * as ts from 'typescript';
import {CompiledClass} from '../analysis/types';
import {getIifeBody} from '../host/esm5_host';
import {EsmRenderingFormatter} from './esm_rendering_formatter';
/**
* A RenderingFormatter that works with files that use ECMAScript Module `import` and `export`
* statements, but instead of `class` declarations it uses ES5 `function` wrappers for classes.
*/
export class Esm5RenderingFormatter extends EsmRenderingFormatter {
/**
* Add the definitions inside the IIFE of each decorated class
*/
addDefinitions(output: MagicString, compiledClass: CompiledClass, definitions: string): void {
const iifeBody = getIifeBody(compiledClass.declaration);
if (!iifeBody) {
throw new Error(
`Compiled class declaration is not inside an IIFE: ${compiledClass.name} in ${compiledClass.declaration.getSourceFile().fileName}`);
}
const returnStatement = iifeBody.statements.find(ts.isReturnStatement);
if (!returnStatement) {
throw new Error(
`Compiled class wrapper IIFE does not have a return statement: ${compiledClass.name} in ${compiledClass.declaration.getSourceFile().fileName}`);
}
const insertionPoint = returnStatement.getFullStart();
output.appendLeft(insertionPoint, '\n' + definitions);
}
}