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
This commit is contained in:
Pete Bacon Darwin
2019-11-08 11:01:26 +00:00
committed by Kara Erickson
parent f67802ddc0
commit c5400616f8
9 changed files with 172 additions and 52 deletions

View File

@ -109,19 +109,8 @@ export class EsmRenderingFormatter implements RenderingFormatter {
if (!classSymbol) {
throw new Error(`Compiled class does not have a valid symbol: ${compiledClass.name}`);
}
let insertionPoint = classSymbol.declaration.valueDeclaration.getEnd();
// If there are static members on this class then insert after the last one
if (classSymbol.declaration.exports !== undefined) {
classSymbol.declaration.exports.forEach(exportSymbol => {
const exportStatement = getContainingStatement(exportSymbol);
if (exportStatement !== null) {
insertionPoint = Math.max(insertionPoint, exportStatement.getEnd());
}
});
}
output.appendLeft(insertionPoint, '\n' + statements);
const endOfClass = this.host.getEndOfClass(classSymbol);
output.appendLeft(endOfClass.getEnd(), '\n' + statements);
}
/**
@ -268,21 +257,3 @@ function getNextSiblingInArray<T extends ts.Node>(node: T, array: ts.NodeArray<T
const index = array.indexOf(node);
return index !== -1 && array.length > index + 1 ? array[index + 1] : null;
}
/**
* Find the statement that contains the given class member
* @param symbol the symbol of a static member of a class
*/
function getContainingStatement(symbol: ts.Symbol): ts.ExpressionStatement|null {
if (symbol.valueDeclaration === undefined) {
return null;
}
let node: ts.Node|null = symbol.valueDeclaration;
while (node) {
if (ts.isExpressionStatement(node)) {
break;
}
node = node.parent;
}
return node || null;
}