Skip to content

Commit a8f28e9

Browse files
wagnermacielmmalerba
authored andcommitted
refactor(material/schematics): change strategy for applying updates (#24588)
* simplify TemplateMigrator logic * update CardTemplateMigrator impl * changed from using a two-pass strategy for gathering context then applying updates to using a one-pass approach which stores updates, sorts them in reverse order, then applies updates in one go * all existing unit tests pass
1 parent bcacdde commit a8f28e9

File tree

3 files changed

+36
-35
lines changed

3 files changed

+36
-35
lines changed

src/material/schematics/ng-generate/mdc-migration/rules/components/card/card-template.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,23 @@
77
*/
88

99
import {TmplAstElement} from '@angular/compiler';
10-
import {TemplateMigrator} from '../../template-migrator';
10+
import {TemplateMigrator, Update} from '../../template-migrator';
1111
import {addAttribute} from '../../tree-traversal';
1212

1313
export class CardTemplateMigrator extends TemplateMigrator {
1414
component = 'card';
1515
tagName = 'mat-card';
1616

17-
override updateStartTag(template: string, node: TmplAstElement): string {
17+
getUpdates(node: TmplAstElement): Update[] {
1818
if (node.name !== this.tagName) {
19-
return template;
19+
return [];
2020
}
21-
return addAttribute(template, node, 'appearance', 'outlined');
21+
22+
return [
23+
{
24+
location: node.startSourceSpan.end,
25+
updateFn: html => addAttribute(html, node, 'appearance', 'outlined'),
26+
},
27+
];
2228
}
2329
}

src/material/schematics/ng-generate/mdc-migration/rules/template-migration.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,27 @@ import {Migration, ResolvedResource} from '@angular/cdk/schematics';
1010
import {SchematicContext} from '@angular-devkit/schematics';
1111
import {visitElements, parseTemplate} from './tree-traversal';
1212
import {ComponentMigrator} from '.';
13+
import {Update} from './template-migrator';
1314

1415
export class TemplateMigration extends Migration<ComponentMigrator[], SchematicContext> {
1516
enabled = true;
1617

1718
override visitTemplate(template: ResolvedResource) {
1819
const ast = parseTemplate(template.content, template.filePath);
1920
const migrators = this.upgradeData.filter(m => m.template).map(m => m.template!);
21+
const updates: Update[] = [];
2022

21-
visitElements(
22-
ast.nodes,
23-
node => {
24-
migrators.forEach(m => {
25-
template.content = m.updateEndTag(template.content, node);
26-
});
27-
},
28-
node => {
29-
migrators.forEach(m => {
30-
template.content = m.updateStartTag(template.content, node);
31-
});
32-
},
33-
);
23+
visitElements(ast.nodes, node => {
24+
for (let i = 0; i < migrators.length; i++) {
25+
updates.push(...migrators[i].getUpdates(node));
26+
}
27+
});
28+
29+
updates.sort((a, b) => b.location.offset - a.location.offset);
30+
31+
updates.forEach(update => {
32+
template.content = update.updateFn(template.content);
33+
});
3434

3535
this.fileSystem.overwrite(template.filePath, template.content);
3636
}

src/material/schematics/ng-generate/mdc-migration/rules/template-migrator.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88

99
import * as compiler from '@angular/compiler';
1010

11+
/** Stores the data needed to make a template update. */
12+
export interface Update {
13+
/** The location of the update. */
14+
location: compiler.ParseLocation;
15+
16+
/** A function to be used to update the template. */
17+
updateFn: (html: string) => string;
18+
}
19+
1120
export abstract class TemplateMigrator {
1221
/** The name of the component that this migration handles. */
1322
abstract component: string;
@@ -16,24 +25,10 @@ export abstract class TemplateMigrator {
1625
abstract tagName: string;
1726

1827
/**
19-
* Updates the start tag of the given node in the html template.
20-
*
21-
* @param template The html content to be updated.
22-
* @param node The Element node to be updated.
23-
* @returns The updated template.
24-
*/
25-
updateEndTag(template: string, node: compiler.TmplAstElement): string {
26-
return template;
27-
}
28-
29-
/**
30-
* Updates the end tag of the given node in the html template.
28+
* Returns the data needed to update the given node.
3129
*
32-
* @param template The html content to be updated.
33-
* @param node The Element node to be updated.
34-
* @returns The updated template.
30+
* @param node A template ast element.
31+
* @returns The data needed to update this node.
3532
*/
36-
updateStartTag(template: string, node: compiler.TmplAstElement): string {
37-
return template;
38-
}
33+
abstract getUpdates(node: compiler.TmplAstElement): Update[];
3934
}

0 commit comments

Comments
 (0)