Skip to content

Commit a857933

Browse files
committed
Ensure moved files don't result in broken imports
1 parent cd2980d commit a857933

File tree

4 files changed

+116
-10
lines changed

4 files changed

+116
-10
lines changed

packages/tsserver-plugin/__tests__/integration.test.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,117 @@ describe('tsserver plugin', () => {
12881288
});
12891289
});
12901290

1291+
describe('renaming files', () => {
1292+
test('moving a transformed file updates its imports', async () => {
1293+
await project.open({
1294+
'dir/greeting.ts': stripIndent`
1295+
import Component, { hbs } from '@glimmerx/component';
1296+
1297+
export interface GreetingArgs {
1298+
message: string;
1299+
}
1300+
1301+
export default class Greeting extends Component<GreetingArgs> {
1302+
static template = hbs\`{{@message}}, World!\`;
1303+
}
1304+
`,
1305+
'dir/index.ts': stripIndent`
1306+
import Component, { hbs } from '@glimmerx/component';
1307+
import Greeting from './greeting';
1308+
1309+
export class Application extends Component {
1310+
static template = hbs\`
1311+
<Greeting @message="Hello" />
1312+
\`;
1313+
}
1314+
`,
1315+
});
1316+
1317+
let greetingMoveResult = await server.request(CommandTypes.GetEditsForFileRename, {
1318+
oldFilePath: project.filePath('dir/greeting.ts'),
1319+
newFilePath: project.filePath('other/greeting.ts'),
1320+
});
1321+
1322+
expect(greetingMoveResult).toMatchObject([
1323+
{
1324+
fileName: project.filePath('dir/index.ts'),
1325+
textChanges: [
1326+
{
1327+
start: { line: 2, offset: 23 },
1328+
end: { line: 2, offset: 33 },
1329+
newText: '../other/greeting',
1330+
},
1331+
],
1332+
},
1333+
]);
1334+
1335+
let indexMoveResult = await server.request(CommandTypes.GetEditsForFileRename, {
1336+
oldFilePath: project.filePath('dir/index.ts'),
1337+
newFilePath: project.filePath('other/index.ts'),
1338+
});
1339+
1340+
expect(indexMoveResult).toMatchObject([
1341+
{
1342+
fileName: project.filePath('dir/index.ts'),
1343+
textChanges: [
1344+
{
1345+
start: { line: 2, offset: 23 },
1346+
end: { line: 2, offset: 33 },
1347+
newText: '../dir/greeting',
1348+
},
1349+
],
1350+
},
1351+
]);
1352+
});
1353+
1354+
test('moving an untransformed file updates its imports', async () => {
1355+
await project.open({
1356+
'dir/foo.ts': stripIndent`
1357+
export const message = 'hello';
1358+
`,
1359+
'dir/index.ts': stripIndent`
1360+
export { message } from './foo';
1361+
`,
1362+
});
1363+
1364+
let greetingMoveResult = await server.request(CommandTypes.GetEditsForFileRename, {
1365+
oldFilePath: project.filePath('dir/foo.ts'),
1366+
newFilePath: project.filePath('other/foo.ts'),
1367+
});
1368+
1369+
expect(greetingMoveResult).toMatchObject([
1370+
{
1371+
fileName: project.filePath('dir/index.ts'),
1372+
textChanges: [
1373+
{
1374+
start: { line: 1, offset: 26 },
1375+
end: { line: 1, offset: 31 },
1376+
newText: '../other/foo',
1377+
},
1378+
],
1379+
},
1380+
]);
1381+
1382+
let indexMoveResult = await server.request(CommandTypes.GetEditsForFileRename, {
1383+
oldFilePath: project.filePath('dir/index.ts'),
1384+
newFilePath: project.filePath('other/index.ts'),
1385+
});
1386+
1387+
expect(indexMoveResult).toMatchObject([
1388+
{
1389+
fileName: project.filePath('dir/index.ts'),
1390+
textChanges: [
1391+
{
1392+
start: { line: 1, offset: 26 },
1393+
end: { line: 1, offset: 31 },
1394+
newText: '../dir/foo',
1395+
},
1396+
],
1397+
},
1398+
]);
1399+
});
1400+
});
1401+
12911402
describe('error recovery', () => {
12921403
test('introducing and fixing a template error with editor changes', async () => {
12931404
await project.open({

packages/tsserver-plugin/__tests__/test-server.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ export class Project {
116116

117117
if (!this.openFiles.has(file)) {
118118
if (!fs.existsSync(file)) {
119+
fs.mkdirSync(path.dirname(file), { recursive: true });
119120
fs.writeFileSync(file, fileContent ?? '');
120121
}
121122

packages/tsserver-plugin/src/index.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,10 @@ const init: ts.server.PluginModuleFactory = ({ typescript: ts }) => {
1414
return {
1515
create(info) {
1616
let logger = loggerFor(info);
17-
let config = loadConfig(path.dirname(info.project.projectName));
17+
let projectDir = path.dirname(info.project.projectName);
18+
let config = loadConfig(projectDir);
1819

19-
logger.log('\nStarting @glint/tsserver-plugin at', new Date().toString());
20+
logger.log('\nStarting @glint/tsserver-plugin in', projectDir, 'at', new Date().toString());
2021

2122
modules.addProject(config, info.project);
2223

packages/tsserver-plugin/src/language-service.ts

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -355,14 +355,7 @@ export default class GlintLanguageService implements Partial<ts.LanguageService>
355355
formatOptions: ts.FormatCodeSettings,
356356
preferences: ts.UserPreferences | undefined
357357
): readonly ts.FileTextChanges[] {
358-
let oldTransformedPath = isTransformablePath(oldFilePath)
359-
? getTransformedPath(oldFilePath)
360-
: oldFilePath;
361-
362-
let edits = [
363-
...this.ls.getEditsForFileRename(oldTransformedPath, newFilePath, formatOptions, preferences),
364-
...this.ls.getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences),
365-
];
358+
let edits = this.ls.getEditsForFileRename(oldFilePath, newFilePath, formatOptions, preferences);
366359

367360
return edits.filter((edit) => !isTransformedPath(edit.fileName));
368361
}

0 commit comments

Comments
 (0)