Skip to content

Commit d388adf

Browse files
wagnermacielmmalerba
authored andcommitted
feat(material/schematics): create updateNamedImport ts migration fn (#25132)
1 parent c682965 commit d388adf

File tree

2 files changed

+82
-6
lines changed

2 files changed

+82
-6
lines changed

src/material/schematics/migration-utilities/typescript/import-operations.spec.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as ts from 'typescript';
2-
import {updateModuleSpecifier} from './import-operations';
2+
import {updateModuleSpecifier, updateNamedImport} from './import-operations';
33

44
describe('import operations', () => {
55
describe('updateModuleSpecifier', () => {
@@ -39,6 +39,51 @@ describe('import operations', () => {
3939
});
4040
});
4141
});
42+
43+
describe('updateNamedExport', () => {
44+
function runUpdateNamedExportTest(
45+
description: string,
46+
opts: {
47+
oldFile: string;
48+
newFile: string;
49+
oldExport: string;
50+
newExport: string;
51+
},
52+
): void {
53+
const node = createNode(opts.oldFile, ts.SyntaxKind.NamedImports) as ts.NamedImports;
54+
const newImport = updateNamedImport(node, {
55+
oldExport: opts.oldExport,
56+
newExport: opts.newExport,
57+
})?.updateFn(opts.oldFile);
58+
expect(newImport).withContext(description).toBe(opts.newFile);
59+
}
60+
it('updates the named exports of import declarations', () => {
61+
runUpdateNamedExportTest('named binding', {
62+
oldExport: 'oldExport',
63+
newExport: 'newExport',
64+
oldFile: `import { oldExport } from 'module-name';`,
65+
newFile: `import { newExport } from 'module-name';`,
66+
});
67+
runUpdateNamedExportTest('aliased named binding', {
68+
oldExport: 'oldExport',
69+
newExport: 'newExport',
70+
oldFile: `import { oldExport as alias } from 'module-name';`,
71+
newFile: `import { newExport as alias } from 'module-name';`,
72+
});
73+
runUpdateNamedExportTest('multiple named bindings', {
74+
oldExport: 'oldExport1',
75+
newExport: 'newExport1',
76+
oldFile: `import { oldExport1, export2 } from 'module-name';`,
77+
newFile: `import { newExport1, export2 } from 'module-name';`,
78+
});
79+
runUpdateNamedExportTest('multiple named bindings w/ alias', {
80+
oldExport: 'oldExport2',
81+
newExport: 'newExport2',
82+
oldFile: `import { export1, oldExport2 as alias2 } from 'module-name';`,
83+
newFile: `import { export1, newExport2 as alias2 } from 'module-name';`,
84+
});
85+
});
86+
});
4287
});
4388

4489
function createSourceFile(text: string): ts.SourceFile {

src/material/schematics/migration-utilities/typescript/import-operations.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,42 @@ export function updateModuleSpecifier(
2121
offset: moduleSpecifier.pos,
2222
updateFn: (text: string) => {
2323
const index = text.indexOf(moduleSpecifier.text, moduleSpecifier.pos);
24-
return (
25-
text.slice(0, index) +
26-
opts.moduleSpecifier +
27-
text.slice(index + moduleSpecifier.text.length)
28-
);
24+
return replaceAt(text, index, {
25+
old: moduleSpecifier.text,
26+
new: opts.moduleSpecifier,
27+
});
2928
},
3029
};
3130
}
31+
32+
/** Returns an Update that renames an export of the given named import node. */
33+
export function updateNamedImport(
34+
node: ts.NamedImports,
35+
opts: {
36+
oldExport: string;
37+
newExport: string;
38+
},
39+
): Update | undefined {
40+
for (let i = 0; i < node.elements.length; i++) {
41+
const n = node.elements[i];
42+
const name = n.propertyName ? n.propertyName : n.name;
43+
if (name.escapedText === opts.oldExport) {
44+
return {
45+
offset: name.pos,
46+
updateFn: (text: string) => {
47+
const index = text.indexOf(opts.oldExport, name.pos);
48+
return replaceAt(text, index, {
49+
old: opts.oldExport,
50+
new: opts.newExport,
51+
});
52+
},
53+
};
54+
}
55+
}
56+
return;
57+
}
58+
59+
/** Replaces the first instance of substring.old after the given index. */
60+
function replaceAt(str: string, index: number, substring: {old: string; new: string}): string {
61+
return str.slice(0, index) + substring.new + str.slice(index + substring.old.length);
62+
}

0 commit comments

Comments
 (0)