@vue/typescript-plugin 2.2.4 → 2.2.6
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.
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as vue from '@vue/language-core';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
import type { RequestContext } from './types';
|
|
4
|
+
export declare function getComponentProps(this: RequestContext, fileName: string, tag: string): {
|
|
5
|
+
name: string;
|
|
6
|
+
required?: true;
|
|
7
|
+
commentMarkdown?: string;
|
|
8
|
+
}[] | undefined;
|
|
9
|
+
export declare function getComponentEvents(this: RequestContext, fileName: string, tag: string): string[] | undefined;
|
|
10
|
+
export declare function getTemplateContextProps(this: RequestContext, fileName: string): string[] | undefined;
|
|
11
|
+
export declare function getComponentNames(this: RequestContext, fileName: string): string[] | undefined;
|
|
12
|
+
export declare function _getComponentNames(ts: typeof import('typescript'), tsLs: ts.LanguageService, vueCode: vue.VueVirtualCode): string[];
|
|
13
|
+
export declare function getElementAttrs(this: RequestContext, fileName: string, tagName: string): string[] | undefined;
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getComponentProps = getComponentProps;
|
|
4
|
+
exports.getComponentEvents = getComponentEvents;
|
|
5
|
+
exports.getTemplateContextProps = getTemplateContextProps;
|
|
6
|
+
exports.getComponentNames = getComponentNames;
|
|
7
|
+
exports._getComponentNames = _getComponentNames;
|
|
8
|
+
exports.getElementAttrs = getElementAttrs;
|
|
9
|
+
const vue = require("@vue/language-core");
|
|
10
|
+
const shared_1 = require("@vue/shared");
|
|
11
|
+
function getComponentProps(fileName, tag) {
|
|
12
|
+
const { typescript: ts, language, languageService, getFileId } = this;
|
|
13
|
+
const volarFile = language.scripts.get(getFileId(fileName));
|
|
14
|
+
if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
const vueCode = volarFile.generated.root;
|
|
18
|
+
const program = languageService.getProgram();
|
|
19
|
+
const checker = program.getTypeChecker();
|
|
20
|
+
const components = getVariableType(ts, languageService, vueCode, '__VLS_components');
|
|
21
|
+
if (!components) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
const name = tag.split('.');
|
|
25
|
+
let componentSymbol = components.type.getProperty(name[0])
|
|
26
|
+
?? components.type.getProperty((0, shared_1.camelize)(name[0]))
|
|
27
|
+
?? components.type.getProperty((0, shared_1.capitalize)((0, shared_1.camelize)(name[0])));
|
|
28
|
+
if (!componentSymbol) {
|
|
29
|
+
return [];
|
|
30
|
+
}
|
|
31
|
+
let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
32
|
+
for (let i = 1; i < name.length; i++) {
|
|
33
|
+
componentSymbol = componentType.getProperty(name[i]);
|
|
34
|
+
if (componentSymbol) {
|
|
35
|
+
componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
return [];
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const result = new Map();
|
|
42
|
+
for (const sig of componentType.getCallSignatures()) {
|
|
43
|
+
const propParam = sig.parameters[0];
|
|
44
|
+
if (propParam) {
|
|
45
|
+
const propsType = checker.getTypeOfSymbolAtLocation(propParam, components.node);
|
|
46
|
+
const props = propsType.getProperties();
|
|
47
|
+
for (const prop of props) {
|
|
48
|
+
const name = prop.name;
|
|
49
|
+
const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
|
|
50
|
+
const commentMarkdown = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags()) || undefined;
|
|
51
|
+
result.set(name, { name, required, commentMarkdown });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
for (const sig of componentType.getConstructSignatures()) {
|
|
56
|
+
const instanceType = sig.getReturnType();
|
|
57
|
+
const propsSymbol = instanceType.getProperty('$props');
|
|
58
|
+
if (propsSymbol) {
|
|
59
|
+
const propsType = checker.getTypeOfSymbolAtLocation(propsSymbol, components.node);
|
|
60
|
+
const props = propsType.getProperties();
|
|
61
|
+
for (const prop of props) {
|
|
62
|
+
if (prop.flags & ts.SymbolFlags.Method) { // #2443
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
const name = prop.name;
|
|
66
|
+
const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
|
|
67
|
+
const commentMarkdown = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags()) || undefined;
|
|
68
|
+
result.set(name, { name, required, commentMarkdown });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return [...result.values()];
|
|
73
|
+
}
|
|
74
|
+
function getComponentEvents(fileName, tag) {
|
|
75
|
+
const { typescript: ts, language, languageService, getFileId } = this;
|
|
76
|
+
const volarFile = language.scripts.get(getFileId(fileName));
|
|
77
|
+
if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const vueCode = volarFile.generated.root;
|
|
81
|
+
const program = languageService.getProgram();
|
|
82
|
+
const checker = program.getTypeChecker();
|
|
83
|
+
const components = getVariableType(ts, languageService, vueCode, '__VLS_components');
|
|
84
|
+
if (!components) {
|
|
85
|
+
return [];
|
|
86
|
+
}
|
|
87
|
+
const name = tag.split('.');
|
|
88
|
+
let componentSymbol = components.type.getProperty(name[0]);
|
|
89
|
+
if (!componentSymbol) {
|
|
90
|
+
componentSymbol = components.type.getProperty((0, shared_1.camelize)(name[0]))
|
|
91
|
+
?? components.type.getProperty((0, shared_1.capitalize)((0, shared_1.camelize)(name[0])));
|
|
92
|
+
}
|
|
93
|
+
if (!componentSymbol) {
|
|
94
|
+
return [];
|
|
95
|
+
}
|
|
96
|
+
let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
97
|
+
for (let i = 1; i < name.length; i++) {
|
|
98
|
+
componentSymbol = componentType.getProperty(name[i]);
|
|
99
|
+
if (componentSymbol) {
|
|
100
|
+
componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
return [];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
const result = new Set();
|
|
107
|
+
// for (const sig of componentType.getCallSignatures()) {
|
|
108
|
+
// const emitParam = sig.parameters[1];
|
|
109
|
+
// if (emitParam) {
|
|
110
|
+
// // TODO
|
|
111
|
+
// }
|
|
112
|
+
// }
|
|
113
|
+
for (const sig of componentType.getConstructSignatures()) {
|
|
114
|
+
const instanceType = sig.getReturnType();
|
|
115
|
+
const emitSymbol = instanceType.getProperty('$emit');
|
|
116
|
+
if (emitSymbol) {
|
|
117
|
+
const emitType = checker.getTypeOfSymbolAtLocation(emitSymbol, components.node);
|
|
118
|
+
for (const call of emitType.getCallSignatures()) {
|
|
119
|
+
const eventNameParamSymbol = call.parameters[0];
|
|
120
|
+
if (eventNameParamSymbol) {
|
|
121
|
+
const eventNameParamType = checker.getTypeOfSymbolAtLocation(eventNameParamSymbol, components.node);
|
|
122
|
+
if (eventNameParamType.isStringLiteral()) {
|
|
123
|
+
result.add(eventNameParamType.value);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return [...result];
|
|
130
|
+
}
|
|
131
|
+
function getTemplateContextProps(fileName) {
|
|
132
|
+
const { typescript: ts, language, languageService, getFileId } = this;
|
|
133
|
+
const volarFile = language.scripts.get(getFileId(fileName));
|
|
134
|
+
if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const vueCode = volarFile.generated.root;
|
|
138
|
+
return getVariableType(ts, languageService, vueCode, '__VLS_ctx')
|
|
139
|
+
?.type
|
|
140
|
+
?.getProperties()
|
|
141
|
+
.map(c => c.name);
|
|
142
|
+
}
|
|
143
|
+
function getComponentNames(fileName) {
|
|
144
|
+
const { typescript: ts, language, languageService, getFileId } = this;
|
|
145
|
+
const volarFile = language.scripts.get(getFileId(fileName));
|
|
146
|
+
if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const vueCode = volarFile.generated.root;
|
|
150
|
+
return getVariableType(ts, languageService, vueCode, '__VLS_components')
|
|
151
|
+
?.type
|
|
152
|
+
?.getProperties()
|
|
153
|
+
.map(c => c.name)
|
|
154
|
+
.filter(entry => !entry.includes('$') && !entry.startsWith('_'))
|
|
155
|
+
?? [];
|
|
156
|
+
}
|
|
157
|
+
function _getComponentNames(ts, tsLs, vueCode) {
|
|
158
|
+
return getVariableType(ts, tsLs, vueCode, '__VLS_components')
|
|
159
|
+
?.type
|
|
160
|
+
?.getProperties()
|
|
161
|
+
.map(c => c.name)
|
|
162
|
+
.filter(entry => !entry.includes('$') && !entry.startsWith('_'))
|
|
163
|
+
?? [];
|
|
164
|
+
}
|
|
165
|
+
function getElementAttrs(fileName, tagName) {
|
|
166
|
+
const { typescript: ts, language, languageService, getFileId } = this;
|
|
167
|
+
const volarFile = language.scripts.get(getFileId(fileName));
|
|
168
|
+
if (!(volarFile?.generated?.root instanceof vue.VueVirtualCode)) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const program = languageService.getProgram();
|
|
172
|
+
let tsSourceFile;
|
|
173
|
+
if (tsSourceFile = program.getSourceFile(fileName)) {
|
|
174
|
+
const typeNode = tsSourceFile.statements.find((node) => ts.isTypeAliasDeclaration(node) && node.name.getText() === '__VLS_IntrinsicElementsCompletion');
|
|
175
|
+
const checker = program.getTypeChecker();
|
|
176
|
+
if (checker && typeNode) {
|
|
177
|
+
const type = checker.getTypeFromTypeNode(typeNode.type);
|
|
178
|
+
const el = type.getProperty(tagName);
|
|
179
|
+
if (el) {
|
|
180
|
+
const attrs = checker.getTypeOfSymbolAtLocation(el, typeNode).getProperties();
|
|
181
|
+
return attrs.map(c => c.name);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
return [];
|
|
186
|
+
}
|
|
187
|
+
function getVariableType(ts, languageService, vueCode, name) {
|
|
188
|
+
const program = languageService.getProgram();
|
|
189
|
+
let tsSourceFile;
|
|
190
|
+
if (tsSourceFile = program.getSourceFile(vueCode.fileName)) {
|
|
191
|
+
const node = searchVariableDeclarationNode(ts, tsSourceFile, name);
|
|
192
|
+
const checker = program.getTypeChecker();
|
|
193
|
+
if (checker && node) {
|
|
194
|
+
return {
|
|
195
|
+
node: node,
|
|
196
|
+
type: checker.getTypeAtLocation(node),
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function searchVariableDeclarationNode(ts, sourceFile, name) {
|
|
202
|
+
let componentsNode;
|
|
203
|
+
walk(sourceFile);
|
|
204
|
+
return componentsNode;
|
|
205
|
+
function walk(node) {
|
|
206
|
+
if (componentsNode) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
else if (ts.isVariableDeclaration(node) && node.name.getText() === name) {
|
|
210
|
+
componentsNode = node;
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
node.forEachChild(walk);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
function generateCommentMarkdown(parts, jsDocTags) {
|
|
218
|
+
const parsedComment = _symbolDisplayPartsToMarkdown(parts);
|
|
219
|
+
const parsedJsDoc = _jsDocTagInfoToMarkdown(jsDocTags);
|
|
220
|
+
let result = [parsedComment, parsedJsDoc].filter(str => !!str).join('\n\n');
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
function _symbolDisplayPartsToMarkdown(parts) {
|
|
224
|
+
return parts.map(part => {
|
|
225
|
+
switch (part.kind) {
|
|
226
|
+
case 'keyword':
|
|
227
|
+
return `\`${part.text}\``;
|
|
228
|
+
case 'functionName':
|
|
229
|
+
return `**${part.text}**`;
|
|
230
|
+
default:
|
|
231
|
+
return part.text;
|
|
232
|
+
}
|
|
233
|
+
}).join('');
|
|
234
|
+
}
|
|
235
|
+
function _jsDocTagInfoToMarkdown(jsDocTags) {
|
|
236
|
+
return jsDocTags.map(tag => {
|
|
237
|
+
const tagName = `*@${tag.name}*`;
|
|
238
|
+
const tagText = tag.text?.map(t => {
|
|
239
|
+
if (t.kind === 'parameterName') {
|
|
240
|
+
return `\`${t.text}\``;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
return t.text;
|
|
244
|
+
}
|
|
245
|
+
}).join('') || '';
|
|
246
|
+
return `${tagName} ${tagText}`;
|
|
247
|
+
}).join('\n\n');
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=componentInfos.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/typescript-plugin",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
16
|
"@volar/typescript": "~2.4.11",
|
|
17
|
-
"@vue/language-core": "2.2.
|
|
17
|
+
"@vue/language-core": "2.2.6",
|
|
18
18
|
"@vue/shared": "^3.5.0"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/node": "^22.10.4"
|
|
22
22
|
},
|
|
23
|
-
"gitHead": "
|
|
23
|
+
"gitHead": "f2088e256dc0220db9549d28d9f865a5711dcfbe"
|
|
24
24
|
}
|