fix(migrations): Do not remove a template if it is referenced even with a trailing semilocon

This commit fixes a behavior where under certain conditions, the migration script ignored
a template reference with a trailing semicolon and incorrectly removed the definition
of a referenced template.

Fixes #64741

(cherry picked from commit 64cb08529d)
This commit is contained in:
Lukas Matta 2025-10-29 00:14:57 +01:00 committed by Kristiyan Kostadinov
parent feac577414
commit 95344c19f3
2 changed files with 47 additions and 1 deletions

View file

@ -520,7 +520,7 @@ function analyzeTemplateUsage(nodes: any[], templateName: string): TemplateUsage
for (const attr of node.attrs) {
if (
(attr.name === '*ngTemplateOutlet' || attr.name === '[ngTemplateOutlet]') &&
attr.value === templateName
attr.value?.split(';')[0] === templateName
) {
isReferencedInTemplateOutlet = true;
}

View file

@ -1395,6 +1395,52 @@ describe('control flow migration (ng update)', () => {
);
});
it('should migrate but not remove ng-templates when referenced elsewhere with a trailing semicolon', async () => {
writeFile(
'/comp.ts',
`
import {Component} from '@angular/core';
import {NgIf} from '@angular/common';
@Component({
templateUrl: './comp.html'
})
class Comp {
show = false;
}
`,
);
writeFile(
'/comp.html',
[
`<div>`,
`<span *ngIf="show; then thenBlock; else elseBlock">Ignored</span>`,
`<ng-template #thenBlock><div>THEN Stuff</div></ng-template>`,
`<ng-template #elseBlock>Else Content</ng-template>`,
`</div>`,
`<ng-container *ngTemplateOutlet="elseBlock;"></ng-container>`,
].join('\n'),
);
await runMigration();
const content = tree.readContent('/comp.html');
expect(content).toBe(
[
`<div>`,
` @if (show) {`,
` <div>THEN Stuff</div>`,
` } @else {`,
` Else Content`,
` }`,
` <ng-template #elseBlock>Else Content</ng-template>`,
`</div>`,
`<ng-container *ngTemplateOutlet="elseBlock;"></ng-container>`,
].join('\n'),
);
});
it('should not remove ng-templates used by other directives', async () => {
writeFile(
'/comp.ts',