@vue/typescript-plugin 3.1.7 → 3.2.0
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 +65 -27
- package/lib/common.d.ts +16 -1
- package/lib/common.js +167 -103
- package/lib/requests/getComponentDirectives.js +1 -10
- package/lib/requests/getComponentMeta.d.ts +4 -0
- package/lib/requests/getComponentMeta.js +14 -0
- package/lib/requests/getComponentNames.js +1 -1
- package/lib/requests/getComponentSlots.js +1 -1
- package/lib/requests/getElementAttrs.d.ts +4 -1
- package/lib/requests/getElementAttrs.js +12 -4
- package/lib/requests/getElementNames.d.ts +1 -1
- package/lib/requests/getElementNames.js +8 -3
- package/lib/requests/index.d.ts +4 -4
- package/lib/requests/utils.d.ts +1 -1
- package/lib/requests/utils.js +48 -16
- package/package.json +6 -5
- package/lib/requests/getComponentEvents.d.ts +0 -3
- package/lib/requests/getComponentEvents.js +0 -40
- package/lib/requests/getComponentProps.d.ts +0 -11
- package/lib/requests/getComponentProps.js +0 -115
package/index.js
CHANGED
|
@@ -1,13 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
const transform_js_1 = require("@volar/typescript/lib/node/transform.js");
|
|
3
36
|
const createLanguageServicePlugin_1 = require("@volar/typescript/lib/quickstart/createLanguageServicePlugin");
|
|
4
|
-
const core = require("@vue/language-core");
|
|
37
|
+
const core = __importStar(require("@vue/language-core"));
|
|
5
38
|
const common_1 = require("./lib/common");
|
|
6
39
|
const collectExtractProps_1 = require("./lib/requests/collectExtractProps");
|
|
7
40
|
const getComponentDirectives_1 = require("./lib/requests/getComponentDirectives");
|
|
8
|
-
const
|
|
41
|
+
const getComponentMeta_1 = require("./lib/requests/getComponentMeta");
|
|
9
42
|
const getComponentNames_1 = require("./lib/requests/getComponentNames");
|
|
10
|
-
const getComponentProps_1 = require("./lib/requests/getComponentProps");
|
|
11
43
|
const getComponentSlots_1 = require("./lib/requests/getComponentSlots");
|
|
12
44
|
const getElementAttrs_1 = require("./lib/requests/getElementAttrs");
|
|
13
45
|
const getElementNames_1 = require("./lib/requests/getElementNames");
|
|
@@ -19,7 +51,6 @@ module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)(
|
|
|
19
51
|
projectToOriginalLanguageService.set(info.project, info.languageService);
|
|
20
52
|
const vueOptions = getVueCompilerOptions();
|
|
21
53
|
const languagePlugin = core.createVueLanguagePlugin(ts, info.languageServiceHost.getCompilationSettings(), vueOptions, id => id);
|
|
22
|
-
vueOptions.globalTypesPath = core.createGlobalTypesWriter(vueOptions, ts.sys.writeFile);
|
|
23
54
|
addVueCommands();
|
|
24
55
|
let _language;
|
|
25
56
|
(0, common_1.preprocessLanguageService)(info.languageService, () => _language);
|
|
@@ -83,7 +114,7 @@ module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)(
|
|
|
83
114
|
return createResponse((0, getImportPathForFile_1.getImportPathForFile)(ts, project, project.getLanguageService().getProgram(), fileName, incomingFileName, preferences));
|
|
84
115
|
});
|
|
85
116
|
session.addProtocolHandler('_vue:getAutoImportSuggestions', request => {
|
|
86
|
-
const [fileName, position
|
|
117
|
+
const [fileName, position] = request.arguments;
|
|
87
118
|
const { project, language, sourceScript, virtualCode } = getProjectAndVirtualCode(fileName);
|
|
88
119
|
const tsLanguageService = projectToOriginalLanguageService.get(project);
|
|
89
120
|
if (!tsLanguageService) {
|
|
@@ -99,30 +130,40 @@ module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)(
|
|
|
99
130
|
continue;
|
|
100
131
|
}
|
|
101
132
|
const tsPosition2 = tsPosition + sourceScript.snapshot.getLength();
|
|
102
|
-
const result = tsLanguageService.getCompletionsAtPosition(fileName, tsPosition2,
|
|
133
|
+
const result = tsLanguageService.getCompletionsAtPosition(fileName, tsPosition2, session['getPreferences'](fileName), session['getFormatOptions'](fileName));
|
|
103
134
|
if (result) {
|
|
104
135
|
(0, common_1.resolveCompletionResult)(ts, language, fileName => fileName, vueOptions, fileName, position, result);
|
|
105
|
-
result.entries = result.entries
|
|
136
|
+
result.entries = result.entries
|
|
137
|
+
.filter(entry => {
|
|
138
|
+
const data = entry.data;
|
|
139
|
+
return data?.__vue__componentAutoImport || data?.__vue__autoImport;
|
|
140
|
+
});
|
|
106
141
|
for (const entry of result.entries) {
|
|
107
|
-
|
|
142
|
+
const data = entry.data;
|
|
143
|
+
data.__vue__autoImportSuggestions = {
|
|
108
144
|
fileName,
|
|
109
145
|
position: tsPosition + sourceScript.snapshot.getLength(),
|
|
110
|
-
entryName:
|
|
146
|
+
entryName: data.__vue__componentAutoImport?.oldName ?? entry.name,
|
|
111
147
|
source: entry.source,
|
|
112
148
|
};
|
|
113
149
|
}
|
|
114
150
|
}
|
|
115
151
|
return createResponse(result);
|
|
116
152
|
}
|
|
117
|
-
const result = tsLanguageService.getCompletionsAtPosition(fileName, 0,
|
|
153
|
+
const result = tsLanguageService.getCompletionsAtPosition(fileName, 0, session['getPreferences'](fileName), session['getFormatOptions'](fileName));
|
|
118
154
|
if (result) {
|
|
119
155
|
(0, common_1.resolveCompletionResult)(ts, language, fileName => fileName, vueOptions, fileName, position, result);
|
|
120
|
-
result.entries = result.entries
|
|
156
|
+
result.entries = result.entries
|
|
157
|
+
.filter(entry => {
|
|
158
|
+
const data = entry.data;
|
|
159
|
+
return data?.__vue__componentAutoImport || data?.__vue__autoImport;
|
|
160
|
+
});
|
|
121
161
|
for (const entry of result.entries) {
|
|
122
|
-
|
|
162
|
+
const data = entry.data;
|
|
163
|
+
data.__vue__autoImportSuggestions = {
|
|
123
164
|
fileName,
|
|
124
165
|
position: 0,
|
|
125
|
-
entryName:
|
|
166
|
+
entryName: data.__vue__componentAutoImport?.oldName ?? entry.name,
|
|
126
167
|
source: entry.source,
|
|
127
168
|
};
|
|
128
169
|
}
|
|
@@ -132,17 +173,17 @@ module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)(
|
|
|
132
173
|
return createResponse(undefined);
|
|
133
174
|
});
|
|
134
175
|
session.addProtocolHandler('_vue:resolveAutoImportCompletionEntry', request => {
|
|
135
|
-
const [data
|
|
136
|
-
if (!data
|
|
176
|
+
const [data] = request.arguments;
|
|
177
|
+
if (!data?.__vue__autoImportSuggestions) {
|
|
137
178
|
return createResponse(undefined);
|
|
138
179
|
}
|
|
139
|
-
const { fileName, position, entryName, source } = data.
|
|
180
|
+
const { fileName, position, entryName, source } = data.__vue__autoImportSuggestions;
|
|
140
181
|
const { project, language } = getProject(fileName);
|
|
141
182
|
const tsLanguageService = projectToOriginalLanguageService.get(project);
|
|
142
183
|
if (!tsLanguageService) {
|
|
143
184
|
return createResponse(undefined);
|
|
144
185
|
}
|
|
145
|
-
const details = tsLanguageService.getCompletionEntryDetails(fileName, position, entryName,
|
|
186
|
+
const details = tsLanguageService.getCompletionEntryDetails(fileName, position, entryName, session['getFormatOptions'](fileName), source, session['getPreferences'](fileName), data);
|
|
146
187
|
if (details) {
|
|
147
188
|
for (const codeAction of details.codeActions ?? []) {
|
|
148
189
|
codeAction.changes = (0, transform_js_1.transformFileTextChanges)(language, codeAction.changes, false, core.isCompletionEnabled);
|
|
@@ -161,20 +202,17 @@ module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)(
|
|
|
161
202
|
const { project } = getProject(fileName);
|
|
162
203
|
return createResponse((0, getComponentDirectives_1.getComponentDirectives)(ts, project.getLanguageService().getProgram(), fileName));
|
|
163
204
|
});
|
|
164
|
-
session.addProtocolHandler('_vue:getComponentEvents', request => {
|
|
165
|
-
const [fileName, tag] = request.arguments;
|
|
166
|
-
const { project, virtualCode } = getProjectAndVirtualCode(fileName);
|
|
167
|
-
return createResponse((0, getComponentEvents_1.getComponentEvents)(ts, project.getLanguageService().getProgram(), virtualCode, tag));
|
|
168
|
-
});
|
|
169
205
|
session.addProtocolHandler('_vue:getComponentNames', request => {
|
|
170
206
|
const [fileName] = request.arguments;
|
|
171
207
|
const { project, virtualCode } = getProjectAndVirtualCode(fileName);
|
|
172
208
|
return createResponse((0, getComponentNames_1.getComponentNames)(ts, project.getLanguageService().getProgram(), virtualCode));
|
|
173
209
|
});
|
|
174
|
-
session.addProtocolHandler('_vue:
|
|
210
|
+
session.addProtocolHandler('_vue:getComponentMeta', request => {
|
|
175
211
|
const [fileName, tag] = request.arguments;
|
|
176
|
-
const { project, virtualCode } = getProjectAndVirtualCode(fileName);
|
|
177
|
-
|
|
212
|
+
const { project, virtualCode, language } = getProjectAndVirtualCode(fileName);
|
|
213
|
+
const program = project.getLanguageService().getProgram();
|
|
214
|
+
const sourceFile = program.getSourceFile(virtualCode.fileName);
|
|
215
|
+
return createResponse((0, getComponentMeta_1.getComponentMeta)(ts, program, language, sourceFile, virtualCode, tag));
|
|
178
216
|
});
|
|
179
217
|
session.addProtocolHandler('_vue:getComponentSlots', request => {
|
|
180
218
|
const [fileName] = request.arguments;
|
|
@@ -184,12 +222,12 @@ module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)(
|
|
|
184
222
|
session.addProtocolHandler('_vue:getElementAttrs', request => {
|
|
185
223
|
const [fileName, tag] = request.arguments;
|
|
186
224
|
const { project } = getProject(fileName);
|
|
187
|
-
return createResponse((0, getElementAttrs_1.getElementAttrs)(ts, project.getLanguageService().getProgram(), tag));
|
|
225
|
+
return createResponse((0, getElementAttrs_1.getElementAttrs)(ts, project.getLanguageService().getProgram(), fileName, tag));
|
|
188
226
|
});
|
|
189
227
|
session.addProtocolHandler('_vue:getElementNames', request => {
|
|
190
228
|
const [fileName] = request.arguments;
|
|
191
229
|
const { project } = getProject(fileName);
|
|
192
|
-
return createResponse((0, getElementNames_1.getElementNames)(ts, project.getLanguageService().getProgram()));
|
|
230
|
+
return createResponse((0, getElementNames_1.getElementNames)(ts, project.getLanguageService().getProgram(), fileName));
|
|
193
231
|
});
|
|
194
232
|
session.addProtocolHandler('_vue:resolveModuleName', request => {
|
|
195
233
|
const [fileName, moduleName] = request.arguments;
|
package/lib/common.d.ts
CHANGED
|
@@ -3,4 +3,19 @@ import type * as ts from 'typescript';
|
|
|
3
3
|
export declare function preprocessLanguageService(languageService: ts.LanguageService, getLanguage: () => Language<any> | undefined): void;
|
|
4
4
|
export declare function postprocessLanguageService<T>(ts: typeof import('typescript'), language: Language<T>, languageService: ts.LanguageService, vueOptions: VueCompilerOptions, asScriptId: (fileName: string) => T): ts.LanguageService;
|
|
5
5
|
export declare function resolveCompletionResult<T>(ts: typeof import('typescript'), language: Language<T>, asScriptId: (fileName: string) => T, vueOptions: VueCompilerOptions, fileName: string, position: number, result: ts.CompletionInfo): void;
|
|
6
|
-
export
|
|
6
|
+
export type VueCompletionData = (ts.CompletionEntryData & {
|
|
7
|
+
__vue__componentAutoImport?: {
|
|
8
|
+
oldName: string;
|
|
9
|
+
newName: string;
|
|
10
|
+
};
|
|
11
|
+
__vue__autoImport?: {
|
|
12
|
+
fileName: string;
|
|
13
|
+
};
|
|
14
|
+
__vue__autoImportSuggestions?: {
|
|
15
|
+
fileName: string;
|
|
16
|
+
position: number;
|
|
17
|
+
entryName: string;
|
|
18
|
+
source: string | undefined;
|
|
19
|
+
};
|
|
20
|
+
}) | undefined;
|
|
21
|
+
export declare function resolveCompletionEntryDetails(language: Language<any>, details: ts.CompletionEntryDetails, data: VueCompletionData): void;
|
package/lib/common.js
CHANGED
|
@@ -11,96 +11,124 @@ const shared_1 = require("@vue/shared");
|
|
|
11
11
|
const windowsPathReg = /\\/g;
|
|
12
12
|
function preprocessLanguageService(languageService, getLanguage) {
|
|
13
13
|
const { getQuickInfoAtPosition, getSuggestionDiagnostics, getCompletionsAtPosition, getCodeFixesAtPosition, } = languageService;
|
|
14
|
-
languageService.getQuickInfoAtPosition = (fileName, position,
|
|
15
|
-
|
|
14
|
+
languageService.getQuickInfoAtPosition = (fileName, position, ...rests) => {
|
|
15
|
+
const result = getQuickInfoAtPosition(fileName, position, ...rests);
|
|
16
|
+
if (!result) {
|
|
17
|
+
return result;
|
|
18
|
+
}
|
|
16
19
|
const language = getLanguage();
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
if (!language) {
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
const [serviceScript, _targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
24
|
+
if (!serviceScript || !(sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode)) {
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
for (const sourceOffset of (0, transform_1.toSourceOffsets)(sourceScript, language, serviceScript, position, () => true)) {
|
|
28
|
+
const generatedOffset2 = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, sourceOffset[1], (data) => !!data.__importCompletion);
|
|
29
|
+
if (generatedOffset2 !== undefined) {
|
|
30
|
+
const extraInfo = getQuickInfoAtPosition(fileName, generatedOffset2, ...rests);
|
|
31
|
+
if (extraInfo) {
|
|
32
|
+
result.tags ??= [];
|
|
33
|
+
result.tags.push(...extraInfo.tags ?? []);
|
|
29
34
|
}
|
|
30
35
|
}
|
|
31
36
|
}
|
|
32
37
|
return result;
|
|
33
38
|
};
|
|
34
|
-
languageService.getSuggestionDiagnostics = fileName => {
|
|
35
|
-
const
|
|
39
|
+
languageService.getSuggestionDiagnostics = (fileName, ...rests) => {
|
|
40
|
+
const result = getSuggestionDiagnostics(fileName, ...rests);
|
|
36
41
|
const language = getLanguage();
|
|
37
|
-
if (language) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
42
|
+
if (!language) {
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
const [serviceScript, _targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
46
|
+
if (!serviceScript || !(sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode)) {
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
for (const diagnostic of result) {
|
|
50
|
+
for (const sourceRange of (0, transform_1.toSourceRanges)(sourceScript, language, serviceScript, diagnostic.start, diagnostic.start + diagnostic.length, true, (data) => !!data.__importCompletion)) {
|
|
51
|
+
const generateRange2 = (0, transform_1.toGeneratedRange)(language, serviceScript, sourceScript, sourceRange[1], sourceRange[2], (data) => !data.__importCompletion);
|
|
52
|
+
if (generateRange2 !== undefined) {
|
|
53
|
+
diagnostic.start = generateRange2[0];
|
|
54
|
+
diagnostic.length = generateRange2[1] - generateRange2[0];
|
|
55
|
+
break;
|
|
49
56
|
}
|
|
50
57
|
}
|
|
51
58
|
}
|
|
52
|
-
return
|
|
59
|
+
return result;
|
|
53
60
|
};
|
|
54
|
-
languageService.getCompletionsAtPosition = (fileName, position,
|
|
55
|
-
|
|
61
|
+
languageService.getCompletionsAtPosition = (fileName, position, ...rests) => {
|
|
62
|
+
const result = getCompletionsAtPosition(fileName, position, ...rests);
|
|
63
|
+
if (!result) {
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
56
66
|
const language = getLanguage();
|
|
57
|
-
if (language) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
67
|
+
if (!language) {
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
const [serviceScript, _targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
71
|
+
if (!serviceScript || !(sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode)) {
|
|
72
|
+
return result;
|
|
73
|
+
}
|
|
74
|
+
for (const sourceOffset of (0, transform_1.toSourceOffsets)(sourceScript, language, serviceScript, position, () => true)) {
|
|
75
|
+
const generatedOffset2 = (0, transform_1.toGeneratedOffset)(language, serviceScript, sourceScript, sourceOffset[1], (data) => !!data.__importCompletion);
|
|
76
|
+
if (generatedOffset2 !== undefined) {
|
|
77
|
+
const completion2 = getCompletionsAtPosition(fileName, generatedOffset2, ...rests);
|
|
78
|
+
if (completion2) {
|
|
79
|
+
const nameToIndex = new Map(result.entries.map((entry, index) => [entry.name, index]));
|
|
80
|
+
for (const entry of completion2.entries) {
|
|
81
|
+
if (entry.kind === 'warning') {
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
if (nameToIndex.has(entry.name)) {
|
|
85
|
+
const index = nameToIndex.get(entry.name);
|
|
86
|
+
const existingEntry = result.entries[index];
|
|
87
|
+
if (existingEntry.kind === 'warning') {
|
|
88
|
+
result.entries[index] = entry;
|
|
70
89
|
}
|
|
71
90
|
}
|
|
91
|
+
else {
|
|
92
|
+
result.entries.push(entry);
|
|
93
|
+
}
|
|
72
94
|
}
|
|
73
95
|
}
|
|
74
96
|
}
|
|
75
97
|
}
|
|
76
98
|
return result;
|
|
77
99
|
};
|
|
78
|
-
languageService.getCodeFixesAtPosition = (fileName, start, end, errorCodes,
|
|
79
|
-
let
|
|
100
|
+
languageService.getCodeFixesAtPosition = (fileName, start, end, errorCodes, ...rests) => {
|
|
101
|
+
let result = getCodeFixesAtPosition(fileName, start, end, errorCodes, ...rests);
|
|
102
|
+
// Property 'xxx' does not exist on type 'yyy'.ts(2339)
|
|
103
|
+
if (!errorCodes.includes(2339)) {
|
|
104
|
+
return result;
|
|
105
|
+
}
|
|
80
106
|
const language = getLanguage();
|
|
81
|
-
if (language
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
107
|
+
if (!language) {
|
|
108
|
+
return result;
|
|
109
|
+
}
|
|
110
|
+
const [serviceScript, _targetScript, sourceScript] = (0, utils_1.getServiceScript)(language, fileName);
|
|
111
|
+
if (!serviceScript || !(sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode)) {
|
|
112
|
+
return result;
|
|
113
|
+
}
|
|
114
|
+
for (const sourceRange of (0, transform_1.toSourceRanges)(sourceScript, language, serviceScript, start, end, true, () => true)) {
|
|
115
|
+
const generateRange2 = (0, transform_1.toGeneratedRange)(language, serviceScript, sourceScript, sourceRange[1], sourceRange[2], (data) => !!data.__importCompletion);
|
|
116
|
+
if (generateRange2 !== undefined) {
|
|
117
|
+
let importFixes = getCodeFixesAtPosition(fileName, generateRange2[0], generateRange2[1], [2304], // Cannot find name 'xxx'.ts(2304)
|
|
118
|
+
...rests);
|
|
119
|
+
importFixes = importFixes.filter(fix => fix.fixName === 'import');
|
|
120
|
+
result = result.concat(importFixes);
|
|
95
121
|
}
|
|
96
122
|
}
|
|
97
|
-
return
|
|
123
|
+
return result;
|
|
98
124
|
};
|
|
99
125
|
}
|
|
100
126
|
function postprocessLanguageService(ts, language, languageService, vueOptions, asScriptId) {
|
|
101
127
|
const proxyCache = new Map();
|
|
102
128
|
const getProxyMethod = (target, p) => {
|
|
103
129
|
switch (p) {
|
|
130
|
+
case 'findReferences':
|
|
131
|
+
return findReferences(target[p]);
|
|
104
132
|
case 'getCompletionsAtPosition':
|
|
105
133
|
return getCompletionsAtPosition(target[p]);
|
|
106
134
|
case 'getCompletionEntryDetails':
|
|
@@ -126,10 +154,43 @@ function postprocessLanguageService(ts, language, languageService, vueOptions, a
|
|
|
126
154
|
return Reflect.set(target, p, value, receiver);
|
|
127
155
|
},
|
|
128
156
|
});
|
|
157
|
+
function findReferences(findReferences) {
|
|
158
|
+
return (fileName, ...rest) => {
|
|
159
|
+
const result = findReferences(fileName, ...rest);
|
|
160
|
+
if (!result) {
|
|
161
|
+
return result;
|
|
162
|
+
}
|
|
163
|
+
// #5719
|
|
164
|
+
for (const { references } of result) {
|
|
165
|
+
for (const reference of references) {
|
|
166
|
+
const sourceScript = language.scripts.get(asScriptId(reference.fileName));
|
|
167
|
+
const root = sourceScript?.generated?.root;
|
|
168
|
+
if (!sourceScript || !(root instanceof language_core_1.VueVirtualCode)) {
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
const styles = root.sfc.styles;
|
|
172
|
+
if (!styles.length) {
|
|
173
|
+
return result;
|
|
174
|
+
}
|
|
175
|
+
const isInStyle = styles.some(style => reference.textSpan.start >= style.startTagEnd
|
|
176
|
+
&& reference.textSpan.start + reference.textSpan.length <= style.endTagStart);
|
|
177
|
+
if (!isInStyle) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
const leadingChar = sourceScript.snapshot.getText(reference.textSpan.start - 1, reference.textSpan.start);
|
|
181
|
+
if (leadingChar === '.') {
|
|
182
|
+
reference.textSpan.start--;
|
|
183
|
+
reference.textSpan.length++;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return result;
|
|
188
|
+
};
|
|
189
|
+
}
|
|
129
190
|
function getCompletionsAtPosition(getCompletionsAtPosition) {
|
|
130
|
-
return (filePath, position,
|
|
191
|
+
return (filePath, position, ...rests) => {
|
|
131
192
|
const fileName = filePath.replace(windowsPathReg, '/');
|
|
132
|
-
const result = getCompletionsAtPosition(fileName, position,
|
|
193
|
+
const result = getCompletionsAtPosition(fileName, position, ...rests);
|
|
133
194
|
if (result) {
|
|
134
195
|
resolveCompletionResult(ts, language, asScriptId, vueOptions, fileName, position, result);
|
|
135
196
|
}
|
|
@@ -154,8 +215,8 @@ function postprocessLanguageService(ts, language, languageService, vueOptions, a
|
|
|
154
215
|
};
|
|
155
216
|
}
|
|
156
217
|
function getDefinitionAndBoundSpan(getDefinitionAndBoundSpan) {
|
|
157
|
-
return (fileName, position) => {
|
|
158
|
-
const result = getDefinitionAndBoundSpan(fileName, position);
|
|
218
|
+
return (fileName, position, ...rests) => {
|
|
219
|
+
const result = getDefinitionAndBoundSpan(fileName, position, ...rests);
|
|
159
220
|
const program = languageService.getProgram();
|
|
160
221
|
const sourceScript = language.scripts.get(asScriptId(fileName));
|
|
161
222
|
const root = sourceScript?.generated?.root;
|
|
@@ -163,26 +224,6 @@ function postprocessLanguageService(ts, language, languageService, vueOptions, a
|
|
|
163
224
|
return result;
|
|
164
225
|
}
|
|
165
226
|
if (!result?.definitions?.length) {
|
|
166
|
-
const { template } = root.sfc;
|
|
167
|
-
if (template) {
|
|
168
|
-
const textSpan = {
|
|
169
|
-
start: template.start + 1,
|
|
170
|
-
length: 'template'.length,
|
|
171
|
-
};
|
|
172
|
-
if (position >= textSpan.start && position <= textSpan.start + textSpan.length) {
|
|
173
|
-
return {
|
|
174
|
-
textSpan,
|
|
175
|
-
definitions: [{
|
|
176
|
-
fileName,
|
|
177
|
-
textSpan,
|
|
178
|
-
kind: ts.ScriptElementKind.scriptElement,
|
|
179
|
-
name: fileName,
|
|
180
|
-
containerKind: ts.ScriptElementKind.unknown,
|
|
181
|
-
containerName: '',
|
|
182
|
-
}],
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
227
|
return;
|
|
187
228
|
}
|
|
188
229
|
if (!root.sfc.template
|
|
@@ -236,16 +277,25 @@ function postprocessLanguageService(ts, language, languageService, vueOptions, a
|
|
|
236
277
|
if (start !== textSpan.start || end - start !== textSpan.length) {
|
|
237
278
|
return;
|
|
238
279
|
}
|
|
239
|
-
if (
|
|
240
|
-
|
|
280
|
+
if (ts.isIndexedAccessTypeNode(type)) {
|
|
281
|
+
const pos = type.indexType.getStart(sourceFile);
|
|
282
|
+
const res = getDefinitionAndBoundSpan(fileName, pos, ...rests);
|
|
283
|
+
if (res?.definitions?.length) {
|
|
284
|
+
for (const definition of res.definitions) {
|
|
285
|
+
definitions.add(definition);
|
|
286
|
+
}
|
|
287
|
+
skippedDefinitions.push(definition);
|
|
288
|
+
}
|
|
241
289
|
}
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
290
|
+
else if (ts.isImportTypeNode(type)) {
|
|
291
|
+
const pos = type.argument.getStart(sourceFile);
|
|
292
|
+
const res = getDefinitionAndBoundSpan(fileName, pos, ...rests);
|
|
293
|
+
if (res?.definitions?.length) {
|
|
294
|
+
for (const definition of res.definitions) {
|
|
295
|
+
definitions.add(definition);
|
|
296
|
+
}
|
|
297
|
+
skippedDefinitions.push(definition);
|
|
247
298
|
}
|
|
248
|
-
skippedDefinitions.push(definition);
|
|
249
299
|
}
|
|
250
300
|
}
|
|
251
301
|
};
|
|
@@ -283,6 +333,7 @@ function resolveCompletionResult(ts, language, asScriptId, vueOptions, fileName,
|
|
|
283
333
|
// modify label
|
|
284
334
|
for (const item of result.entries) {
|
|
285
335
|
if (item.source) {
|
|
336
|
+
const data = item.data;
|
|
286
337
|
const oldName = item.name;
|
|
287
338
|
for (const vueExt of vueOptions.extensions) {
|
|
288
339
|
const suffix = (0, shared_1.capitalize)(vueExt.slice(1)); // .vue -> Vue
|
|
@@ -292,9 +343,8 @@ function resolveCompletionResult(ts, language, asScriptId, vueOptions, fileName,
|
|
|
292
343
|
// #2286
|
|
293
344
|
item.insertText = item.insertText.replace(`${suffix}$1`, '$1');
|
|
294
345
|
}
|
|
295
|
-
if (
|
|
296
|
-
|
|
297
|
-
item.data.__isComponentAutoImport = {
|
|
346
|
+
if (data) {
|
|
347
|
+
data.__vue__componentAutoImport = {
|
|
298
348
|
oldName,
|
|
299
349
|
newName: item.name,
|
|
300
350
|
};
|
|
@@ -302,9 +352,8 @@ function resolveCompletionResult(ts, language, asScriptId, vueOptions, fileName,
|
|
|
302
352
|
break;
|
|
303
353
|
}
|
|
304
354
|
}
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
-
item.data.__isAutoImport = {
|
|
355
|
+
if (data) {
|
|
356
|
+
data.__vue__autoImport = {
|
|
308
357
|
fileName,
|
|
309
358
|
};
|
|
310
359
|
}
|
|
@@ -313,8 +362,8 @@ function resolveCompletionResult(ts, language, asScriptId, vueOptions, fileName,
|
|
|
313
362
|
}
|
|
314
363
|
function resolveCompletionEntryDetails(language, details, data) {
|
|
315
364
|
// modify import statement
|
|
316
|
-
if (data
|
|
317
|
-
const { oldName, newName } = data.
|
|
365
|
+
if (data?.__vue__componentAutoImport) {
|
|
366
|
+
const { oldName, newName } = data.__vue__componentAutoImport;
|
|
318
367
|
for (const codeAction of details?.codeActions ?? []) {
|
|
319
368
|
for (const change of codeAction.changes) {
|
|
320
369
|
for (const textChange of change.textChanges) {
|
|
@@ -323,8 +372,23 @@ function resolveCompletionEntryDetails(language, details, data) {
|
|
|
323
372
|
}
|
|
324
373
|
}
|
|
325
374
|
}
|
|
326
|
-
|
|
327
|
-
|
|
375
|
+
// #5874
|
|
376
|
+
if (data?.__vue__autoImportSuggestions) {
|
|
377
|
+
for (const codeAction of details?.codeActions ?? []) {
|
|
378
|
+
for (const change of codeAction.changes) {
|
|
379
|
+
for (const textChange of change.textChanges) {
|
|
380
|
+
if (data.__vue__componentAutoImport) {
|
|
381
|
+
const { oldName, newName } = data.__vue__componentAutoImport;
|
|
382
|
+
textChange.newText = textChange.newText.replace('import type ' + oldName + ' from ', 'import ' + newName + ' from ');
|
|
383
|
+
}
|
|
384
|
+
const { entryName } = data.__vue__autoImportSuggestions;
|
|
385
|
+
textChange.newText = textChange.newText.replace('import type { ' + entryName + ' } from ', 'import { ' + entryName + ' } from ');
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
if (data?.__vue__autoImport) {
|
|
391
|
+
const { fileName } = data.__vue__autoImport;
|
|
328
392
|
const sourceScript = language.scripts.get(fileName);
|
|
329
393
|
if (sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode) {
|
|
330
394
|
const { vueSfc } = sourceScript.generated.root;
|
|
@@ -3,14 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getComponentDirectives = getComponentDirectives;
|
|
4
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
|
-
const builtInDirectives = new Set([
|
|
7
|
-
'vBind',
|
|
8
|
-
'vIf',
|
|
9
|
-
'vOn',
|
|
10
|
-
'vOnce',
|
|
11
|
-
'vShow',
|
|
12
|
-
'vSlot',
|
|
13
|
-
]);
|
|
14
6
|
function getComponentDirectives(ts, program, fileName) {
|
|
15
7
|
const sourceFile = program.getSourceFile(fileName);
|
|
16
8
|
if (!sourceFile) {
|
|
@@ -23,7 +15,6 @@ function getComponentDirectives(ts, program, fileName) {
|
|
|
23
15
|
}
|
|
24
16
|
return directives.type.getProperties()
|
|
25
17
|
.map(({ name }) => name)
|
|
26
|
-
.filter(name => name.
|
|
27
|
-
.filter(name => !builtInDirectives.has(name));
|
|
18
|
+
.filter(name => name.match(/^v[A-Z]/));
|
|
28
19
|
}
|
|
29
20
|
//# sourceMappingURL=getComponentDirectives.js.map
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Language, VueVirtualCode } from '@vue/language-core';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
import type { ComponentMeta } from 'vue-component-meta';
|
|
4
|
+
export declare function getComponentMeta(ts: typeof import('typescript'), program: ts.Program, language: Language<string>, sourceFile: ts.SourceFile, virtualCode: VueVirtualCode, tag: string): ComponentMeta | undefined;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getComponentMeta = getComponentMeta;
|
|
4
|
+
const componentMeta_1 = require("vue-component-meta/lib/componentMeta");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
function getComponentMeta(ts, program, language, sourceFile, virtualCode, tag) {
|
|
7
|
+
const checker = program.getTypeChecker();
|
|
8
|
+
const componentType = (0, utils_1.getComponentType)(ts, checker, sourceFile, virtualCode, tag);
|
|
9
|
+
if (!componentType) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
return (0, componentMeta_1.getComponentMeta)(ts, checker, ts.createPrinter(), language, componentType.node, componentType.type, false);
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=getComponentMeta.js.map
|
|
@@ -16,7 +16,7 @@ function getComponentNames(ts, program, { fileName, sfc }) {
|
|
|
16
16
|
.filter(entry => !entry.includes('$') && !entry.startsWith('_'))
|
|
17
17
|
?? [];
|
|
18
18
|
componentNames.push((0, utils_1.getSelfComponentName)(fileName));
|
|
19
|
-
componentNames.push(...language_core_1.tsCodegen.get(sfc)?.
|
|
19
|
+
componentNames.push(...language_core_1.tsCodegen.get(sfc)?.getImportedComponents() ?? []);
|
|
20
20
|
return [...new Set(componentNames)];
|
|
21
21
|
}
|
|
22
22
|
//# sourceMappingURL=getComponentNames.js.map
|
|
@@ -13,7 +13,7 @@ function getComponentSlots(ts, program, virtualCode) {
|
|
|
13
13
|
return [];
|
|
14
14
|
}
|
|
15
15
|
const checker = program.getTypeChecker();
|
|
16
|
-
const assignName = codegen.
|
|
16
|
+
const assignName = codegen.getScriptSetupRanges()?.defineSlots?.name ?? language_core_1.names.slots;
|
|
17
17
|
const slots = (0, utils_1.getVariableType)(ts, checker, sourceFile, assignName);
|
|
18
18
|
if (!slots) {
|
|
19
19
|
return [];
|
|
@@ -1,2 +1,5 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
|
-
export declare function getElementAttrs(ts: typeof import('typescript'), program: ts.Program, tag: string):
|
|
2
|
+
export declare function getElementAttrs(ts: typeof import('typescript'), program: ts.Program, fileName: string, tag: string): {
|
|
3
|
+
name: string;
|
|
4
|
+
type: string;
|
|
5
|
+
}[];
|
|
@@ -2,16 +2,24 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getElementAttrs = getElementAttrs;
|
|
4
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
function getElementAttrs(ts, program, fileName, tag) {
|
|
7
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
8
|
+
if (!sourceFile) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
6
11
|
const checker = program.getTypeChecker();
|
|
7
|
-
const elements =
|
|
12
|
+
const elements = (0, utils_1.getVariableType)(ts, checker, sourceFile, language_core_1.names.intrinsics);
|
|
8
13
|
if (!elements) {
|
|
9
14
|
return [];
|
|
10
15
|
}
|
|
11
|
-
const elementType =
|
|
16
|
+
const elementType = elements.type.getProperty(tag);
|
|
12
17
|
if (!elementType) {
|
|
13
18
|
return [];
|
|
14
19
|
}
|
|
15
|
-
return checker.getTypeOfSymbol(elementType).getProperties().map(c =>
|
|
20
|
+
return checker.getTypeOfSymbol(elementType).getProperties().map(c => ({
|
|
21
|
+
name: c.name,
|
|
22
|
+
type: checker.typeToString(checker.getTypeOfSymbolAtLocation(c, sourceFile), elements.node, ts.TypeFormatFlags.NoTruncation),
|
|
23
|
+
}));
|
|
16
24
|
}
|
|
17
25
|
//# sourceMappingURL=getElementAttrs.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
|
-
export declare function getElementNames(ts: typeof import('typescript'), program: ts.Program): string[];
|
|
2
|
+
export declare function getElementNames(ts: typeof import('typescript'), program: ts.Program, fileName: string): string[];
|
|
@@ -2,12 +2,17 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getElementNames = getElementNames;
|
|
4
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
function getElementNames(ts, program, fileName) {
|
|
7
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
8
|
+
if (!sourceFile) {
|
|
9
|
+
return [];
|
|
10
|
+
}
|
|
6
11
|
const checker = program.getTypeChecker();
|
|
7
|
-
const elements =
|
|
12
|
+
const elements = (0, utils_1.getVariableType)(ts, checker, sourceFile, language_core_1.names.intrinsics);
|
|
8
13
|
if (!elements) {
|
|
9
14
|
return [];
|
|
10
15
|
}
|
|
11
|
-
return
|
|
16
|
+
return elements.type.getProperties().map(c => c.name);
|
|
12
17
|
}
|
|
13
18
|
//# sourceMappingURL=getElementNames.js.map
|
package/lib/requests/index.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
|
+
import type { VueCompletionData } from '../common.js';
|
|
2
3
|
type Response<T> = T | null | undefined | Promise<T | null | undefined>;
|
|
3
4
|
export interface Requests {
|
|
4
5
|
collectExtractProps(fileName: string, templateCodeRange: [number, number]): Response<ReturnType<typeof import('./collectExtractProps.js')['collectExtractProps']>>;
|
|
5
6
|
getImportPathForFile(fileName: string, incomingFileName: string, preferences: ts.UserPreferences): Response<ReturnType<typeof import('./getImportPathForFile.js')['getImportPathForFile']>>;
|
|
6
7
|
isRefAtPosition(fileName: string, position: number): Response<ReturnType<typeof import('./isRefAtPosition.js')['isRefAtPosition']>>;
|
|
7
8
|
getComponentDirectives(fileName: string): Response<ReturnType<typeof import('./getComponentDirectives.js')['getComponentDirectives']>>;
|
|
8
|
-
getComponentEvents(fileName: string, tag: string): Response<ReturnType<typeof import('./getComponentEvents.js')['getComponentEvents']>>;
|
|
9
9
|
getComponentNames(fileName: string): Response<ReturnType<typeof import('./getComponentNames.js')['getComponentNames']>>;
|
|
10
|
-
|
|
10
|
+
getComponentMeta(fileName: string, tag: string): Response<ReturnType<typeof import('./getComponentMeta.js')['getComponentMeta']>>;
|
|
11
11
|
getComponentSlots(fileName: string): Response<ReturnType<typeof import('./getComponentSlots.js')['getComponentSlots']>>;
|
|
12
12
|
getElementAttrs(fileName: string, tag: string): Response<ReturnType<typeof import('./getElementAttrs.js')['getElementAttrs']>>;
|
|
13
13
|
getElementNames(fileName: string): Response<ReturnType<typeof import('./getElementNames.js')['getElementNames']>>;
|
|
@@ -15,7 +15,7 @@ export interface Requests {
|
|
|
15
15
|
getDocumentHighlights(fileName: string, position: number): Response<ts.DocumentHighlights[]>;
|
|
16
16
|
getEncodedSemanticClassifications(fileName: string, span: ts.TextSpan): Response<ts.Classifications>;
|
|
17
17
|
getQuickInfoAtPosition(fileName: string, position: ts.LineAndCharacter): Response<string>;
|
|
18
|
-
getAutoImportSuggestions(fileName: string, position: number
|
|
19
|
-
resolveAutoImportCompletionEntry(data:
|
|
18
|
+
getAutoImportSuggestions(fileName: string, position: number): Response<ts.CompletionInfo>;
|
|
19
|
+
resolveAutoImportCompletionEntry(data: VueCompletionData): Response<ts.CompletionEntryDetails>;
|
|
20
20
|
}
|
|
21
21
|
export {};
|
package/lib/requests/utils.d.ts
CHANGED
|
@@ -6,6 +6,6 @@ export declare function getComponentType(ts: typeof import('typescript'), checke
|
|
|
6
6
|
} | undefined;
|
|
7
7
|
export declare function getSelfComponentName(fileName: string): Capitalize<string>;
|
|
8
8
|
export declare function getVariableType(ts: typeof import('typescript'), checker: ts.TypeChecker, sourceFile: ts.SourceFile, name: string): {
|
|
9
|
-
node: ts.
|
|
9
|
+
node: ts.VariableDeclaration;
|
|
10
10
|
type: ts.Type;
|
|
11
11
|
} | undefined;
|
package/lib/requests/utils.js
CHANGED
|
@@ -1,11 +1,44 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
36
|
exports.getComponentType = getComponentType;
|
|
4
37
|
exports.getSelfComponentName = getSelfComponentName;
|
|
5
38
|
exports.getVariableType = getVariableType;
|
|
6
39
|
const language_core_1 = require("@vue/language-core");
|
|
7
40
|
const shared_1 = require("@vue/shared");
|
|
8
|
-
const path = require("path-browserify");
|
|
41
|
+
const path = __importStar(require("path-browserify"));
|
|
9
42
|
function getComponentType(ts, checker, sourceFile, { fileName, sfc }, tag) {
|
|
10
43
|
const testNames = new Set([
|
|
11
44
|
tag,
|
|
@@ -13,7 +46,7 @@ function getComponentType(ts, checker, sourceFile, { fileName, sfc }, tag) {
|
|
|
13
46
|
(0, shared_1.capitalize)((0, shared_1.camelize)(tag)),
|
|
14
47
|
]);
|
|
15
48
|
const codegen = language_core_1.tsCodegen.get(sfc);
|
|
16
|
-
for (const importedName of codegen?.
|
|
49
|
+
for (const importedName of codegen?.getImportedComponents() ?? []) {
|
|
17
50
|
if (testNames.has(importedName)) {
|
|
18
51
|
const node = searchDefaultImportIdentifier(ts, sourceFile, importedName);
|
|
19
52
|
if (node) {
|
|
@@ -30,27 +63,26 @@ function getComponentType(ts, checker, sourceFile, { fileName, sfc }, tag) {
|
|
|
30
63
|
let componentSymbol = components.type.getProperty(nameParts[0])
|
|
31
64
|
?? components.type.getProperty((0, shared_1.camelize)(nameParts[0]))
|
|
32
65
|
?? components.type.getProperty((0, shared_1.capitalize)((0, shared_1.camelize)(nameParts[0])));
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const name = getSelfComponentName(fileName);
|
|
36
|
-
if (name === (0, shared_1.capitalize)((0, shared_1.camelize)(tag))) {
|
|
37
|
-
componentType = getVariableType(ts, checker, sourceFile, language_core_1.names._export)?.type;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
66
|
+
if (componentSymbol) {
|
|
67
|
+
let componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
42
68
|
for (let i = 1; i < nameParts.length; i++) {
|
|
43
69
|
componentSymbol = componentType.getProperty(nameParts[i]);
|
|
44
70
|
if (componentSymbol) {
|
|
45
71
|
componentType = checker.getTypeOfSymbolAtLocation(componentSymbol, components.node);
|
|
46
72
|
}
|
|
47
73
|
}
|
|
74
|
+
if (componentType) {
|
|
75
|
+
return {
|
|
76
|
+
node: components.node,
|
|
77
|
+
type: componentType,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
48
80
|
}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
81
|
+
else {
|
|
82
|
+
const name = getSelfComponentName(fileName);
|
|
83
|
+
if (name === (0, shared_1.capitalize)((0, shared_1.camelize)(tag))) {
|
|
84
|
+
return getVariableType(ts, checker, sourceFile, language_core_1.names._export);
|
|
85
|
+
}
|
|
54
86
|
}
|
|
55
87
|
}
|
|
56
88
|
const selfName = getSelfComponentName(fileName);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/typescript-plugin",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.2.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -13,14 +13,15 @@
|
|
|
13
13
|
"directory": "packages/typescript-plugin"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@volar/typescript": "2.4.
|
|
17
|
-
"@vue/language-core": "3.
|
|
16
|
+
"@volar/typescript": "2.4.27",
|
|
17
|
+
"@vue/language-core": "3.2.0",
|
|
18
18
|
"@vue/shared": "^3.5.0",
|
|
19
|
-
"path-browserify": "^1.0.1"
|
|
19
|
+
"path-browserify": "^1.0.1",
|
|
20
|
+
"vue-component-meta": "3.2.0"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"@types/node": "^22.10.4",
|
|
23
24
|
"@types/path-browserify": "^1.0.1"
|
|
24
25
|
},
|
|
25
|
-
"gitHead": "
|
|
26
|
+
"gitHead": "3138110d767d3d6110899bc46518b53c4b456271"
|
|
26
27
|
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getComponentEvents = getComponentEvents;
|
|
4
|
-
const utils_1 = require("./utils");
|
|
5
|
-
function getComponentEvents(ts, program, virtualCode, tag) {
|
|
6
|
-
const sourceFile = program.getSourceFile(virtualCode.fileName);
|
|
7
|
-
if (!sourceFile) {
|
|
8
|
-
return [];
|
|
9
|
-
}
|
|
10
|
-
const checker = program.getTypeChecker();
|
|
11
|
-
const componentType = (0, utils_1.getComponentType)(ts, checker, sourceFile, virtualCode, tag);
|
|
12
|
-
if (!componentType) {
|
|
13
|
-
return [];
|
|
14
|
-
}
|
|
15
|
-
const result = new Set();
|
|
16
|
-
// for (const sig of componentType.getCallSignatures()) {
|
|
17
|
-
// const emitParam = sig.parameters[1];
|
|
18
|
-
// if (emitParam) {
|
|
19
|
-
// // TODO
|
|
20
|
-
// }
|
|
21
|
-
// }
|
|
22
|
-
for (const sig of componentType.type.getConstructSignatures()) {
|
|
23
|
-
const instanceType = sig.getReturnType();
|
|
24
|
-
const emitSymbol = instanceType.getProperty('$emit');
|
|
25
|
-
if (emitSymbol) {
|
|
26
|
-
const emitType = checker.getTypeOfSymbolAtLocation(emitSymbol, componentType.node);
|
|
27
|
-
for (const call of emitType.getCallSignatures()) {
|
|
28
|
-
if (call.parameters.length) {
|
|
29
|
-
const eventNameParamSymbol = call.parameters[0];
|
|
30
|
-
const eventNameParamType = checker.getTypeOfSymbolAtLocation(eventNameParamSymbol, componentType.node);
|
|
31
|
-
if (eventNameParamType.isStringLiteral()) {
|
|
32
|
-
result.add(eventNameParamType.value);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
return [...result];
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=getComponentEvents.js.map
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { VueVirtualCode } from '@vue/language-core';
|
|
2
|
-
import type * as ts from 'typescript';
|
|
3
|
-
export interface ComponentPropInfo {
|
|
4
|
-
name: string;
|
|
5
|
-
required?: boolean;
|
|
6
|
-
deprecated?: boolean;
|
|
7
|
-
isAttribute?: boolean;
|
|
8
|
-
documentation?: string;
|
|
9
|
-
values?: string[];
|
|
10
|
-
}
|
|
11
|
-
export declare function getComponentProps(ts: typeof import('typescript'), program: ts.Program, virtualCode: VueVirtualCode, tag: string): ComponentPropInfo[];
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getComponentProps = getComponentProps;
|
|
4
|
-
const utils_1 = require("./utils");
|
|
5
|
-
function getComponentProps(ts, program, virtualCode, tag) {
|
|
6
|
-
const sourceFile = program.getSourceFile(virtualCode.fileName);
|
|
7
|
-
if (!sourceFile) {
|
|
8
|
-
return [];
|
|
9
|
-
}
|
|
10
|
-
const checker = program.getTypeChecker();
|
|
11
|
-
const componentType = (0, utils_1.getComponentType)(ts, checker, sourceFile, virtualCode, tag);
|
|
12
|
-
if (!componentType) {
|
|
13
|
-
return [];
|
|
14
|
-
}
|
|
15
|
-
const result = new Map();
|
|
16
|
-
for (const sig of componentType.type.getCallSignatures()) {
|
|
17
|
-
if (sig.parameters.length) {
|
|
18
|
-
const propParam = sig.parameters[0];
|
|
19
|
-
const propsType = checker.getTypeOfSymbolAtLocation(propParam, componentType.node);
|
|
20
|
-
const props = propsType.getProperties();
|
|
21
|
-
for (const prop of props) {
|
|
22
|
-
handlePropSymbol(prop);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
for (const sig of componentType.type.getConstructSignatures()) {
|
|
27
|
-
const instanceType = sig.getReturnType();
|
|
28
|
-
const propsSymbol = instanceType.getProperty('$props');
|
|
29
|
-
if (propsSymbol) {
|
|
30
|
-
const propsType = checker.getTypeOfSymbolAtLocation(propsSymbol, componentType.node);
|
|
31
|
-
const props = propsType.getProperties();
|
|
32
|
-
for (const prop of props) {
|
|
33
|
-
handlePropSymbol(prop);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
return [...result.values()];
|
|
38
|
-
function handlePropSymbol(prop) {
|
|
39
|
-
if (prop.flags & ts.SymbolFlags.Method) { // #2443
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
const name = prop.name;
|
|
43
|
-
const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
|
|
44
|
-
const { documentation, deprecated, } = generateDocumentation(prop.getDocumentationComment(checker), prop.getJsDocTags());
|
|
45
|
-
const values = [];
|
|
46
|
-
const type = checker.getTypeOfSymbol(prop);
|
|
47
|
-
const subTypes = type.types;
|
|
48
|
-
if (subTypes) {
|
|
49
|
-
for (const subType of subTypes) {
|
|
50
|
-
const value = subType.value;
|
|
51
|
-
if (value) {
|
|
52
|
-
values.push(value);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
let isAttribute;
|
|
57
|
-
for (const { parent } of checker.getRootSymbols(prop).flatMap(root => root.declarations ?? [])) {
|
|
58
|
-
if (!ts.isInterfaceDeclaration(parent)) {
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
const { text } = parent.name;
|
|
62
|
-
if (text.endsWith('HTMLAttributes')
|
|
63
|
-
|| text === 'AriaAttributes'
|
|
64
|
-
|| text === 'SVGAttributes') {
|
|
65
|
-
isAttribute = true;
|
|
66
|
-
break;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
result.set(name, {
|
|
70
|
-
name,
|
|
71
|
-
required,
|
|
72
|
-
deprecated,
|
|
73
|
-
isAttribute,
|
|
74
|
-
documentation,
|
|
75
|
-
values,
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
function generateDocumentation(parts, jsDocTags) {
|
|
80
|
-
const parsedComment = _symbolDisplayPartsToMarkdown(parts);
|
|
81
|
-
const parsedJsDoc = _jsDocTagInfoToMarkdown(jsDocTags);
|
|
82
|
-
const documentation = [parsedComment, parsedJsDoc].filter(str => !!str).join('\n\n');
|
|
83
|
-
const deprecated = jsDocTags.some(tag => tag.name === 'deprecated');
|
|
84
|
-
return {
|
|
85
|
-
documentation,
|
|
86
|
-
deprecated,
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function _symbolDisplayPartsToMarkdown(parts) {
|
|
90
|
-
return parts.map(part => {
|
|
91
|
-
switch (part.kind) {
|
|
92
|
-
case 'keyword':
|
|
93
|
-
return `\`${part.text}\``;
|
|
94
|
-
case 'functionName':
|
|
95
|
-
return `**${part.text}**`;
|
|
96
|
-
default:
|
|
97
|
-
return part.text;
|
|
98
|
-
}
|
|
99
|
-
}).join('');
|
|
100
|
-
}
|
|
101
|
-
function _jsDocTagInfoToMarkdown(jsDocTags) {
|
|
102
|
-
return jsDocTags.map(tag => {
|
|
103
|
-
const tagName = `*@${tag.name}*`;
|
|
104
|
-
const tagText = tag.text?.map(t => {
|
|
105
|
-
if (t.kind === 'parameterName') {
|
|
106
|
-
return `\`${t.text}\``;
|
|
107
|
-
}
|
|
108
|
-
else {
|
|
109
|
-
return t.text;
|
|
110
|
-
}
|
|
111
|
-
}).join('') || '';
|
|
112
|
-
return `${tagName} ${tagText}`;
|
|
113
|
-
}).join('\n\n');
|
|
114
|
-
}
|
|
115
|
-
//# sourceMappingURL=getComponentProps.js.map
|