fix(ngcc): render adjacent statements after static properties (#33630)

See https://github.com/angular/angular/pull/33337#issuecomment-545487737

Fixes FW-1664

PR Close #33630
This commit is contained in:
Pete Bacon Darwin
2019-11-06 17:03:56 +00:00
committed by atscott
parent 7b87392f47
commit fe12d0dc78
11 changed files with 398 additions and 62 deletions

View File

@ -100,6 +100,30 @@ export class EsmRenderingFormatter implements RenderingFormatter {
output.appendLeft(insertionPoint, '\n' + definitions);
}
/**
* Add the adjacent statements after all static properties of the class.
*/
addAdjacentStatements(output: MagicString, compiledClass: CompiledClass, statements: string):
void {
const classSymbol = this.host.getClassSymbol(compiledClass.declaration);
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);
}
/**
* Remove static decorator properties from classes.
*/
@ -244,3 +268,21 @@ 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;
}