@vue/language-service 1.9.0-alpha.3 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/template/en.json +2 -2
- package/data/template/fr.json +1 -1
- package/data/template/ja.json +2 -2
- package/data/template/ko.json +13 -13
- package/data/template/pt.json +18 -18
- package/data/template/zh-cn.json +2 -2
- package/index.d.ts +7 -0
- package/index.js +64 -0
- package/lib/ideFeatures/nameCasing.d.ts +13 -0
- package/{out → lib}/ideFeatures/nameCasing.js +82 -29
- package/lib/plugins/css.d.ts +2 -0
- package/lib/plugins/css.js +27 -0
- package/{out → lib}/plugins/data.d.ts +1 -2
- package/lib/plugins/vue-autoinsert-dotvalue.d.ts +10 -0
- package/{out → lib}/plugins/vue-autoinsert-dotvalue.js +70 -54
- package/lib/plugins/vue-autoinsert-parentheses.d.ts +2 -0
- package/lib/plugins/vue-autoinsert-parentheses.js +60 -0
- package/lib/plugins/vue-autoinsert-space.d.ts +2 -0
- package/lib/plugins/vue-autoinsert-space.js +34 -0
- package/lib/plugins/vue-codelens-references.d.ts +2 -0
- package/lib/plugins/vue-codelens-references.js +38 -0
- package/lib/plugins/vue-directive-comments.d.ts +2 -0
- package/lib/plugins/vue-directive-comments.js +61 -0
- package/lib/plugins/vue-document-drop.d.ts +2 -0
- package/lib/plugins/vue-document-drop.js +81 -0
- package/lib/plugins/vue-extract-file.d.ts +8 -0
- package/lib/plugins/vue-extract-file.js +258 -0
- package/lib/plugins/vue-sfc.d.ts +7 -0
- package/lib/plugins/vue-sfc.js +163 -0
- package/lib/plugins/vue-template.d.ts +3 -0
- package/lib/plugins/vue-template.js +594 -0
- package/lib/plugins/vue-toggle-v-bind-codeaction.d.ts +2 -0
- package/lib/plugins/vue-toggle-v-bind-codeaction.js +126 -0
- package/lib/plugins/vue-twoslash-queries.d.ts +2 -0
- package/lib/plugins/vue-twoslash-queries.js +50 -0
- package/lib/plugins/vue-visualize-hidden-callback-param.d.ts +2 -0
- package/lib/plugins/vue-visualize-hidden-callback-param.js +45 -0
- package/{out → lib}/types.d.ts +1 -2
- package/{out → lib}/types.js +1 -1
- package/package.json +20 -20
- package/scripts/update-html-data.js +426 -0
- package/out/helpers.d.ts +0 -17
- package/out/helpers.js +0 -235
- package/out/ideFeatures/dragImport.d.ts +0 -9
- package/out/ideFeatures/dragImport.js +0 -50
- package/out/ideFeatures/nameCasing.d.ts +0 -16
- package/out/index.d.ts +0 -8
- package/out/index.js +0 -26
- package/out/languageService.d.ts +0 -9
- package/out/languageService.js +0 -239
- package/out/plugins/vue-autoinsert-dotvalue.d.ts +0 -7
- package/out/plugins/vue-autoinsert-parentheses.d.ts +0 -3
- package/out/plugins/vue-autoinsert-parentheses.js +0 -61
- package/out/plugins/vue-autoinsert-space.d.ts +0 -3
- package/out/plugins/vue-autoinsert-space.js +0 -32
- package/out/plugins/vue-codelens-references.d.ts +0 -3
- package/out/plugins/vue-codelens-references.js +0 -54
- package/out/plugins/vue-directive-comments.d.ts +0 -3
- package/out/plugins/vue-directive-comments.js +0 -57
- package/out/plugins/vue-extract-file.d.ts +0 -9
- package/out/plugins/vue-extract-file.js +0 -293
- package/out/plugins/vue-template.d.ts +0 -12
- package/out/plugins/vue-template.js +0 -548
- package/out/plugins/vue-toggle-v-bind-codeaction.d.ts +0 -3
- package/out/plugins/vue-toggle-v-bind-codeaction.js +0 -126
- package/out/plugins/vue-twoslash-queries.d.ts +0 -3
- package/out/plugins/vue-twoslash-queries.js +0 -60
- package/out/plugins/vue-visualize-hidden-callback-param.d.ts +0 -3
- package/out/plugins/vue-visualize-hidden-callback-param.js +0 -43
- package/out/plugins/vue.d.ts +0 -8
- package/out/plugins/vue.js +0 -169
- /package/{out → lib}/plugins/data.js +0 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
const fs = require('fs');
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const langs = [
|
|
5
|
+
{
|
|
6
|
+
name: 'en',
|
|
7
|
+
url: 'https://vuejs.org/',
|
|
8
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs/docs/',
|
|
9
|
+
supported: true,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'zh-cn',
|
|
13
|
+
url: 'https://cn.vuejs.org/',
|
|
14
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs-translations/docs-zh-cn/',
|
|
15
|
+
supported: true,
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'ja',
|
|
19
|
+
url: 'https://ja.vuejs.org/',
|
|
20
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs-translations/docs-ja/',
|
|
21
|
+
supported: true,
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'ua',
|
|
25
|
+
url: 'https://ua.vuejs.org/',
|
|
26
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs-translations/docs-ua/',
|
|
27
|
+
supported: false,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'fr',
|
|
31
|
+
url: 'https://fr.vuejs.org/',
|
|
32
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs-translations/docs-fr/',
|
|
33
|
+
supported: true,
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'ko',
|
|
37
|
+
url: 'https://ko.vuejs.org/',
|
|
38
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs-translations/docs-ko/',
|
|
39
|
+
supported: true,
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'pt',
|
|
43
|
+
url: 'https://pt.vuejs.org/',
|
|
44
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs-translations/docs-pt/',
|
|
45
|
+
supported: true,
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
name: 'bn',
|
|
49
|
+
url: 'https://bn.vuejs.org/',
|
|
50
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs-translations/docs-bn/',
|
|
51
|
+
supported: false,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'it',
|
|
55
|
+
url: 'https://it.vuejs.org/',
|
|
56
|
+
repoUrl: 'https://raw.githubusercontent.com/vuejs-translations/docs-it/',
|
|
57
|
+
supported: true,
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
for (const lang of langs) {
|
|
62
|
+
if (lang.supported) {
|
|
63
|
+
templateWorker(lang);
|
|
64
|
+
sfcWorker(lang);
|
|
65
|
+
modelWorker(lang);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async function sfcWorker(lang) {
|
|
70
|
+
|
|
71
|
+
const sfcDoc = await fetchText(lang.repoUrl + 'HEAD/src/api/sfc-spec.md', lang.url);
|
|
72
|
+
const cssFeaturesDoc = await fetchText(lang.repoUrl + 'HEAD/src/api/sfc-css-features.md', lang.url);
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @type {import('vscode-html-languageservice').IAttributeData}
|
|
76
|
+
*/
|
|
77
|
+
const langAttr = {
|
|
78
|
+
name: 'lang',
|
|
79
|
+
description: {
|
|
80
|
+
kind: 'markdown',
|
|
81
|
+
value: sfcDoc.split('\n## ')[4].split('\n').slice(1).join('\n'),
|
|
82
|
+
},
|
|
83
|
+
values: [
|
|
84
|
+
// // custom block
|
|
85
|
+
// { name: 'md' },
|
|
86
|
+
// { name: 'json' },
|
|
87
|
+
// { name: 'jsonc' },
|
|
88
|
+
// { name: 'json5' },
|
|
89
|
+
// { name: 'yaml' },
|
|
90
|
+
// { name: 'toml' },
|
|
91
|
+
// { name: 'gql' },
|
|
92
|
+
// { name: 'graphql' },
|
|
93
|
+
],
|
|
94
|
+
references: langs.map(lang => ({
|
|
95
|
+
name: lang.name,
|
|
96
|
+
url: `${lang.url}api/sfc-spec.html#pre-processors`,
|
|
97
|
+
})),
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* @type {import('vscode-html-languageservice').IAttributeData}
|
|
101
|
+
*/
|
|
102
|
+
const srcAttr = {
|
|
103
|
+
name: 'src',
|
|
104
|
+
description: {
|
|
105
|
+
kind: 'markdown',
|
|
106
|
+
value: sfcDoc.split('\n## ')[5].split('\n').slice(1).join('\n'),
|
|
107
|
+
},
|
|
108
|
+
references: langs.map(lang => ({
|
|
109
|
+
name: lang.name,
|
|
110
|
+
url: `${lang.url}api/sfc-spec.html#src-imports`,
|
|
111
|
+
})),
|
|
112
|
+
};
|
|
113
|
+
const languageBlocks = sfcDoc
|
|
114
|
+
.split('\n## ')[2]
|
|
115
|
+
.split('\n### ')
|
|
116
|
+
.slice(1)
|
|
117
|
+
.map((section) => {
|
|
118
|
+
const lines = section.split('\n');
|
|
119
|
+
const name = normalizeTagName(lines[0]);
|
|
120
|
+
/**
|
|
121
|
+
* @type {import('vscode-html-languageservice').ITagData}
|
|
122
|
+
*/
|
|
123
|
+
const data = {
|
|
124
|
+
name,
|
|
125
|
+
attributes: name === 'script setup' ? [] : [srcAttr],
|
|
126
|
+
description: {
|
|
127
|
+
kind: 'markdown',
|
|
128
|
+
value: lines.slice(1).join('\n'),
|
|
129
|
+
},
|
|
130
|
+
references: langs.map(lang => ({
|
|
131
|
+
name: lang.name,
|
|
132
|
+
url: `${lang.url}api/sfc-spec.html#${normalizeHash(name)}`,
|
|
133
|
+
})),
|
|
134
|
+
};
|
|
135
|
+
if (name === 'template') {
|
|
136
|
+
data.attributes.push({
|
|
137
|
+
...langAttr,
|
|
138
|
+
values: [
|
|
139
|
+
{ name: 'html' },
|
|
140
|
+
{ name: 'pug' },
|
|
141
|
+
],
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (name === 'script') {
|
|
145
|
+
data.attributes.push({
|
|
146
|
+
...langAttr,
|
|
147
|
+
values: [
|
|
148
|
+
{ name: 'ts' },
|
|
149
|
+
{ name: 'js' },
|
|
150
|
+
{ name: 'tsx' },
|
|
151
|
+
{ name: 'jsx' },
|
|
152
|
+
],
|
|
153
|
+
});
|
|
154
|
+
data.attributes.push({ name: 'generic' });
|
|
155
|
+
}
|
|
156
|
+
if (name === 'style') {
|
|
157
|
+
data.attributes.push({
|
|
158
|
+
...langAttr,
|
|
159
|
+
values: [
|
|
160
|
+
{ name: 'css' },
|
|
161
|
+
{ name: 'scss' },
|
|
162
|
+
{ name: 'less' },
|
|
163
|
+
{ name: 'stylus' },
|
|
164
|
+
{ name: 'postcss' },
|
|
165
|
+
{ name: 'sass' },
|
|
166
|
+
],
|
|
167
|
+
});
|
|
168
|
+
data.attributes.push({
|
|
169
|
+
name: 'scoped',
|
|
170
|
+
valueSet: 'v',
|
|
171
|
+
description: {
|
|
172
|
+
kind: 'markdown',
|
|
173
|
+
value: cssFeaturesDoc.split('\n## ')[1].split('\n').slice(1).join('\n'),
|
|
174
|
+
},
|
|
175
|
+
references: langs.map(lang => ({
|
|
176
|
+
name: lang.name,
|
|
177
|
+
url: `${lang.url}api/sfc-css-features.html#scoped-css`,
|
|
178
|
+
})),
|
|
179
|
+
});
|
|
180
|
+
data.attributes.push({
|
|
181
|
+
name: 'module',
|
|
182
|
+
valueSet: 'v',
|
|
183
|
+
description: {
|
|
184
|
+
kind: 'markdown',
|
|
185
|
+
value: cssFeaturesDoc.split('\n## ')[2].split('\n').slice(1).join('\n'),
|
|
186
|
+
},
|
|
187
|
+
references: langs.map(lang => ({
|
|
188
|
+
name: lang.name,
|
|
189
|
+
url: `${lang.url}api/sfc-css-features.html#css-modules`,
|
|
190
|
+
})),
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return data;
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
const scriptBlock = languageBlocks.find(b => b.name === 'script');
|
|
197
|
+
const scriptSetupBlock = languageBlocks.find(b => b.name === 'script setup');
|
|
198
|
+
|
|
199
|
+
if (!scriptBlock || !scriptSetupBlock) {
|
|
200
|
+
throw new Error('script or script setup block not found');
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
scriptBlock.attributes.push({
|
|
204
|
+
name: 'setup',
|
|
205
|
+
valueSet: 'v',
|
|
206
|
+
description: scriptSetupBlock.description,
|
|
207
|
+
references: scriptSetupBlock.references,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* @type {import('vscode-html-languageservice').HTMLDataV1}
|
|
212
|
+
*/
|
|
213
|
+
const data = {
|
|
214
|
+
version: 1.1,
|
|
215
|
+
tags: languageBlocks,
|
|
216
|
+
globalAttributes: [langAttr, srcAttr],
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const writePath = path.resolve(__dirname, '../data/language-blocks/' + lang.name + '.json');
|
|
220
|
+
fs.writeFileSync(writePath, JSON.stringify(data, null, 2));
|
|
221
|
+
console.log(writePath);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
async function modelWorker(lang) {
|
|
225
|
+
|
|
226
|
+
const formsDoc = await fetchText(lang.repoUrl + 'HEAD/src/guide/essentials/forms.md', lang.url);
|
|
227
|
+
const modifiers = formsDoc
|
|
228
|
+
.split('\n## ')[3]
|
|
229
|
+
.split('\n### ')
|
|
230
|
+
.slice(1)
|
|
231
|
+
.map((section) => {
|
|
232
|
+
const lines = section.split('\n');
|
|
233
|
+
let name = normalizeAttrName(lines[0]);
|
|
234
|
+
name = name.split('.')[1];
|
|
235
|
+
/**
|
|
236
|
+
* @type {import('vscode-html-languageservice').IAttributeData}
|
|
237
|
+
*/
|
|
238
|
+
const data = {
|
|
239
|
+
name,
|
|
240
|
+
description: {
|
|
241
|
+
kind: 'markdown',
|
|
242
|
+
value: lines.slice(1).join('\n'),
|
|
243
|
+
},
|
|
244
|
+
references: langs.map(lang => ({
|
|
245
|
+
name: lang.name,
|
|
246
|
+
url: `${lang.url}guide/essentials/forms.html#${normalizeHash(name)}`,
|
|
247
|
+
})),
|
|
248
|
+
};
|
|
249
|
+
return data;
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* @type {import('vscode-html-languageservice').HTMLDataV1}
|
|
254
|
+
*/
|
|
255
|
+
const data = {
|
|
256
|
+
version: 1.1,
|
|
257
|
+
globalAttributes: modifiers,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
const writePath = path.resolve(__dirname, '../data/model-modifiers/' + lang.name + '.json');
|
|
261
|
+
fs.writeFileSync(writePath, JSON.stringify(data, null, 2));
|
|
262
|
+
console.log(writePath);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
async function templateWorker(lang) {
|
|
266
|
+
|
|
267
|
+
const directivesDoc = await fetchText(lang.repoUrl + 'HEAD/src/api/built-in-directives.md', lang.url);
|
|
268
|
+
const attributesDoc = await fetchText(lang.repoUrl + 'HEAD/src/api/built-in-special-attributes.md', lang.url);
|
|
269
|
+
const componentsDoc = await fetchText(lang.repoUrl + 'HEAD/src/api/built-in-components.md', lang.url);
|
|
270
|
+
const elementsDoc = await fetchText(lang.repoUrl + 'HEAD/src/api/built-in-special-elements.md', lang.url);
|
|
271
|
+
|
|
272
|
+
const directives = directivesDoc
|
|
273
|
+
.split('\n## ')
|
|
274
|
+
.slice(1)
|
|
275
|
+
.map((section) => {
|
|
276
|
+
const lines = section.split('\n');
|
|
277
|
+
const name = normalizeAttrName(lines[0]);
|
|
278
|
+
/**
|
|
279
|
+
* @type {import('vscode-html-languageservice').IAttributeData}
|
|
280
|
+
*/
|
|
281
|
+
const data = {
|
|
282
|
+
name,
|
|
283
|
+
valueSet: name === 'v-else' ? 'v' : undefined,
|
|
284
|
+
description: {
|
|
285
|
+
kind: 'markdown',
|
|
286
|
+
value: lines.slice(1).join('\n'),
|
|
287
|
+
},
|
|
288
|
+
references: langs.map(lang => ({
|
|
289
|
+
name: lang.name,
|
|
290
|
+
url: `${lang.url}api/built-in-directives.html#${normalizeHash(name)}`,
|
|
291
|
+
})),
|
|
292
|
+
};
|
|
293
|
+
return data;
|
|
294
|
+
});
|
|
295
|
+
const attributes = attributesDoc
|
|
296
|
+
.split('\n## ')
|
|
297
|
+
.slice(1)
|
|
298
|
+
.map((section) => {
|
|
299
|
+
const lines = section.split('\n');
|
|
300
|
+
const name = normalizeAttrName(lines[0]);
|
|
301
|
+
/**
|
|
302
|
+
* @type {import('vscode-html-languageservice').IAttributeData}
|
|
303
|
+
*/
|
|
304
|
+
const data = {
|
|
305
|
+
name,
|
|
306
|
+
description: {
|
|
307
|
+
kind: 'markdown',
|
|
308
|
+
value: lines.slice(1).join('\n'),
|
|
309
|
+
},
|
|
310
|
+
references: langs.map(lang => ({
|
|
311
|
+
name: lang.name,
|
|
312
|
+
url: `${lang.url}api/built-in-special-attributes.html#${normalizeHash(name)}`,
|
|
313
|
+
})),
|
|
314
|
+
};
|
|
315
|
+
return data;
|
|
316
|
+
});
|
|
317
|
+
const components = componentsDoc
|
|
318
|
+
.split('\n## ')
|
|
319
|
+
.slice(1)
|
|
320
|
+
.map((section) => {
|
|
321
|
+
const lines = section.split('\n');
|
|
322
|
+
const name = normalizeTagName(lines[0]);
|
|
323
|
+
/**
|
|
324
|
+
* @type {import('vscode-html-languageservice').ITagData}
|
|
325
|
+
*/
|
|
326
|
+
const data = {
|
|
327
|
+
name,
|
|
328
|
+
description: {
|
|
329
|
+
kind: 'markdown',
|
|
330
|
+
value: lines.slice(1).join('\n'),
|
|
331
|
+
},
|
|
332
|
+
attributes: [],
|
|
333
|
+
references: langs.map(lang => ({
|
|
334
|
+
name: lang.name,
|
|
335
|
+
url: `${lang.url}api/built-in-components.html#${normalizeHash(name)}`,
|
|
336
|
+
})),
|
|
337
|
+
};
|
|
338
|
+
return data;
|
|
339
|
+
});
|
|
340
|
+
const elements = elementsDoc
|
|
341
|
+
.split('\n## ')
|
|
342
|
+
.slice(1)
|
|
343
|
+
.map((section) => {
|
|
344
|
+
const lines = section.split('\n');
|
|
345
|
+
const name = normalizeTagName(lines[0]);
|
|
346
|
+
/**
|
|
347
|
+
* @type {import('vscode-html-languageservice').ITagData}
|
|
348
|
+
*/
|
|
349
|
+
const data = {
|
|
350
|
+
name,
|
|
351
|
+
description: {
|
|
352
|
+
kind: 'markdown',
|
|
353
|
+
value: lines.slice(1).join('\n'),
|
|
354
|
+
},
|
|
355
|
+
attributes: [],
|
|
356
|
+
references: langs.map(lang => ({
|
|
357
|
+
name: lang.name,
|
|
358
|
+
url: `${lang.url}api/built-in-special-elements.html#${normalizeHash(name)}`,
|
|
359
|
+
})),
|
|
360
|
+
};
|
|
361
|
+
return data;
|
|
362
|
+
});
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* @type {import('vscode-html-languageservice').HTMLDataV1}
|
|
366
|
+
*/
|
|
367
|
+
const data = {
|
|
368
|
+
version: 1.1,
|
|
369
|
+
tags: [
|
|
370
|
+
...components,
|
|
371
|
+
...elements,
|
|
372
|
+
],
|
|
373
|
+
globalAttributes: [
|
|
374
|
+
...directives,
|
|
375
|
+
...attributes
|
|
376
|
+
],
|
|
377
|
+
};
|
|
378
|
+
|
|
379
|
+
const writePath = path.resolve(__dirname, '../data/template/' + lang.name + '.json');
|
|
380
|
+
fs.writeFileSync(writePath, JSON.stringify(data, null, 2));
|
|
381
|
+
console.log(writePath);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
async function fetchText(url, baseUrl) {
|
|
385
|
+
let text = await (await fetch(url)).text();
|
|
386
|
+
text = text.replace(/```vue-html/g, '```html');
|
|
387
|
+
text = text.replace(/\{\#.*?\}/g, '')
|
|
388
|
+
text = resolveMarkdownLinks(text, baseUrl);
|
|
389
|
+
return text;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function resolveMarkdownLinks(text, url) {
|
|
393
|
+
return text.replace(/\[(.*?)\]\(\/(.*?)\)/g, (match, p1, p2) => {
|
|
394
|
+
const p2Parts = p2.split('#');
|
|
395
|
+
if (!p2Parts[0].endsWith('.html')) {
|
|
396
|
+
p2Parts[0] += '.html';
|
|
397
|
+
}
|
|
398
|
+
p2 = p2Parts.join('#');
|
|
399
|
+
return `[${p1}](${url}${p2})`;
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
function normalizeTagName(name) {
|
|
404
|
+
name = name.trim();
|
|
405
|
+
return _normalizeName(name);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
function normalizeAttrName(name) {
|
|
409
|
+
name = name.trim();
|
|
410
|
+
name = name.split(' ')[0];
|
|
411
|
+
return _normalizeName(name);
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
function _normalizeName(name) {
|
|
415
|
+
if (name.startsWith('`')) {
|
|
416
|
+
name = name.split('`')[1].split('`')[0];
|
|
417
|
+
}
|
|
418
|
+
if (name.startsWith('<')) {
|
|
419
|
+
name = name.split('<')[1].split('>')[0];
|
|
420
|
+
}
|
|
421
|
+
return name;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function normalizeHash(str) {
|
|
425
|
+
return str.replace(/ /g, '-').toLowerCase();
|
|
426
|
+
}
|
package/out/helpers.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import * as vue from '@vue/language-core';
|
|
2
|
-
import * as embedded from '@volar/language-core';
|
|
3
|
-
import type * as ts from 'typescript/lib/tsserverlibrary';
|
|
4
|
-
export declare function getPropsByTag(ts: typeof import('typescript/lib/tsserverlibrary'), tsLs: ts.LanguageService, sourceFile: embedded.VirtualFile, tag: string, vueCompilerOptions: vue.VueCompilerOptions, requiredOnly?: boolean): string[];
|
|
5
|
-
export declare function getEventsOfTag(ts: typeof import('typescript/lib/tsserverlibrary'), tsLs: ts.LanguageService, sourceFile: embedded.VirtualFile, tag: string, vueCompilerOptions: vue.VueCompilerOptions): string[];
|
|
6
|
-
export declare function getTemplateCtx(ts: typeof import('typescript/lib/tsserverlibrary'), tsLs: ts.LanguageService, sourceFile: embedded.VirtualFile): string[] | undefined;
|
|
7
|
-
export declare function getComponentNames(ts: typeof import('typescript/lib/tsserverlibrary'), tsLs: ts.LanguageService, sourceFile: embedded.VirtualFile, vueCompilerOptions: vue.VueCompilerOptions): string[];
|
|
8
|
-
export declare function getElementAttrs(ts: typeof import('typescript/lib/tsserverlibrary'), tsLs: ts.LanguageService, tsLsHost: ts.LanguageServiceHost, tagName: string): string[];
|
|
9
|
-
type Tags = Map<string, {
|
|
10
|
-
offsets: number[];
|
|
11
|
-
attrs: Map<string, {
|
|
12
|
-
offsets: number[];
|
|
13
|
-
}>;
|
|
14
|
-
}>;
|
|
15
|
-
export declare function getTemplateTagsAndAttrs(sourceFile: embedded.VirtualFile): Tags;
|
|
16
|
-
export {};
|
|
17
|
-
//# sourceMappingURL=helpers.d.ts.map
|
package/out/helpers.js
DELETED
|
@@ -1,235 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getTemplateTagsAndAttrs = exports.getElementAttrs = exports.getComponentNames = exports.getTemplateCtx = exports.getEventsOfTag = exports.getPropsByTag = void 0;
|
|
4
|
-
const vue = require("@vue/language-core");
|
|
5
|
-
const embedded = require("@volar/language-core");
|
|
6
|
-
const computeds_1 = require("computeds");
|
|
7
|
-
const language_core_1 = require("@vue/language-core");
|
|
8
|
-
const shared_1 = require("@vue/shared");
|
|
9
|
-
function getPropsByTag(ts, tsLs, sourceFile, tag, vueCompilerOptions, requiredOnly = false) {
|
|
10
|
-
const checker = tsLs.getProgram().getTypeChecker();
|
|
11
|
-
const components = getVariableType(ts, tsLs, sourceFile, '__VLS_components');
|
|
12
|
-
if (!components)
|
|
13
|
-
return [];
|
|
14
|
-
const name = tag.split('.');
|
|
15
|
-
let componentSymbol = components.type.getProperty(name[0]);
|
|
16
|
-
if (!componentSymbol && !vueCompilerOptions.nativeTags.includes(name[0])) {
|
|
17
|
-
componentSymbol = components.type.getProperty((0, shared_1.camelize)(name[0]))
|
|
18
|
-
?? components.type.getProperty((0, shared_1.capitalize)((0, shared_1.camelize)(name[0])));
|
|
19
|
-
}
|
|
20
|
-
if (!componentSymbol)
|
|
21
|
-
return [];
|
|
22
|
-
let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
23
|
-
for (let i = 1; i < name.length; i++) {
|
|
24
|
-
componentSymbol = componentType.getProperty(name[i]);
|
|
25
|
-
if (componentSymbol) {
|
|
26
|
-
componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
return [];
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const result = new Set();
|
|
33
|
-
for (const sig of componentType.getCallSignatures()) {
|
|
34
|
-
const propParam = sig.parameters[0];
|
|
35
|
-
if (propParam) {
|
|
36
|
-
const propsType = checker.getTypeOfSymbolAtLocation(propParam, components.node);
|
|
37
|
-
const props = propsType.getProperties();
|
|
38
|
-
for (const prop of props) {
|
|
39
|
-
if (!requiredOnly || !(prop.flags & ts.SymbolFlags.Optional)) {
|
|
40
|
-
result.add(prop.name);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
for (const sig of componentType.getConstructSignatures()) {
|
|
46
|
-
const instanceType = sig.getReturnType();
|
|
47
|
-
const propsSymbol = instanceType.getProperty('$props');
|
|
48
|
-
if (propsSymbol) {
|
|
49
|
-
const propsType = checker.getTypeOfSymbolAtLocation(propsSymbol, components.node);
|
|
50
|
-
const props = propsType.getProperties();
|
|
51
|
-
for (const prop of props) {
|
|
52
|
-
if (prop.flags & ts.SymbolFlags.Method) { // #2443
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (!requiredOnly || !(prop.flags & ts.SymbolFlags.Optional)) {
|
|
56
|
-
result.add(prop.name);
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
return [...result];
|
|
62
|
-
}
|
|
63
|
-
exports.getPropsByTag = getPropsByTag;
|
|
64
|
-
function getEventsOfTag(ts, tsLs, sourceFile, tag, vueCompilerOptions) {
|
|
65
|
-
const checker = tsLs.getProgram().getTypeChecker();
|
|
66
|
-
const components = getVariableType(ts, tsLs, sourceFile, '__VLS_components');
|
|
67
|
-
if (!components)
|
|
68
|
-
return [];
|
|
69
|
-
const name = tag.split('.');
|
|
70
|
-
let componentSymbol = components.type.getProperty(name[0]);
|
|
71
|
-
if (!componentSymbol && !vueCompilerOptions.nativeTags.includes(name[0])) {
|
|
72
|
-
componentSymbol = components.type.getProperty((0, shared_1.camelize)(name[0]))
|
|
73
|
-
?? components.type.getProperty((0, shared_1.capitalize)((0, shared_1.camelize)(name[0])));
|
|
74
|
-
}
|
|
75
|
-
if (!componentSymbol)
|
|
76
|
-
return [];
|
|
77
|
-
let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
78
|
-
for (let i = 1; i < name.length; i++) {
|
|
79
|
-
componentSymbol = componentType.getProperty(name[i]);
|
|
80
|
-
if (componentSymbol) {
|
|
81
|
-
componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
82
|
-
}
|
|
83
|
-
else {
|
|
84
|
-
return [];
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
const result = new Set();
|
|
88
|
-
// for (const sig of componentType.getCallSignatures()) {
|
|
89
|
-
// const emitParam = sig.parameters[1];
|
|
90
|
-
// if (emitParam) {
|
|
91
|
-
// // TODO
|
|
92
|
-
// }
|
|
93
|
-
// }
|
|
94
|
-
for (const sig of componentType.getConstructSignatures()) {
|
|
95
|
-
const instanceType = sig.getReturnType();
|
|
96
|
-
const emitSymbol = instanceType.getProperty('$emit');
|
|
97
|
-
if (emitSymbol) {
|
|
98
|
-
const emitType = checker.getTypeOfSymbolAtLocation(emitSymbol, components.node);
|
|
99
|
-
for (const call of emitType.getCallSignatures()) {
|
|
100
|
-
const eventNameParamSymbol = call.parameters[0];
|
|
101
|
-
if (eventNameParamSymbol) {
|
|
102
|
-
const eventNameParamType = checker.getTypeOfSymbolAtLocation(eventNameParamSymbol, components.node);
|
|
103
|
-
if (eventNameParamType.isStringLiteral()) {
|
|
104
|
-
result.add(eventNameParamType.value);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
return [...result];
|
|
111
|
-
}
|
|
112
|
-
exports.getEventsOfTag = getEventsOfTag;
|
|
113
|
-
function getTemplateCtx(ts, tsLs, sourceFile) {
|
|
114
|
-
return getVariableType(ts, tsLs, sourceFile, '__VLS_ctx')
|
|
115
|
-
?.type
|
|
116
|
-
?.getProperties()
|
|
117
|
-
.map(c => c.name);
|
|
118
|
-
}
|
|
119
|
-
exports.getTemplateCtx = getTemplateCtx;
|
|
120
|
-
function getComponentNames(ts, tsLs, sourceFile, vueCompilerOptions) {
|
|
121
|
-
return getVariableType(ts, tsLs, sourceFile, '__VLS_components')
|
|
122
|
-
?.type
|
|
123
|
-
?.getProperties()
|
|
124
|
-
.map(c => c.name)
|
|
125
|
-
.filter(entry => entry.indexOf('$') === -1 && !entry.startsWith('_'))
|
|
126
|
-
.filter(entry => !vueCompilerOptions.nativeTags.includes(entry))
|
|
127
|
-
?? [];
|
|
128
|
-
}
|
|
129
|
-
exports.getComponentNames = getComponentNames;
|
|
130
|
-
function getElementAttrs(ts, tsLs, tsLsHost, tagName) {
|
|
131
|
-
const sharedTypesFileName = tsLsHost.getCurrentDirectory() + '/' + language_core_1.sharedTypes.baseName;
|
|
132
|
-
let tsSourceFile;
|
|
133
|
-
if (tsSourceFile = tsLs.getProgram()?.getSourceFile(sharedTypesFileName)) {
|
|
134
|
-
const typeNode = tsSourceFile.statements.find((node) => ts.isTypeAliasDeclaration(node) && node.name.getText() === '__VLS_IntrinsicElements');
|
|
135
|
-
const checker = tsLs.getProgram()?.getTypeChecker();
|
|
136
|
-
if (checker && typeNode) {
|
|
137
|
-
const type = checker.getTypeFromTypeNode(typeNode.type);
|
|
138
|
-
const el = type.getProperty(tagName);
|
|
139
|
-
if (el) {
|
|
140
|
-
const attrs = checker.getTypeOfSymbolAtLocation(el, typeNode).getProperties();
|
|
141
|
-
return attrs.map(c => c.name);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return [];
|
|
146
|
-
}
|
|
147
|
-
exports.getElementAttrs = getElementAttrs;
|
|
148
|
-
function getVariableType(ts, tsLs, sourceFile, name) {
|
|
149
|
-
if (!(sourceFile instanceof vue.VueFile)) {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
let file;
|
|
153
|
-
let tsSourceFile;
|
|
154
|
-
embedded.forEachEmbeddedFile(sourceFile, embedded => {
|
|
155
|
-
if (embedded.fileName === sourceFile.mainScriptName) {
|
|
156
|
-
file = embedded;
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
if (file && (tsSourceFile = tsLs.getProgram()?.getSourceFile(file.fileName))) {
|
|
160
|
-
const node = searchVariableDeclarationNode(ts, tsSourceFile, name);
|
|
161
|
-
const checker = tsLs.getProgram()?.getTypeChecker();
|
|
162
|
-
if (checker && node) {
|
|
163
|
-
return {
|
|
164
|
-
node: node,
|
|
165
|
-
type: checker.getTypeAtLocation(node),
|
|
166
|
-
};
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
function searchVariableDeclarationNode(ts, sourceFile, name) {
|
|
171
|
-
let componentsNode;
|
|
172
|
-
walk(sourceFile);
|
|
173
|
-
return componentsNode;
|
|
174
|
-
function walk(node) {
|
|
175
|
-
if (componentsNode) {
|
|
176
|
-
return;
|
|
177
|
-
}
|
|
178
|
-
else if (ts.isVariableDeclaration(node) && node.name.getText() === name) {
|
|
179
|
-
componentsNode = node;
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
node.forEachChild(walk);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
const map = new WeakMap();
|
|
187
|
-
function getTemplateTagsAndAttrs(sourceFile) {
|
|
188
|
-
if (!map.has(sourceFile)) {
|
|
189
|
-
const getter = (0, computeds_1.computed)(() => {
|
|
190
|
-
if (!(sourceFile instanceof vue.VueFile))
|
|
191
|
-
return;
|
|
192
|
-
const ast = sourceFile.sfc.template?.ast;
|
|
193
|
-
const tags = new Map();
|
|
194
|
-
if (ast) {
|
|
195
|
-
vue.walkElementNodes(ast, node => {
|
|
196
|
-
if (!tags.has(node.tag)) {
|
|
197
|
-
tags.set(node.tag, { offsets: [], attrs: new Map() });
|
|
198
|
-
}
|
|
199
|
-
const tag = tags.get(node.tag);
|
|
200
|
-
const startTagHtmlOffset = node.loc.start.offset + node.loc.source.indexOf(node.tag);
|
|
201
|
-
const endTagHtmlOffset = node.loc.start.offset + node.loc.source.lastIndexOf(node.tag);
|
|
202
|
-
tag.offsets.push(startTagHtmlOffset);
|
|
203
|
-
if (!node.isSelfClosing) {
|
|
204
|
-
tag.offsets.push(endTagHtmlOffset);
|
|
205
|
-
}
|
|
206
|
-
for (const prop of node.props) {
|
|
207
|
-
let name;
|
|
208
|
-
let offset;
|
|
209
|
-
if (prop.type === 7
|
|
210
|
-
&& prop.arg?.type === 4
|
|
211
|
-
&& prop.arg.isStatic) {
|
|
212
|
-
name = prop.arg.content;
|
|
213
|
-
offset = prop.arg.loc.start.offset;
|
|
214
|
-
}
|
|
215
|
-
else if (prop.type === 6) {
|
|
216
|
-
name = prop.name;
|
|
217
|
-
offset = prop.loc.start.offset;
|
|
218
|
-
}
|
|
219
|
-
if (name !== undefined && offset !== undefined) {
|
|
220
|
-
if (!tag.attrs.has(name)) {
|
|
221
|
-
tag.attrs.set(name, { offsets: [] });
|
|
222
|
-
}
|
|
223
|
-
tag.attrs.get(name).offsets.push(offset);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
}
|
|
228
|
-
return tags;
|
|
229
|
-
});
|
|
230
|
-
map.set(sourceFile, getter);
|
|
231
|
-
}
|
|
232
|
-
return map.get(sourceFile)() ?? new Map();
|
|
233
|
-
}
|
|
234
|
-
exports.getTemplateTagsAndAttrs = getTemplateTagsAndAttrs;
|
|
235
|
-
//# sourceMappingURL=helpers.js.map
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ServiceContext } from '@volar/language-service';
|
|
2
|
-
import type * as vscode from 'vscode-languageserver-protocol';
|
|
3
|
-
import { TagNameCasing } from '../types';
|
|
4
|
-
export declare function getDragImportEdits(ts: typeof import('typescript/lib/tsserverlibrary'), ctx: ServiceContext, uri: string, importUri: string, casing: TagNameCasing): {
|
|
5
|
-
insertText: string;
|
|
6
|
-
insertTextFormat: vscode.InsertTextFormat;
|
|
7
|
-
additionalEdits: vscode.TextEdit[];
|
|
8
|
-
} | undefined;
|
|
9
|
-
//# sourceMappingURL=dragImport.d.ts.map
|