@vue/language-service 2.2.10 → 2.2.12
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/index.js +0 -1
- package/package.json +16 -16
- package/lib/nameCasing.d.ts +0 -14
- package/lib/nameCasing.js +0 -201
- package/lib/plugins/vue-compiler-dom-errors.d.ts +0 -2
- package/lib/plugins/vue-compiler-dom-errors.js +0 -68
- package/lib/plugins/vue-document-highlights.d.ts +0 -3
- package/lib/plugins/vue-document-highlights.js +0 -46
- package/lib/plugins/vue-missing-props-hints.d.ts +0 -3
- package/lib/plugins/vue-missing-props-hints.js +0 -160
package/index.js
CHANGED
|
@@ -74,7 +74,6 @@ function getFullLanguageServicePlugins(ts, { disableAutoImportCache } = {}) {
|
|
|
74
74
|
languageService.getCompletionsAtPosition = proxy.getCompletionsAtPosition;
|
|
75
75
|
languageService.getCompletionEntryDetails = proxy.getCompletionEntryDetails;
|
|
76
76
|
languageService.getCodeFixesAtPosition = proxy.getCodeFixesAtPosition;
|
|
77
|
-
languageService.getDefinitionAndBoundSpan = proxy.getDefinitionAndBoundSpan;
|
|
78
77
|
languageService.getQuickInfoAtPosition = proxy.getQuickInfoAtPosition;
|
|
79
78
|
}
|
|
80
79
|
return created;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/language-service",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.12",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"data",
|
|
@@ -17,23 +17,23 @@
|
|
|
17
17
|
"update-html-data": "node ./scripts/update-html-data.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@volar/language-core": "
|
|
21
|
-
"@volar/language-service": "
|
|
22
|
-
"@volar/typescript": "
|
|
20
|
+
"@volar/language-core": "2.4.15",
|
|
21
|
+
"@volar/language-service": "2.4.15",
|
|
22
|
+
"@volar/typescript": "2.4.15",
|
|
23
23
|
"@vue/compiler-dom": "^3.5.0",
|
|
24
|
-
"@vue/language-core": "2.2.
|
|
24
|
+
"@vue/language-core": "2.2.12",
|
|
25
25
|
"@vue/shared": "^3.5.0",
|
|
26
|
-
"@vue/typescript-plugin": "2.2.
|
|
26
|
+
"@vue/typescript-plugin": "2.2.12",
|
|
27
27
|
"alien-signals": "^1.0.3",
|
|
28
28
|
"path-browserify": "^1.0.1",
|
|
29
|
-
"volar-service-css": "0.0.
|
|
30
|
-
"volar-service-emmet": "0.0.
|
|
31
|
-
"volar-service-html": "0.0.
|
|
32
|
-
"volar-service-json": "0.0.
|
|
33
|
-
"volar-service-pug": "0.0.
|
|
34
|
-
"volar-service-pug-beautify": "0.0.
|
|
35
|
-
"volar-service-typescript": "0.0.
|
|
36
|
-
"volar-service-typescript-twoslash-queries": "0.0.
|
|
29
|
+
"volar-service-css": "0.0.64",
|
|
30
|
+
"volar-service-emmet": "0.0.64",
|
|
31
|
+
"volar-service-html": "0.0.64",
|
|
32
|
+
"volar-service-json": "0.0.64",
|
|
33
|
+
"volar-service-pug": "0.0.64",
|
|
34
|
+
"volar-service-pug-beautify": "0.0.64",
|
|
35
|
+
"volar-service-typescript": "0.0.64",
|
|
36
|
+
"volar-service-typescript-twoslash-queries": "0.0.64",
|
|
37
37
|
"vscode-css-languageservice": "^6.3.1",
|
|
38
38
|
"vscode-html-languageservice": "^5.2.0",
|
|
39
39
|
"vscode-languageserver-textdocument": "^1.0.11",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "^22.10.4",
|
|
44
44
|
"@types/path-browserify": "^1.0.1",
|
|
45
|
-
"@volar/kit": "
|
|
45
|
+
"@volar/kit": "2.4.15",
|
|
46
46
|
"vscode-languageserver-protocol": "^3.17.5"
|
|
47
47
|
},
|
|
48
|
-
"gitHead": "
|
|
48
|
+
"gitHead": "0b13bf1966398ea3949b6b02d09b251ddc9a51eb"
|
|
49
49
|
}
|
package/lib/nameCasing.d.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { LanguageServiceContext } from '@volar/language-service';
|
|
2
|
-
import type * as vscode from 'vscode-languageserver-protocol';
|
|
3
|
-
import type { URI } from 'vscode-uri';
|
|
4
|
-
import { AttrNameCasing, TagNameCasing } from './types';
|
|
5
|
-
export declare function convertTagName(context: LanguageServiceContext, uri: URI, casing: TagNameCasing, tsPluginClient: import('@vue/typescript-plugin/lib/requests').Requests | undefined): Promise<vscode.TextEdit[] | undefined>;
|
|
6
|
-
export declare function convertAttrName(context: LanguageServiceContext, uri: URI, casing: AttrNameCasing, tsPluginClient?: import('@vue/typescript-plugin/lib/requests').Requests): Promise<vscode.TextEdit[] | undefined>;
|
|
7
|
-
export declare function getNameCasing(context: LanguageServiceContext, uri: URI): Promise<{
|
|
8
|
-
tag: TagNameCasing;
|
|
9
|
-
attr: AttrNameCasing;
|
|
10
|
-
}>;
|
|
11
|
-
export declare function detect(context: LanguageServiceContext, uri: URI): Promise<{
|
|
12
|
-
tag: TagNameCasing[];
|
|
13
|
-
attr: AttrNameCasing[];
|
|
14
|
-
}>;
|
package/lib/nameCasing.js
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.convertTagName = convertTagName;
|
|
4
|
-
exports.convertAttrName = convertAttrName;
|
|
5
|
-
exports.getNameCasing = getNameCasing;
|
|
6
|
-
exports.detect = detect;
|
|
7
|
-
const language_core_1 = require("@vue/language-core");
|
|
8
|
-
const alien_signals_1 = require("alien-signals");
|
|
9
|
-
const types_1 = require("./types");
|
|
10
|
-
async function convertTagName(context, uri, casing, tsPluginClient) {
|
|
11
|
-
const sourceFile = context.language.scripts.get(uri);
|
|
12
|
-
if (!sourceFile) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const root = sourceFile?.generated?.root;
|
|
16
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
const { template } = root.sfc;
|
|
20
|
-
if (!template) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
const document = context.documents.get(sourceFile.id, sourceFile.languageId, sourceFile.snapshot);
|
|
24
|
-
const edits = [];
|
|
25
|
-
const components = await tsPluginClient?.getComponentNames(root.fileName) ?? [];
|
|
26
|
-
const tags = getTemplateTagsAndAttrs(root);
|
|
27
|
-
for (const [tagName, { offsets }] of tags) {
|
|
28
|
-
const componentName = components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
|
|
29
|
-
if (componentName) {
|
|
30
|
-
for (const offset of offsets) {
|
|
31
|
-
const start = document.positionAt(template.startTagEnd + offset);
|
|
32
|
-
const end = document.positionAt(template.startTagEnd + offset + tagName.length);
|
|
33
|
-
const range = { start, end };
|
|
34
|
-
if (casing === types_1.TagNameCasing.Kebab && tagName !== (0, language_core_1.hyphenateTag)(componentName)) {
|
|
35
|
-
edits.push({ range, newText: (0, language_core_1.hyphenateTag)(componentName) });
|
|
36
|
-
}
|
|
37
|
-
if (casing === types_1.TagNameCasing.Pascal && tagName !== componentName) {
|
|
38
|
-
edits.push({ range, newText: componentName });
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return edits;
|
|
44
|
-
}
|
|
45
|
-
async function convertAttrName(context, uri, casing, tsPluginClient) {
|
|
46
|
-
const sourceFile = context.language.scripts.get(uri);
|
|
47
|
-
if (!sourceFile) {
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
const root = sourceFile?.generated?.root;
|
|
51
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
52
|
-
return;
|
|
53
|
-
}
|
|
54
|
-
const { template } = root.sfc;
|
|
55
|
-
if (!template) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
const document = context.documents.get(uri, sourceFile.languageId, sourceFile.snapshot);
|
|
59
|
-
const edits = [];
|
|
60
|
-
const components = await tsPluginClient?.getComponentNames(root.fileName) ?? [];
|
|
61
|
-
const tags = getTemplateTagsAndAttrs(root);
|
|
62
|
-
for (const [tagName, { attrs }] of tags) {
|
|
63
|
-
const componentName = components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
|
|
64
|
-
if (componentName) {
|
|
65
|
-
const props = (await tsPluginClient?.getComponentProps(root.fileName, componentName) ?? []).map(prop => prop.name);
|
|
66
|
-
for (const [attrName, { offsets }] of attrs) {
|
|
67
|
-
const propName = props.find(prop => prop === attrName || (0, language_core_1.hyphenateAttr)(prop) === attrName);
|
|
68
|
-
if (propName) {
|
|
69
|
-
for (const offset of offsets) {
|
|
70
|
-
const start = document.positionAt(template.startTagEnd + offset);
|
|
71
|
-
const end = document.positionAt(template.startTagEnd + offset + attrName.length);
|
|
72
|
-
const range = { start, end };
|
|
73
|
-
if (casing === types_1.AttrNameCasing.Kebab && attrName !== (0, language_core_1.hyphenateAttr)(propName)) {
|
|
74
|
-
edits.push({ range, newText: (0, language_core_1.hyphenateAttr)(propName) });
|
|
75
|
-
}
|
|
76
|
-
if (casing === types_1.AttrNameCasing.Camel && attrName !== propName) {
|
|
77
|
-
edits.push({ range, newText: propName });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
return edits;
|
|
85
|
-
}
|
|
86
|
-
async function getNameCasing(context, uri) {
|
|
87
|
-
const detected = await detect(context, uri);
|
|
88
|
-
const [attr, tag] = await Promise.all([
|
|
89
|
-
context.env.getConfiguration?.('vue.complete.casing.props', uri.toString()),
|
|
90
|
-
context.env.getConfiguration?.('vue.complete.casing.tags', uri.toString()),
|
|
91
|
-
]);
|
|
92
|
-
const tagNameCasing = detected.tag.length === 1 && (tag === 'autoPascal' || tag === 'autoKebab') ? detected.tag[0] : (tag === 'autoKebab' || tag === 'kebab') ? types_1.TagNameCasing.Kebab : types_1.TagNameCasing.Pascal;
|
|
93
|
-
const attrNameCasing = detected.attr.length === 1 && (attr === 'autoCamel' || attr === 'autoKebab') ? detected.attr[0] : (attr === 'autoCamel' || attr === 'camel') ? types_1.AttrNameCasing.Camel : types_1.AttrNameCasing.Kebab;
|
|
94
|
-
return {
|
|
95
|
-
tag: tagNameCasing,
|
|
96
|
-
attr: attrNameCasing,
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
async function detect(context, uri) {
|
|
100
|
-
const rootFile = context.language.scripts.get(uri)?.generated?.root;
|
|
101
|
-
if (!(rootFile instanceof language_core_1.VueVirtualCode)) {
|
|
102
|
-
return {
|
|
103
|
-
tag: [],
|
|
104
|
-
attr: [],
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
return {
|
|
108
|
-
tag: await getTagNameCase(rootFile),
|
|
109
|
-
attr: getAttrNameCase(rootFile),
|
|
110
|
-
};
|
|
111
|
-
function getAttrNameCase(file) {
|
|
112
|
-
const tags = getTemplateTagsAndAttrs(file);
|
|
113
|
-
const result = [];
|
|
114
|
-
for (const [_, { attrs }] of tags) {
|
|
115
|
-
for (const [tagName] of attrs) {
|
|
116
|
-
// attrName
|
|
117
|
-
if (tagName !== (0, language_core_1.hyphenateTag)(tagName)) {
|
|
118
|
-
result.push(types_1.AttrNameCasing.Camel);
|
|
119
|
-
break;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
for (const [tagName] of attrs) {
|
|
123
|
-
// attr-name
|
|
124
|
-
if (tagName.includes('-')) {
|
|
125
|
-
result.push(types_1.AttrNameCasing.Kebab);
|
|
126
|
-
break;
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
return result;
|
|
131
|
-
}
|
|
132
|
-
function getTagNameCase(file) {
|
|
133
|
-
const result = new Set();
|
|
134
|
-
if (file.sfc.template?.ast) {
|
|
135
|
-
for (const element of (0, language_core_1.forEachElementNode)(file.sfc.template.ast)) {
|
|
136
|
-
if (element.tagType === 1) {
|
|
137
|
-
if (element.tag !== (0, language_core_1.hyphenateTag)(element.tag)) {
|
|
138
|
-
// TagName
|
|
139
|
-
result.add(types_1.TagNameCasing.Pascal);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
// Tagname -> tagname
|
|
143
|
-
// TagName -> tag-name
|
|
144
|
-
result.add(types_1.TagNameCasing.Kebab);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
return [...result];
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
const map = new WeakMap();
|
|
153
|
-
function getTemplateTagsAndAttrs(sourceFile) {
|
|
154
|
-
if (!map.has(sourceFile)) {
|
|
155
|
-
const getter = (0, alien_signals_1.computed)(() => {
|
|
156
|
-
if (!(sourceFile instanceof language_core_1.VueVirtualCode)) {
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
const ast = sourceFile.sfc.template?.ast;
|
|
160
|
-
const tags = new Map();
|
|
161
|
-
if (ast) {
|
|
162
|
-
for (const node of (0, language_core_1.forEachElementNode)(ast)) {
|
|
163
|
-
if (!tags.has(node.tag)) {
|
|
164
|
-
tags.set(node.tag, { offsets: [], attrs: new Map() });
|
|
165
|
-
}
|
|
166
|
-
const tag = tags.get(node.tag);
|
|
167
|
-
const startTagHtmlOffset = node.loc.start.offset + node.loc.source.indexOf(node.tag);
|
|
168
|
-
const endTagHtmlOffset = node.loc.start.offset + node.loc.source.lastIndexOf(node.tag);
|
|
169
|
-
tag.offsets.push(startTagHtmlOffset);
|
|
170
|
-
if (!node.isSelfClosing) {
|
|
171
|
-
tag.offsets.push(endTagHtmlOffset);
|
|
172
|
-
}
|
|
173
|
-
for (const prop of node.props) {
|
|
174
|
-
let name;
|
|
175
|
-
let offset;
|
|
176
|
-
if (prop.type === 7
|
|
177
|
-
&& prop.arg?.type === 4
|
|
178
|
-
&& prop.arg.isStatic) {
|
|
179
|
-
name = prop.arg.content;
|
|
180
|
-
offset = prop.arg.loc.start.offset;
|
|
181
|
-
}
|
|
182
|
-
else if (prop.type === 6) {
|
|
183
|
-
name = prop.name;
|
|
184
|
-
offset = prop.loc.start.offset;
|
|
185
|
-
}
|
|
186
|
-
if (name !== undefined && offset !== undefined) {
|
|
187
|
-
if (!tag.attrs.has(name)) {
|
|
188
|
-
tag.attrs.set(name, { offsets: [] });
|
|
189
|
-
}
|
|
190
|
-
tag.attrs.get(name).offsets.push(offset);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
return tags;
|
|
196
|
-
});
|
|
197
|
-
map.set(sourceFile, getter);
|
|
198
|
-
}
|
|
199
|
-
return map.get(sourceFile)() ?? new Map();
|
|
200
|
-
}
|
|
201
|
-
//# sourceMappingURL=nameCasing.js.map
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.create = create;
|
|
4
|
-
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
const vscode_uri_1 = require("vscode-uri");
|
|
6
|
-
function create() {
|
|
7
|
-
return {
|
|
8
|
-
name: 'vue-compiler-dom-errors',
|
|
9
|
-
capabilities: {
|
|
10
|
-
diagnosticProvider: {
|
|
11
|
-
interFileDependencies: false,
|
|
12
|
-
workspaceDiagnostics: false,
|
|
13
|
-
},
|
|
14
|
-
},
|
|
15
|
-
create(context) {
|
|
16
|
-
return {
|
|
17
|
-
provideDiagnostics(document) {
|
|
18
|
-
if (!isSupportedDocument(document)) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
const uri = vscode_uri_1.URI.parse(document.uri);
|
|
22
|
-
const decoded = context.decodeEmbeddedDocumentUri(uri);
|
|
23
|
-
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
24
|
-
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
25
|
-
if (!virtualCode) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const root = sourceScript?.generated?.root;
|
|
29
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
const templateErrors = [];
|
|
33
|
-
const { template } = root.sfc;
|
|
34
|
-
if (template) {
|
|
35
|
-
for (const error of template.errors) {
|
|
36
|
-
onCompilerError(error, 1);
|
|
37
|
-
}
|
|
38
|
-
for (const warning of template.warnings) {
|
|
39
|
-
onCompilerError(warning, 2);
|
|
40
|
-
}
|
|
41
|
-
function onCompilerError(error, severity) {
|
|
42
|
-
const templateHtmlRange = {
|
|
43
|
-
start: error.loc?.start.offset ?? 0,
|
|
44
|
-
end: error.loc?.end.offset ?? 0,
|
|
45
|
-
};
|
|
46
|
-
let errorMessage = error.message;
|
|
47
|
-
templateErrors.push({
|
|
48
|
-
range: {
|
|
49
|
-
start: document.positionAt(templateHtmlRange.start),
|
|
50
|
-
end: document.positionAt(templateHtmlRange.end),
|
|
51
|
-
},
|
|
52
|
-
severity,
|
|
53
|
-
code: error.code,
|
|
54
|
-
source: 'vue',
|
|
55
|
-
message: errorMessage,
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
return templateErrors;
|
|
60
|
-
},
|
|
61
|
-
};
|
|
62
|
-
},
|
|
63
|
-
};
|
|
64
|
-
function isSupportedDocument(document) {
|
|
65
|
-
return document.languageId === 'jade' || document.languageId === 'html';
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
//# sourceMappingURL=vue-compiler-dom-errors.js.map
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.create = create;
|
|
4
|
-
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
const vscode_uri_1 = require("vscode-uri");
|
|
6
|
-
function create(getDocumentHighlights) {
|
|
7
|
-
return {
|
|
8
|
-
name: 'vue-document-highlights',
|
|
9
|
-
capabilities: {
|
|
10
|
-
documentHighlightProvider: true,
|
|
11
|
-
},
|
|
12
|
-
create(context) {
|
|
13
|
-
return {
|
|
14
|
-
async provideDocumentHighlights(document, position) {
|
|
15
|
-
const uri = vscode_uri_1.URI.parse(document.uri);
|
|
16
|
-
const decoded = context.decodeEmbeddedDocumentUri(uri);
|
|
17
|
-
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
18
|
-
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
19
|
-
if (!sourceScript?.generated || virtualCode?.id !== 'main') {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
const root = sourceScript.generated.root;
|
|
23
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const result = await getDocumentHighlights(root.fileName, document.offsetAt(position));
|
|
27
|
-
return result
|
|
28
|
-
?.filter(({ fileName }) => fileName === root.fileName)
|
|
29
|
-
.flatMap(({ highlightSpans }) => highlightSpans)
|
|
30
|
-
.map(({ textSpan, kind }) => ({
|
|
31
|
-
range: {
|
|
32
|
-
start: document.positionAt(textSpan.start),
|
|
33
|
-
end: document.positionAt(textSpan.start + textSpan.length),
|
|
34
|
-
},
|
|
35
|
-
kind: kind === 'reference'
|
|
36
|
-
? 2
|
|
37
|
-
: kind === 'writtenReference'
|
|
38
|
-
? 3
|
|
39
|
-
: 1,
|
|
40
|
-
}));
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
},
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
//# sourceMappingURL=vue-document-highlights.js.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { LanguageServiceContext } from '@volar/language-service';
|
|
2
|
-
import { LanguageServicePlugin } from '../types';
|
|
3
|
-
export declare function create(getTsPluginClient?: (context: LanguageServiceContext) => import('@vue/typescript-plugin/lib/requests').Requests | undefined): LanguageServicePlugin;
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.create = create;
|
|
4
|
-
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
const html = require("vscode-html-languageservice");
|
|
6
|
-
const vscode_uri_1 = require("vscode-uri");
|
|
7
|
-
const nameCasing_1 = require("../nameCasing");
|
|
8
|
-
const types_1 = require("../types");
|
|
9
|
-
function create(getTsPluginClient) {
|
|
10
|
-
return {
|
|
11
|
-
name: 'vue-missing-props-hints',
|
|
12
|
-
capabilities: {
|
|
13
|
-
inlayHintProvider: {},
|
|
14
|
-
},
|
|
15
|
-
create(context) {
|
|
16
|
-
const tsPluginClient = getTsPluginClient?.(context);
|
|
17
|
-
let intrinsicElementNames;
|
|
18
|
-
return {
|
|
19
|
-
async provideInlayHints(document, range, cancellationToken) {
|
|
20
|
-
if (!isSupportedDocument(document)) {
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if (!context.project.vue) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
const vueCompilerOptions = context.project.vue.compilerOptions;
|
|
27
|
-
const enabled = await context.env.getConfiguration?.('vue.inlayHints.missingProps') ?? false;
|
|
28
|
-
if (!enabled) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
const uri = vscode_uri_1.URI.parse(document.uri);
|
|
32
|
-
const decoded = context.decodeEmbeddedDocumentUri(uri);
|
|
33
|
-
const sourceScript = decoded && context.language.scripts.get(decoded[0]);
|
|
34
|
-
const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
|
|
35
|
-
if (!virtualCode) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
const root = sourceScript?.generated?.root;
|
|
39
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const scanner = getScanner(context, document);
|
|
43
|
-
if (!scanner) {
|
|
44
|
-
return;
|
|
45
|
-
}
|
|
46
|
-
const result = [];
|
|
47
|
-
const casing = await (0, nameCasing_1.getNameCasing)(context, decoded[0]);
|
|
48
|
-
const components = await tsPluginClient?.getComponentNames(root.fileName) ?? [];
|
|
49
|
-
const componentProps = {};
|
|
50
|
-
intrinsicElementNames ??= new Set(await tsPluginClient?.getElementNames(root.fileName) ?? []);
|
|
51
|
-
let token;
|
|
52
|
-
let current;
|
|
53
|
-
while ((token = scanner.scan()) !== html.TokenType.EOS) {
|
|
54
|
-
if (token === html.TokenType.StartTag) {
|
|
55
|
-
const tagName = scanner.getTokenText();
|
|
56
|
-
const tagOffset = scanner.getTokenOffset();
|
|
57
|
-
const checkTag = tagName.includes('.')
|
|
58
|
-
? tagName
|
|
59
|
-
: components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
|
|
60
|
-
if (intrinsicElementNames.has(tagName) || !checkTag) {
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (tagOffset < document.offsetAt(range.start)) {
|
|
64
|
-
continue;
|
|
65
|
-
}
|
|
66
|
-
if (tagOffset > document.offsetAt(range.end)) {
|
|
67
|
-
break;
|
|
68
|
-
}
|
|
69
|
-
if (!componentProps[checkTag]) {
|
|
70
|
-
if (cancellationToken.isCancellationRequested) {
|
|
71
|
-
break;
|
|
72
|
-
}
|
|
73
|
-
componentProps[checkTag] = (await tsPluginClient?.getComponentProps(root.fileName, checkTag) ?? [])
|
|
74
|
-
.filter(prop => prop.required)
|
|
75
|
-
.map(prop => prop.name);
|
|
76
|
-
}
|
|
77
|
-
current = {
|
|
78
|
-
unburnedRequiredProps: [...componentProps[checkTag]],
|
|
79
|
-
labelOffset: scanner.getTokenOffset() + scanner.getTokenLength(),
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
else if (token === html.TokenType.AttributeName) {
|
|
83
|
-
if (current) {
|
|
84
|
-
let attrText = scanner.getTokenText();
|
|
85
|
-
if (attrText === 'v-bind') {
|
|
86
|
-
current.unburnedRequiredProps = [];
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
// remove modifiers
|
|
90
|
-
if (attrText.includes('.')) {
|
|
91
|
-
attrText = attrText.split('.')[0];
|
|
92
|
-
}
|
|
93
|
-
// normalize
|
|
94
|
-
if (attrText.startsWith('v-bind:')) {
|
|
95
|
-
attrText = attrText.slice('v-bind:'.length);
|
|
96
|
-
}
|
|
97
|
-
else if (attrText.startsWith(':')) {
|
|
98
|
-
attrText = attrText.slice(':'.length);
|
|
99
|
-
}
|
|
100
|
-
else if (attrText.startsWith('v-model:')) {
|
|
101
|
-
attrText = attrText.slice('v-model:'.length);
|
|
102
|
-
}
|
|
103
|
-
else if (attrText === 'v-model') {
|
|
104
|
-
attrText = vueCompilerOptions.target >= 3 ? 'modelValue' : 'value'; // TODO: support for experimentalModelPropName?
|
|
105
|
-
}
|
|
106
|
-
else if (attrText.startsWith('v-on:')) {
|
|
107
|
-
attrText = 'on-' + (0, language_core_1.hyphenateAttr)(attrText.slice('v-on:'.length));
|
|
108
|
-
}
|
|
109
|
-
else if (attrText.startsWith('@')) {
|
|
110
|
-
attrText = 'on-' + (0, language_core_1.hyphenateAttr)(attrText.slice('@'.length));
|
|
111
|
-
}
|
|
112
|
-
current.unburnedRequiredProps = current.unburnedRequiredProps.filter(propName => {
|
|
113
|
-
return attrText !== propName
|
|
114
|
-
&& attrText !== (0, language_core_1.hyphenateAttr)(propName);
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
else if (token === html.TokenType.StartTagSelfClose || token === html.TokenType.StartTagClose) {
|
|
120
|
-
if (current) {
|
|
121
|
-
for (const requiredProp of current.unburnedRequiredProps) {
|
|
122
|
-
result.push({
|
|
123
|
-
label: `${requiredProp}!`,
|
|
124
|
-
paddingLeft: true,
|
|
125
|
-
position: document.positionAt(current.labelOffset),
|
|
126
|
-
kind: 2,
|
|
127
|
-
textEdits: [{
|
|
128
|
-
range: {
|
|
129
|
-
start: document.positionAt(current.labelOffset),
|
|
130
|
-
end: document.positionAt(current.labelOffset),
|
|
131
|
-
},
|
|
132
|
-
newText: ` :${casing.attr === types_1.AttrNameCasing.Kebab ? (0, language_core_1.hyphenateAttr)(requiredProp) : requiredProp}=`,
|
|
133
|
-
}],
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
current = undefined;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
return result;
|
|
141
|
-
},
|
|
142
|
-
};
|
|
143
|
-
},
|
|
144
|
-
};
|
|
145
|
-
function getScanner(context, document) {
|
|
146
|
-
if (document.languageId === 'html') {
|
|
147
|
-
return context.inject('html/languageService').createScanner(document.getText());
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
const pugDocument = context.inject('pug/pugDocument', document);
|
|
151
|
-
if (pugDocument) {
|
|
152
|
-
return context.inject('pug/languageService').createScanner(pugDocument);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
function isSupportedDocument(document) {
|
|
157
|
-
return document.languageId === 'jade' || document.languageId === 'html';
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
//# sourceMappingURL=vue-missing-props-hints.js.map
|