Skip to content

Commit a167a93

Browse files
committed
feat: provide Svelte 5 component migration command
1 parent b12afd1 commit a167a93

File tree

4 files changed

+65
-10
lines changed

4 files changed

+65
-10
lines changed

packages/language-server/src/plugins/svelte/SveltePlugin.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
WorkspaceEdit
1616
} from 'vscode-languageserver';
1717
import { Plugin } from 'prettier';
18-
import { getPackageInfo, importPrettier } from '../../importPackage';
18+
import { getPackageInfo, importPrettier, importSvelte } from '../../importPackage';
1919
import { Document } from '../../lib/documents';
2020
import { Logger } from '../../logger';
2121
import { LSConfigManager, LSSvelteConfig } from '../../ls-config';
@@ -288,6 +288,10 @@ export class SveltePlugin
288288
command: string,
289289
args?: any[]
290290
): Promise<WorkspaceEdit | string | null> {
291+
if (command === 'migrate_to_svelte_5') {
292+
return this.migrate(document);
293+
}
294+
291295
if (!this.featureEnabled('codeActions')) {
292296
return null;
293297
}
@@ -300,6 +304,36 @@ export class SveltePlugin
300304
}
301305
}
302306

307+
private migrate(document: Document): WorkspaceEdit | string {
308+
try {
309+
const compiler = importSvelte(document.getFilePath() ?? '') as any;
310+
if (!compiler.migrate) {
311+
return 'Your installed Svelte version does not support migration';
312+
}
313+
314+
const migrated = compiler.migrate(document.getText(), {
315+
filename: document.getFilePath() ?? undefined
316+
});
317+
318+
return {
319+
changes: {
320+
[document.uri]: [
321+
TextEdit.replace(
322+
Range.create(
323+
document.positionAt(0),
324+
document.positionAt(document.getTextLength())
325+
),
326+
migrated.code
327+
)
328+
]
329+
}
330+
};
331+
} catch (error: any) {
332+
Logger.error('Failed to migrate Svelte file', error);
333+
return error?.message ?? 'Failed to migrate Svelte file';
334+
}
335+
}
336+
303337
async getSelectionRange(
304338
document: Document,
305339
position: Position

packages/language-server/src/server.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ export function startServer(options?: LSOptions) {
290290
'constant_scope_2',
291291
'constant_scope_3',
292292
'extract_to_svelte_component',
293+
'migrate_to_svelte_5',
293294
'Infer function return type'
294295
]
295296
}
@@ -592,15 +593,13 @@ export function startServer(options?: LSOptions) {
592593
return null;
593594
}
594595

595-
if (doc) {
596-
const compiled = await sveltePlugin.getCompiledResult(doc);
597-
if (compiled) {
598-
const js = compiled.js;
599-
const css = compiled.css;
600-
return { js, css };
601-
} else {
602-
return null;
603-
}
596+
const compiled = await sveltePlugin.getCompiledResult(doc);
597+
if (compiled) {
598+
const js = compiled.js;
599+
const css = compiled.css;
600+
return { js, css };
601+
} else {
602+
return null;
604603
}
605604
});
606605

packages/svelte-vscode/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,10 @@
540540
"command": "svelte.extractComponent",
541541
"title": "Svelte: Extract Component"
542542
},
543+
{
544+
"command": "svelte.migrate_to_svelte_5",
545+
"title": "Svelte: Migrate Component to Svelte 5 Syntax"
546+
},
543547
{
544548
"command": "svelte.typescript.findAllFileReferences",
545549
"title": "Svelte: Find File References"

packages/svelte-vscode/src/extension.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ export function activateSvelteLanguageServer(context: ExtensionContext) {
259259

260260
addExtracComponentCommand(getLS, context);
261261

262+
addMigrateToSvelte5Command(getLS, context);
263+
262264
languages.setLanguageConfiguration('svelte', {
263265
indentationRules: {
264266
// Matches a valid opening tag that is:
@@ -495,6 +497,22 @@ function addExtracComponentCommand(getLS: () => LanguageClient, context: Extensi
495497
);
496498
}
497499

500+
function addMigrateToSvelte5Command(getLS: () => LanguageClient, context: ExtensionContext) {
501+
context.subscriptions.push(
502+
commands.registerTextEditorCommand('svelte.migrate_to_svelte_5', async (editor) => {
503+
if (editor?.document?.languageId !== 'svelte') {
504+
return;
505+
}
506+
507+
const uri = editor.document.uri.toString();
508+
getLS().sendRequest(ExecuteCommandRequest.type, {
509+
command: 'migrate_to_svelte_5',
510+
arguments: [uri]
511+
});
512+
})
513+
);
514+
}
515+
498516
function createLanguageServer(serverOptions: ServerOptions, clientOptions: LanguageClientOptions) {
499517
return new LanguageClient('svelte', 'Svelte', serverOptions, clientOptions);
500518
}

0 commit comments

Comments
 (0)