Skip to content

Commit 1462f5e

Browse files
committed
feat(typescript-plugin): create script setup block when auto import if needed
1 parent 8865234 commit 1462f5e

File tree

5 files changed

+31
-19
lines changed

5 files changed

+31
-19
lines changed

packages/language-core/lib/types.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,6 @@ export interface Sfc {
123123
customBlocks: readonly (SfcBlock & {
124124
type: string;
125125
})[];
126-
127-
/**
128-
* @deprecated use `template.ast` instead
129-
*/
130-
templateAst: CompilerDOM.RootNode | undefined;
131-
/**
132-
* @deprecated use `script.ast` instead
133-
*/
134-
scriptAst: ts.SourceFile | undefined;
135-
/**
136-
* @deprecated use `scriptSetup.ast` instead
137-
*/
138-
scriptSetupAst: ts.SourceFile | undefined;
139126
}
140127

141128
export interface TextRange {

packages/language-core/lib/virtualFile/computedSfc.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,9 +126,6 @@ export function computedSfc(
126126
get scriptSetup() { return scriptSetup(); },
127127
get styles() { return styles; },
128128
get customBlocks() { return customBlocks; },
129-
get templateAst() { return template()?.ast; },
130-
get scriptAst() { return script()?.ast; },
131-
get scriptSetupAst() { return scriptSetup()?.ast; },
132129
};
133130

134131
function computedTemplateAst(base: SfcBlock) {

packages/language-service/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ export function getVueLanguageServicePlugins(
5555
}
5656
const languageService = (created.provide as import('volar-service-typescript').Provide)['typescript/languageService']();
5757
const vueOptions = getVueOptions(context.env);
58-
decorateLanguageServiceForVue(context.language, languageService, vueOptions, ts, false);
58+
decorateLanguageServiceForVue(context.language, languageService, vueOptions, ts, false, fileName => context.env.typescript!.fileNameToUri(fileName));
5959
return created;
6060
},
6161
};

packages/typescript-plugin/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ function createLanguageServicePlugin(): ts.server.PluginModuleFactory {
6464
projects.set(info.project, { info, language, vueOptions });
6565

6666
decorateLanguageService(language, info.languageService);
67-
decorateLanguageServiceForVue(language, info.languageService, vueOptions, ts, true);
67+
decorateLanguageServiceForVue(language, info.languageService, vueOptions, ts, true, fileName => fileName);
6868
decorateLanguageServiceHost(ts, language, info.languageServiceHost);
6969
startNamedPipeServer(ts, info.project.projectKind, info.project.getCurrentDirectory());
7070

packages/typescript-plugin/lib/common.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ export function decorateLanguageServiceForVue(
99
vueOptions: vue.VueCompilerOptions,
1010
ts: typeof import('typescript'),
1111
isTsPlugin: boolean,
12+
getScriptId: (fileName: string) => string,
1213
) {
1314
const {
1415
getCompletionsAtPosition,
@@ -49,6 +50,12 @@ export function decorateLanguageServiceForVue(
4950
break;
5051
}
5152
}
53+
if (item.data) {
54+
// @ts-expect-error
55+
item.data.__isAutoImport = {
56+
fileName,
57+
};
58+
}
5259
}
5360
}
5461
}
@@ -69,6 +76,27 @@ export function decorateLanguageServiceForVue(
6976
}
7077
}
7178
}
79+
// @ts-expect-error
80+
if (args[6]?.__isAutoImport) {
81+
// @ts-expect-error
82+
const { fileName } = args[6]?.__isAutoImport;
83+
const sourceScript = language.scripts.get(getScriptId(fileName));
84+
if (sourceScript?.generated?.root instanceof vue.VueVirtualCode) {
85+
const sfc = sourceScript.generated.root.getVueSfc();
86+
if (!sfc?.descriptor.script && !sfc?.descriptor.scriptSetup) {
87+
for (const codeAction of details?.codeActions ?? []) {
88+
for (const change of codeAction.changes) {
89+
for (const textChange of change.textChanges) {
90+
textChange.newText = `<script setup lang="ts">${textChange.newText}</script>\n\n`;
91+
break;
92+
}
93+
break;
94+
}
95+
break;
96+
}
97+
}
98+
}
99+
}
72100
return details;
73101
};
74102
languageService.getCodeFixesAtPosition = (...args) => {
@@ -80,7 +108,7 @@ export function decorateLanguageServiceForVue(
80108
if (isTsPlugin) {
81109
languageService.getEncodedSemanticClassifications = (fileName, span, format) => {
82110
const result = getEncodedSemanticClassifications(fileName, span, format);
83-
const file = language.scripts.get(fileName);
111+
const file = language.scripts.get(getScriptId(fileName));
84112
if (file?.generated?.root instanceof vue.VueVirtualCode) {
85113
const { template } = file.generated.root.sfc;
86114
if (template) {

0 commit comments

Comments
 (0)