fix(ngcc): insert definitions after statement (#34677)
If a class was defined as a class expression in a variable declaration, the definitions were being inserted before the statment's final semi-colon. Now the insertion point will be after the full statement. Fixes #34648 PR Close #34677
This commit is contained in:
parent
9f65b787d0
commit
8815ace418
|
@ -102,7 +102,8 @@ export class EsmRenderingFormatter implements RenderingFormatter {
|
||||||
if (!classSymbol) {
|
if (!classSymbol) {
|
||||||
throw new Error(`Compiled class does not have a valid symbol: ${compiledClass.name}`);
|
throw new Error(`Compiled class does not have a valid symbol: ${compiledClass.name}`);
|
||||||
}
|
}
|
||||||
const insertionPoint = classSymbol.declaration.valueDeclaration.getEnd();
|
const declarationStatement = getDeclarationStatement(classSymbol.declaration.valueDeclaration);
|
||||||
|
const insertionPoint = declarationStatement.getEnd();
|
||||||
output.appendLeft(insertionPoint, '\n' + definitions);
|
output.appendLeft(insertionPoint, '\n' + definitions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +274,18 @@ export class EsmRenderingFormatter implements RenderingFormatter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function findStatement(node: ts.Node) {
|
function getDeclarationStatement(node: ts.Node): ts.Statement {
|
||||||
|
let statement = node;
|
||||||
|
while (statement) {
|
||||||
|
if (ts.isVariableStatement(statement) || ts.isClassDeclaration(statement)) {
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
statement = statement.parent;
|
||||||
|
}
|
||||||
|
throw new Error(`Class is not defined in a declaration statement: ${node.getText()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function findStatement(node: ts.Node): ts.Statement|undefined {
|
||||||
while (node) {
|
while (node) {
|
||||||
if (ts.isExpressionStatement(node) || ts.isReturnStatement(node)) {
|
if (ts.isExpressionStatement(node) || ts.isReturnStatement(node)) {
|
||||||
return node;
|
return node;
|
||||||
|
|
|
@ -74,10 +74,12 @@ B.decorators = [
|
||||||
{ type: OtherB },
|
{ type: OtherB },
|
||||||
{ type: Directive, args: [{ selector: '[b]' }] }
|
{ type: Directive, args: [{ selector: '[b]' }] }
|
||||||
];
|
];
|
||||||
export class C {}
|
var C_1;
|
||||||
|
let C = C_1 = class C {};
|
||||||
C.decorators = [
|
C.decorators = [
|
||||||
{ type: Directive, args: [{ selector: '[c]' }] },
|
{ type: Directive, args: [{ selector: '[c]' }] },
|
||||||
];
|
];
|
||||||
|
export C;
|
||||||
let compileNgModuleFactory = compileNgModuleFactory__PRE_R3__;
|
let compileNgModuleFactory = compileNgModuleFactory__PRE_R3__;
|
||||||
let badlyFormattedVariable = __PRE_R3__badlyFormattedVariable;
|
let badlyFormattedVariable = __PRE_R3__badlyFormattedVariable;
|
||||||
|
|
||||||
|
@ -220,6 +222,20 @@ export class A {`);
|
||||||
export class A {}
|
export class A {}
|
||||||
SOME DEFINITION TEXT
|
SOME DEFINITION TEXT
|
||||||
A.decorators = [
|
A.decorators = [
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should insert the definitions after the variable declaration of class expressions',
|
||||||
|
() => {
|
||||||
|
const {renderer, decorationAnalyses, sourceFile} = setup([PROGRAM]);
|
||||||
|
const output = new MagicString(PROGRAM.contents);
|
||||||
|
const compiledClass =
|
||||||
|
decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !;
|
||||||
|
renderer.addDefinitions(output, compiledClass, 'SOME DEFINITION TEXT');
|
||||||
|
expect(output.toString()).toContain(`
|
||||||
|
let C = C_1 = class C {};
|
||||||
|
SOME DEFINITION TEXT
|
||||||
|
C.decorators = [
|
||||||
`);
|
`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue