fix(ngcc): better detection of end of decorator expression (#33192)
for removal of decorator from __decorate calls. FW-1629 #resolve PR Close #33192
This commit is contained in:
parent
4da2dda647
commit
50710838bf
|
@ -99,9 +99,17 @@ export class EsmRenderingFormatter implements RenderingFormatter {
|
||||||
} else {
|
} else {
|
||||||
nodesToRemove.forEach(node => {
|
nodesToRemove.forEach(node => {
|
||||||
// remove any trailing comma
|
// remove any trailing comma
|
||||||
const end = (output.slice(node.getEnd(), node.getEnd() + 1) === ',') ?
|
const nextSibling = getNextSiblingInArray(node, items);
|
||||||
node.getEnd() + 1 :
|
let end: number;
|
||||||
node.getEnd();
|
|
||||||
|
if (nextSibling !== null &&
|
||||||
|
output.slice(nextSibling.getFullStart() - 1, nextSibling.getFullStart()) === ',') {
|
||||||
|
end = nextSibling.getFullStart() - 1 + nextSibling.getLeadingTriviaWidth();
|
||||||
|
} else if (output.slice(node.getEnd(), node.getEnd() + 1) === ',') {
|
||||||
|
end = node.getEnd() + 1;
|
||||||
|
} else {
|
||||||
|
end = node.getEnd();
|
||||||
|
}
|
||||||
output.remove(node.getFullStart(), end);
|
output.remove(node.getFullStart(), end);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -214,3 +222,8 @@ function generateImportString(
|
||||||
const importAs = importPath ? importManager.generateNamedImport(importPath, importName) : null;
|
const importAs = importPath ? importManager.generateNamedImport(importPath, importName) : null;
|
||||||
return importAs ? `${importAs.moduleImport}.${importAs.symbol}` : `${importName}`;
|
return importAs ? `${importAs.moduleImport}.${importAs.symbol}` : `${importName}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNextSiblingInArray<T extends ts.Node>(node: T, array: ts.NodeArray<T>): T|null {
|
||||||
|
const index = array.indexOf(node);
|
||||||
|
return index !== -1 && array.length > index + 1 ? array[index + 1] : null;
|
||||||
|
}
|
||||||
|
|
|
@ -288,6 +288,28 @@ A.decorators = [
|
||||||
.toContain(`{ type: Directive, args: [{ selector: '[c]' }] }`);
|
.toContain(`{ type: Directive, args: [{ selector: '[c]' }] }`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should handle a decorator with a trailing comment', () => {
|
||||||
|
const text = `
|
||||||
|
import {Directive} from '@angular/core';
|
||||||
|
export class A {}
|
||||||
|
A.decorators = [
|
||||||
|
{ type: Directive, args: [{ selector: '[a]' }] },
|
||||||
|
{ type: OtherA }
|
||||||
|
];
|
||||||
|
`;
|
||||||
|
const file = {name: _('/node_modules/test-package/index.js'), contents: text};
|
||||||
|
const {decorationAnalyses, sourceFile, renderer} = setup([file]);
|
||||||
|
const output = new MagicString(text);
|
||||||
|
const compiledClass =
|
||||||
|
decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !;
|
||||||
|
const decorator = compiledClass.decorators ![0];
|
||||||
|
const decoratorsToRemove = new Map<ts.Node, ts.Node[]>();
|
||||||
|
decoratorsToRemove.set(decorator.node.parent !, [decorator.node]);
|
||||||
|
renderer.removeDecorators(output, decoratorsToRemove);
|
||||||
|
// The decorator should have been removed correctly.
|
||||||
|
expect(output.toString()).toContain('A.decorators = [ { type: OtherA }');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should delete the decorator (and its container if there are no other decorators left) that was matched in the analysis',
|
it('should delete the decorator (and its container if there are no other decorators left) that was matched in the analysis',
|
||||||
() => {
|
() => {
|
||||||
|
|
Loading…
Reference in New Issue