-
-
Notifications
You must be signed in to change notification settings - Fork 439
/
Copy pathnode.ts
126 lines (96 loc) · 4.23 KB
/
node.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import type { Connection } from '@volar/language-server';
import { createConnection, createServer, createSimpleProjectProviderFactory, loadTsdkByPath } from '@volar/language-server/node';
import { ParsedCommandLine, VueCompilerOptions, createParsedCommandLine, createVueLanguagePlugin, parse, resolveVueCompilerOptions } from '@vue/language-core';
import { ServiceEnvironment, convertAttrName, convertTagName, createVueServicePlugins, detect } from '@vue/language-service';
import { DetectNameCasingRequest, GetConvertAttrCasingEditsRequest, GetConvertTagCasingEditsRequest, ParseSFCRequest } from './lib/protocol';
import type { VueInitializationOptions } from './lib/types';
export const connection: Connection = createConnection();
export const server = createServer(connection);
const envToVueOptions = new WeakMap<ServiceEnvironment, VueCompilerOptions>();
let tsdk: ReturnType<typeof loadTsdkByPath>;
connection.listen();
connection.onInitialize(async params => {
const options: VueInitializationOptions = params.initializationOptions;
tsdk = loadTsdkByPath(options.typescript.tsdk!, params.locale);
const vueFileExtensions: string[] = ['vue'];
if (options.vue?.additionalExtensions) {
for (const additionalExtension of options.vue.additionalExtensions) {
vueFileExtensions.push(additionalExtension);
}
}
const result = await server.initialize(
params,
createSimpleProjectProviderFactory(),
{
watchFileExtensions: ['js', 'cjs', 'mjs', 'ts', 'cts', 'mts', 'jsx', 'tsx', 'json', ...vueFileExtensions],
getServicePlugins() {
return createVueServicePlugins(tsdk.typescript, env => envToVueOptions.get(env)!);
},
async getLanguagePlugins(serviceEnv, projectContext) {
const [commandLine, vueOptions] = await parseCommandLine();
const resolvedVueOptions = resolveVueCompilerOptions(vueOptions);
const vueLanguagePlugin = createVueLanguagePlugin(tsdk.typescript, serviceEnv.typescript!.uriToFileName, commandLine?.options ?? {}, resolvedVueOptions, options.codegenStack);
envToVueOptions.set(serviceEnv, resolvedVueOptions);
return [vueLanguagePlugin];
async function parseCommandLine() {
let commandLine: ParsedCommandLine | undefined;
let vueOptions: Partial<VueCompilerOptions> = {};
if (projectContext.typescript) {
const { sys } = projectContext.typescript;
let sysVersion: number | undefined;
let newSysVersion = await sys.sync();
while (sysVersion !== newSysVersion) {
sysVersion = newSysVersion;
if (projectContext.typescript.configFileName) {
commandLine = createParsedCommandLine(tsdk.typescript, sys, projectContext.typescript.configFileName);
}
newSysVersion = await sys.sync();
}
}
if (commandLine) {
vueOptions = commandLine.vueOptions;
}
vueOptions.extensions = [
...vueOptions.extensions ?? ['.vue'],
...vueFileExtensions.map(ext => '.' + ext),
];
vueOptions.extensions = [...new Set(vueOptions.extensions)];
return [commandLine, vueOptions] as const;
}
},
},
);
// handle by tsserver + @vue/typescript-plugin
result.capabilities.semanticTokensProvider = undefined;
return result;
});
connection.onInitialized(() => {
server.initialized();
});
connection.onShutdown(() => {
server.shutdown();
});
connection.onRequest(ParseSFCRequest.type, params => {
return parse(params);
});
connection.onRequest(DetectNameCasingRequest.type, async params => {
const languageService = await getService(params.textDocument.uri);
if (languageService) {
return await detect(languageService.context, params.textDocument.uri);
}
});
connection.onRequest(GetConvertTagCasingEditsRequest.type, async params => {
const languageService = await getService(params.textDocument.uri);
if (languageService) {
return await convertTagName(languageService.context, params.textDocument.uri, params.casing);
}
});
connection.onRequest(GetConvertAttrCasingEditsRequest.type, async params => {
const languageService = await getService(params.textDocument.uri);
if (languageService) {
return await convertAttrName(languageService.context, params.textDocument.uri, params.casing);
}
});
async function getService(uri: string) {
return (await server.projects.getProject(uri)).getLanguageService();
}