Skip to content

Commit cf5c61c

Browse files
aparzialxhub
authored andcommitted
fix(core): fix used templates are not deleted (#60459)
After running the control flow migration, used templates are not deleted. PR Close #60459
1 parent d95d352 commit cf5c61c

File tree

2 files changed

+73
-12
lines changed

2 files changed

+73
-12
lines changed

packages/core/schematics/ng-generate/control-flow-migration/util.ts

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,6 @@ export function calculateNesting(
385385
}
386386
}
387387

388-
function escapeRegExp(val: string) {
389-
return val.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
390-
}
391-
392388
/**
393389
* determines if a given template string contains line breaks
394390
*/
@@ -425,20 +421,48 @@ export function getTemplates(template: string): Map<string, Template> {
425421
const visitor = new TemplateCollector();
426422
visitAll(visitor, parsed.tree.rootNodes);
427423

428-
// count usages of each ng-template
429424
for (let [key, tmpl] of visitor.templates) {
430-
const escapeKey = escapeRegExp(key.slice(1));
431-
const regex = new RegExp(`[^a-zA-Z0-9-<(\']${escapeKey}\\W`, 'gm');
432-
const matches = template.match(regex);
433-
tmpl.count = matches?.length ?? 0;
425+
tmpl.count = countTemplateUsage(parsed.tree.rootNodes, key);
434426
tmpl.generateContents(template);
435427
}
436-
437428
return visitor.templates;
438429
}
439430
return new Map<string, Template>();
440431
}
441432

433+
function countTemplateUsage(nodes: any[], templateName: string): number {
434+
let count = 0;
435+
let isReferencedInTemplateOutlet = false;
436+
437+
for (const node of nodes) {
438+
if (node.attrs) {
439+
for (const attr of node.attrs) {
440+
if (attr.name === '*ngTemplateOutlet' && attr.value === templateName.slice(1)) {
441+
isReferencedInTemplateOutlet = true;
442+
break;
443+
}
444+
445+
if (attr.name.trim() === templateName) {
446+
count++;
447+
}
448+
}
449+
}
450+
451+
if (node.children) {
452+
if (node.name === 'for') {
453+
for (const child of node.children) {
454+
if (child.value?.includes(templateName.slice(1))) {
455+
count++;
456+
}
457+
}
458+
}
459+
count += countTemplateUsage(node.children, templateName);
460+
}
461+
}
462+
463+
return isReferencedInTemplateOutlet ? count + 2 : count;
464+
}
465+
442466
export function updateTemplates(
443467
template: string,
444468
templates: Map<string, Template>,
@@ -497,8 +521,12 @@ export function processNgTemplates(
497521
} else {
498522
template = template.replace(replaceRegex, t.children);
499523
}
500-
// the +1 accounts for the t.count's counting of the original template
501-
if (t.count === matches.length + 1 && safeToRemove) {
524+
525+
const dist = matches.filter(
526+
(obj, index, self) => index === self.findIndex((t) => t.input === obj.input),
527+
);
528+
529+
if ((t.count === dist.length || t.count - matches.length === 1) && safeToRemove) {
502530
const refsInComponentFile = getViewChildOrViewChildrenNames(sourceFile);
503531
if (refsInComponentFile?.length > 0) {
504532
const templateRefs = getTemplateReferences(template);

packages/core/schematics/test/control_flow_migration_spec.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6932,5 +6932,38 @@ describe('control flow migration', () => {
69326932
const content = tree.readContent('/comp.ts');
69336933
expect(content).not.toContain('<ng-template #contentTemplate>');
69346934
});
6935+
6936+
it('should remove ng-template reference when use in if-else block', async () => {
6937+
writeFile(
6938+
'/comp.ts',
6939+
`
6940+
import {Component} from '@angular/core';
6941+
6942+
@Component({
6943+
templateUrl: './comp.html'
6944+
})
6945+
class Comp {
6946+
}
6947+
`,
6948+
);
6949+
6950+
writeFile(
6951+
'/comp.html',
6952+
[
6953+
`<div>`,
6954+
`<div *ngIf="param; else loading">`,
6955+
`<div>content</div>`,
6956+
`</div>`,
6957+
`<ng-template #loading>`,
6958+
`<div>loading</div>`,
6959+
`</ng-template>`,
6960+
`</div>`,
6961+
].join('\n'),
6962+
);
6963+
6964+
await runMigration();
6965+
const content = tree.readContent('/comp.html');
6966+
expect(content).not.toContain('<ng-template #loading>');
6967+
});
69356968
});
69366969
});

0 commit comments

Comments
 (0)