@vue/typescript-plugin 3.0.7-alpha.0 → 3.0.7
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 +76 -80
- package/lib/common.js +6 -8
- package/lib/proxy.d.ts +3 -0
- package/lib/proxy.js +227 -0
- package/lib/requests/collectExtractProps.d.ts +1 -1
- package/lib/requests/collectExtractProps.js +2 -2
- package/lib/requests/getComponentEvents.js +2 -2
- package/lib/requests/getComponentHighlights.d.ts +1 -0
- package/lib/requests/getComponentHighlights.js +3 -0
- package/lib/requests/getComponentNames.js +1 -1
- package/lib/requests/getComponentProps.js +2 -2
- package/lib/requests/getCurrentComponentSlots.d.ts +1 -0
- package/lib/requests/getCurrentComponentSlots.js +3 -0
- package/lib/requests/getDefineSlotNames.d.ts +1 -0
- package/lib/requests/getDefineSlotNames.js +3 -0
- package/lib/requests/getDefineSlots.d.ts +2 -0
- package/lib/requests/getDefineSlots.js +16 -0
- package/lib/requests/getElementNames.js +1 -1
- package/lib/requests/getImportPathForFile.d.ts +1 -3
- package/lib/requests/getImportPathForFile.js +3 -5
- package/lib/requests/getMissingPropsDiagnostics.d.ts +10 -0
- package/lib/requests/getMissingPropsDiagnostics.js +40 -0
- package/lib/requests/getPropertiesAtLocation.d.ts +2 -3
- package/lib/requests/getPropertiesAtLocation.js +11 -3
- package/lib/requests/getReactiveReferences.d.ts +12 -0
- package/lib/requests/getReactiveReferences.js +605 -0
- package/lib/requests/getReactiveVariableSpans.d.ts +3 -0
- package/lib/requests/getReactiveVariableSpans.js +30 -0
- package/lib/requests/getSemanticClassfications.d.ts +3 -0
- package/lib/requests/getSemanticClassfications.js +8 -0
- package/lib/requests/getVariableProperties.d.ts +10 -0
- package/lib/requests/getVariableProperties.js +16 -0
- package/lib/requests/index.d.ts +2 -1
- package/lib/requests/isRefAtLocation.d.ts +3 -0
- package/lib/requests/isRefAtLocation.js +55 -0
- package/lib/requests/isRefAtPosition.d.ts +3 -0
- package/lib/requests/isRefAtPosition.js +54 -0
- package/lib/requests/resolveModuleName.d.ts +4 -0
- package/lib/requests/resolveModuleName.js +28 -0
- package/package.json +3 -3
package/index.js
CHANGED
|
@@ -11,13 +11,14 @@ const getComponentSlots_1 = require("./lib/requests/getComponentSlots");
|
|
|
11
11
|
const getElementAttrs_1 = require("./lib/requests/getElementAttrs");
|
|
12
12
|
const getElementNames_1 = require("./lib/requests/getElementNames");
|
|
13
13
|
const getImportPathForFile_1 = require("./lib/requests/getImportPathForFile");
|
|
14
|
-
const
|
|
14
|
+
const getReactiveReferences_1 = require("./lib/requests/getReactiveReferences");
|
|
15
|
+
const isRefAtPosition_1 = require("./lib/requests/isRefAtPosition");
|
|
15
16
|
const windowsPathReg = /\\/g;
|
|
16
17
|
const project2Service = new WeakMap();
|
|
17
18
|
module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)((ts, info) => {
|
|
18
19
|
const vueOptions = getVueCompilerOptions();
|
|
19
|
-
vue.writeGlobalTypes(vueOptions, ts.sys.writeFile);
|
|
20
20
|
const languagePlugin = vue.createVueLanguagePlugin(ts, info.languageServiceHost.getCompilationSettings(), vueOptions, id => id);
|
|
21
|
+
vue.writeGlobalTypes(vueOptions, ts.sys.writeFile);
|
|
21
22
|
addVueCommands();
|
|
22
23
|
return {
|
|
23
24
|
languagePlugins: [languagePlugin],
|
|
@@ -47,135 +48,130 @@ module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)(
|
|
|
47
48
|
function addVueCommands() {
|
|
48
49
|
const projectService = info.project.projectService;
|
|
49
50
|
projectService.logger.info('Vue: called handler processing ' + info.project.projectKind);
|
|
50
|
-
|
|
51
|
-
if (!session) {
|
|
51
|
+
if (!info.session) {
|
|
52
52
|
projectService.logger.info('Vue: there is no session in info.');
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
+
const session = info.session;
|
|
55
56
|
if (!session.addProtocolHandler) {
|
|
56
57
|
// addProtocolHandler was introduced in TS 4.4 or 4.5 in 2021, see https://github.com/microsoft/TypeScript/issues/43893
|
|
57
58
|
projectService.logger.info('Vue: there is no addProtocolHandler method.');
|
|
58
59
|
return;
|
|
59
60
|
}
|
|
60
|
-
|
|
61
|
+
// @ts-expect-error
|
|
62
|
+
const handlers = session.handlers;
|
|
63
|
+
if (handlers.has('_vue:projectInfo')) {
|
|
61
64
|
return;
|
|
62
65
|
}
|
|
63
66
|
session.addProtocolHandler('_vue:projectInfo', request => {
|
|
64
|
-
return
|
|
67
|
+
return handlers.get('projectInfo')(request);
|
|
65
68
|
});
|
|
66
69
|
session.addProtocolHandler('_vue:documentHighlights-full', request => {
|
|
67
|
-
return
|
|
70
|
+
return handlers.get('documentHighlights-full')(request);
|
|
68
71
|
});
|
|
69
72
|
session.addProtocolHandler('_vue:encodedSemanticClassifications-full', request => {
|
|
70
|
-
return
|
|
73
|
+
return handlers.get('encodedSemanticClassifications-full')(request);
|
|
71
74
|
});
|
|
72
75
|
session.addProtocolHandler('_vue:quickinfo', request => {
|
|
73
|
-
return
|
|
76
|
+
return handlers.get('quickinfo')(request);
|
|
74
77
|
});
|
|
75
78
|
session.addProtocolHandler('_vue:collectExtractProps', request => {
|
|
76
79
|
const [fileName, templateCodeRange] = request.arguments;
|
|
77
|
-
const { language,
|
|
78
|
-
return
|
|
79
|
-
response: (0, collectExtractProps_1.collectExtractProps)(ts, language, program, sourceScript, virtualCode, templateCodeRange),
|
|
80
|
-
};
|
|
80
|
+
const { language, languageService, sourceScript, virtualCode } = getLanguageServiceAndVirtualCode(fileName);
|
|
81
|
+
return createResponse((0, collectExtractProps_1.collectExtractProps)(ts, language, languageService.getProgram(), sourceScript, virtualCode, templateCodeRange, sourceScript.generated ? sourceScript.snapshot.getLength() : 0));
|
|
81
82
|
});
|
|
82
83
|
session.addProtocolHandler('_vue:getImportPathForFile', request => {
|
|
83
84
|
const [fileName, incomingFileName, preferences] = request.arguments;
|
|
84
|
-
const { languageServiceHost,
|
|
85
|
-
return
|
|
86
|
-
response: (0, getImportPathForFile_1.getImportPathForFile)(ts, languageServiceHost, program, fileName, incomingFileName, preferences),
|
|
87
|
-
};
|
|
85
|
+
const { languageServiceHost, languageService } = getLanguageService(fileName);
|
|
86
|
+
return createResponse((0, getImportPathForFile_1.getImportPathForFile)(ts, languageServiceHost, languageService.getProgram(), fileName, incomingFileName, preferences));
|
|
88
87
|
});
|
|
89
|
-
session.addProtocolHandler('_vue:
|
|
88
|
+
session.addProtocolHandler('_vue:isRefAtPosition', request => {
|
|
90
89
|
const [fileName, position] = request.arguments;
|
|
91
|
-
const { language,
|
|
92
|
-
return
|
|
93
|
-
response: (0, getPropertiesAtLocation_1.getPropertiesAtLocation)(ts, language, program, sourceScript, virtualCode, position),
|
|
94
|
-
};
|
|
90
|
+
const { language, languageService, sourceScript, virtualCode } = getLanguageServiceAndVirtualCode(fileName);
|
|
91
|
+
return createResponse((0, isRefAtPosition_1.isRefAtPosition)(ts, language, languageService.getProgram(), sourceScript, virtualCode, position, sourceScript.generated ? sourceScript.snapshot.getLength() : 0));
|
|
95
92
|
});
|
|
96
93
|
session.addProtocolHandler('_vue:getComponentDirectives', request => {
|
|
97
94
|
const [fileName] = request.arguments;
|
|
98
|
-
const {
|
|
99
|
-
return
|
|
100
|
-
response: (0, getComponentDirectives_1.getComponentDirectives)(ts, program, fileName),
|
|
101
|
-
};
|
|
95
|
+
const { languageService } = getLanguageService(fileName);
|
|
96
|
+
return createResponse((0, getComponentDirectives_1.getComponentDirectives)(ts, languageService.getProgram(), fileName));
|
|
102
97
|
});
|
|
103
98
|
session.addProtocolHandler('_vue:getComponentEvents', request => {
|
|
104
99
|
const [fileName, tag] = request.arguments;
|
|
105
|
-
const {
|
|
106
|
-
return
|
|
107
|
-
response: (0, getComponentEvents_1.getComponentEvents)(ts, program, fileName, tag),
|
|
108
|
-
};
|
|
100
|
+
const { languageService } = getLanguageService(fileName);
|
|
101
|
+
return createResponse((0, getComponentEvents_1.getComponentEvents)(ts, languageService.getProgram(), fileName, tag));
|
|
109
102
|
});
|
|
110
103
|
session.addProtocolHandler('_vue:getComponentNames', request => {
|
|
111
104
|
const [fileName] = request.arguments;
|
|
112
|
-
const {
|
|
113
|
-
return
|
|
114
|
-
response: (0, getComponentNames_1.getComponentNames)(ts, program, fileName),
|
|
115
|
-
};
|
|
105
|
+
const { languageService } = getLanguageService(fileName);
|
|
106
|
+
return createResponse((0, getComponentNames_1.getComponentNames)(ts, languageService.getProgram(), fileName));
|
|
116
107
|
});
|
|
117
108
|
session.addProtocolHandler('_vue:getComponentProps', request => {
|
|
118
109
|
const [fileName, tag] = request.arguments;
|
|
119
|
-
const {
|
|
120
|
-
return
|
|
121
|
-
response: (0, getComponentProps_1.getComponentProps)(ts, program, fileName, tag),
|
|
122
|
-
};
|
|
110
|
+
const { languageService } = getLanguageService(fileName);
|
|
111
|
+
return createResponse((0, getComponentProps_1.getComponentProps)(ts, languageService.getProgram(), fileName, tag));
|
|
123
112
|
});
|
|
124
113
|
session.addProtocolHandler('_vue:getComponentSlots', request => {
|
|
125
114
|
const [fileName] = request.arguments;
|
|
126
|
-
const {
|
|
127
|
-
return
|
|
128
|
-
response: (0, getComponentSlots_1.getComponentSlots)(ts, program, virtualCode),
|
|
129
|
-
};
|
|
115
|
+
const { languageService, virtualCode } = getLanguageServiceAndVirtualCode(fileName);
|
|
116
|
+
return createResponse((0, getComponentSlots_1.getComponentSlots)(ts, languageService.getProgram(), virtualCode));
|
|
130
117
|
});
|
|
131
118
|
session.addProtocolHandler('_vue:getElementAttrs', request => {
|
|
132
119
|
const [fileName, tag] = request.arguments;
|
|
133
|
-
const {
|
|
134
|
-
return
|
|
135
|
-
response: (0, getElementAttrs_1.getElementAttrs)(ts, program, fileName, tag),
|
|
136
|
-
};
|
|
120
|
+
const { languageService } = getLanguageService(fileName);
|
|
121
|
+
return createResponse((0, getElementAttrs_1.getElementAttrs)(ts, languageService.getProgram(), fileName, tag));
|
|
137
122
|
});
|
|
138
123
|
session.addProtocolHandler('_vue:getElementNames', request => {
|
|
139
124
|
const [fileName] = request.arguments;
|
|
140
|
-
const {
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
|
|
125
|
+
const { languageService } = getLanguageService(fileName);
|
|
126
|
+
return createResponse((0, getElementNames_1.getElementNames)(ts, languageService.getProgram(), fileName));
|
|
127
|
+
});
|
|
128
|
+
session.addProtocolHandler('_vue:getReactiveReferences', request => {
|
|
129
|
+
const [fileName, position] = request.arguments;
|
|
130
|
+
const { languageService, language } = getLanguageService(fileName);
|
|
131
|
+
const sourceScript = language.scripts.get(fileName);
|
|
132
|
+
return createResponse((0, getReactiveReferences_1.getReactiveReferences)(ts, language, languageService, sourceScript, fileName, position, sourceScript?.generated ? sourceScript.snapshot.getLength() : 0));
|
|
144
133
|
});
|
|
145
134
|
projectService.logger.info('Vue specific commands are successfully added.');
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
throw new Error('No source script found for file: ' + fileName);
|
|
135
|
+
function createResponse(res) {
|
|
136
|
+
return {
|
|
137
|
+
response: res,
|
|
138
|
+
responseRequired: true,
|
|
139
|
+
};
|
|
152
140
|
}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
141
|
+
function getLanguageServiceAndVirtualCode(fileName) {
|
|
142
|
+
const service = getLanguageService(fileName);
|
|
143
|
+
const sourceScript = service.language.scripts.get(fileName);
|
|
144
|
+
if (!sourceScript) {
|
|
145
|
+
throw new Error('No source script found for file: ' + fileName);
|
|
146
|
+
}
|
|
147
|
+
const virtualCode = sourceScript.generated?.root;
|
|
148
|
+
if (!(virtualCode instanceof vue.VueVirtualCode)) {
|
|
149
|
+
throw new Error('No virtual code found for file: ' + fileName);
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
...service,
|
|
153
|
+
sourceScript,
|
|
154
|
+
virtualCode,
|
|
155
|
+
};
|
|
156
156
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
157
|
+
function getLanguageService(fileName) {
|
|
158
|
+
// @ts-expect-error
|
|
159
|
+
const { project } = session.getFileAndProject({
|
|
160
|
+
file: fileName,
|
|
161
|
+
projectFileName: undefined,
|
|
162
|
+
});
|
|
163
|
+
const service = project2Service.get(project);
|
|
164
|
+
if (!service) {
|
|
165
|
+
throw new Error('No vue service for project: ' + project.getProjectName());
|
|
166
|
+
}
|
|
167
|
+
const [language, languageServiceHost, languageService] = service;
|
|
168
|
+
return {
|
|
169
|
+
typescript: ts,
|
|
170
|
+
languageService,
|
|
171
|
+
languageServiceHost,
|
|
172
|
+
language,
|
|
173
|
+
};
|
|
171
174
|
}
|
|
172
|
-
const [language, languageServiceHost, languageService] = service;
|
|
173
|
-
return {
|
|
174
|
-
typescript: ts,
|
|
175
|
-
program: languageService.getProgram(),
|
|
176
|
-
languageServiceHost,
|
|
177
|
-
language,
|
|
178
|
-
};
|
|
179
175
|
}
|
|
180
176
|
});
|
|
181
177
|
//# sourceMappingURL=index.js.map
|
package/lib/common.js
CHANGED
|
@@ -20,14 +20,12 @@ function createVueLanguageServiceProxy(ts, language, languageService, vueOptions
|
|
|
20
20
|
};
|
|
21
21
|
return new Proxy(languageService, {
|
|
22
22
|
get(target, p, receiver) {
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return proxyMethod;
|
|
30
|
-
}
|
|
23
|
+
if (!proxyCache.has(p)) {
|
|
24
|
+
proxyCache.set(p, getProxyMethod(target, p));
|
|
25
|
+
}
|
|
26
|
+
const proxyMethod = proxyCache.get(p);
|
|
27
|
+
if (proxyMethod) {
|
|
28
|
+
return proxyMethod;
|
|
31
29
|
}
|
|
32
30
|
return Reflect.get(target, p, receiver);
|
|
33
31
|
},
|
package/lib/proxy.d.ts
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type Language, type VueCompilerOptions } from '@vue/language-core';
|
|
2
|
+
import type * as ts from 'typescript';
|
|
3
|
+
export declare function createVueLanguageServiceProxy(ts: typeof import('typescript'), language: Language<string>, languageService: ts.LanguageService, vueOptions: VueCompilerOptions): ts.LanguageService;
|
package/lib/proxy.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createVueLanguageServiceProxy = createVueLanguageServiceProxy;
|
|
4
|
+
const language_core_1 = require("@vue/language-core");
|
|
5
|
+
const shared_1 = require("@vue/shared");
|
|
6
|
+
const windowsPathReg = /\\/g;
|
|
7
|
+
function createVueLanguageServiceProxy(ts, language, languageService, vueOptions) {
|
|
8
|
+
const proxyCache = new Map();
|
|
9
|
+
const getProxyMethod = (target, p) => {
|
|
10
|
+
switch (p) {
|
|
11
|
+
case 'getCompletionsAtPosition':
|
|
12
|
+
return getCompletionsAtPosition(ts, language, vueOptions, target[p]);
|
|
13
|
+
case 'getCompletionEntryDetails':
|
|
14
|
+
return getCompletionEntryDetails(language, target[p]);
|
|
15
|
+
case 'getCodeFixesAtPosition':
|
|
16
|
+
return getCodeFixesAtPosition(target[p]);
|
|
17
|
+
case 'getDefinitionAndBoundSpan':
|
|
18
|
+
return getDefinitionAndBoundSpan(ts, language, languageService, vueOptions, target[p]);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
return new Proxy(languageService, {
|
|
22
|
+
get(target, p, receiver) {
|
|
23
|
+
if (!proxyCache.has(p)) {
|
|
24
|
+
proxyCache.set(p, getProxyMethod(target, p));
|
|
25
|
+
}
|
|
26
|
+
return proxyCache.get(p) ?? Reflect.get(target, p, receiver);
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function getCompletionsAtPosition(ts, language, vueOptions, getCompletionsAtPosition) {
|
|
31
|
+
return (filePath, position, options, formattingSettings) => {
|
|
32
|
+
const fileName = filePath.replace(windowsPathReg, '/');
|
|
33
|
+
const result = getCompletionsAtPosition(fileName, position, options, formattingSettings);
|
|
34
|
+
if (result) {
|
|
35
|
+
// filter __VLS_
|
|
36
|
+
result.entries = result.entries.filter(entry => !entry.name.includes('__VLS_')
|
|
37
|
+
&& !entry.labelDetails?.description?.includes('__VLS_'));
|
|
38
|
+
// filter global variables in template and styles
|
|
39
|
+
const sourceScript = language.scripts.get(fileName);
|
|
40
|
+
const root = sourceScript?.generated?.root;
|
|
41
|
+
if (root instanceof language_core_1.VueVirtualCode) {
|
|
42
|
+
const blocks = [
|
|
43
|
+
root.sfc.template,
|
|
44
|
+
...root.sfc.styles,
|
|
45
|
+
];
|
|
46
|
+
const ranges = blocks.filter(Boolean).map(block => [
|
|
47
|
+
block.startTagEnd,
|
|
48
|
+
block.endTagStart,
|
|
49
|
+
]);
|
|
50
|
+
if (ranges.some(([start, end]) => position >= start && position <= end)) {
|
|
51
|
+
const globalKinds = new Set(['var', 'function', 'module']);
|
|
52
|
+
const globalsOrKeywords = ts.Completions.SortText.GlobalsOrKeywords;
|
|
53
|
+
const sortTexts = new Set([
|
|
54
|
+
globalsOrKeywords,
|
|
55
|
+
'z' + globalsOrKeywords,
|
|
56
|
+
globalsOrKeywords + '1',
|
|
57
|
+
]);
|
|
58
|
+
result.entries = result.entries.filter(entry => !(entry.kind === 'const' && entry.name in vueOptions.macros) && (!globalKinds.has(entry.kind)
|
|
59
|
+
|| !sortTexts.has(entry.sortText)
|
|
60
|
+
|| (0, shared_1.isGloballyAllowed)(entry.name)));
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// modify label
|
|
64
|
+
for (const item of result.entries) {
|
|
65
|
+
if (item.source) {
|
|
66
|
+
const originalName = item.name;
|
|
67
|
+
for (const vueExt of vueOptions.extensions) {
|
|
68
|
+
const suffix = (0, shared_1.capitalize)(vueExt.slice(1)); // .vue -> Vue
|
|
69
|
+
if (item.source.endsWith(vueExt) && item.name.endsWith(suffix)) {
|
|
70
|
+
item.name = (0, shared_1.capitalize)(item.name.slice(0, -suffix.length));
|
|
71
|
+
if (item.insertText) {
|
|
72
|
+
// #2286
|
|
73
|
+
item.insertText = item.insertText.replace(`${suffix}$1`, '$1');
|
|
74
|
+
}
|
|
75
|
+
if (item.data) {
|
|
76
|
+
// @ts-expect-error
|
|
77
|
+
item.data.__isComponentAutoImport = {
|
|
78
|
+
ext: vueExt,
|
|
79
|
+
suffix,
|
|
80
|
+
originalName,
|
|
81
|
+
newName: item.insertText,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
if (item.data) {
|
|
88
|
+
// @ts-expect-error
|
|
89
|
+
item.data.__isAutoImport = {
|
|
90
|
+
fileName,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
function getCompletionEntryDetails(language, getCompletionEntryDetails) {
|
|
100
|
+
return (...args) => {
|
|
101
|
+
const details = getCompletionEntryDetails(...args);
|
|
102
|
+
// modify import statement
|
|
103
|
+
// @ts-expect-error
|
|
104
|
+
if (args[6]?.__isComponentAutoImport) {
|
|
105
|
+
// @ts-expect-error
|
|
106
|
+
const { originalName, newName } = args[6].__isComponentAutoImport;
|
|
107
|
+
for (const codeAction of details?.codeActions ?? []) {
|
|
108
|
+
for (const change of codeAction.changes) {
|
|
109
|
+
for (const textChange of change.textChanges) {
|
|
110
|
+
textChange.newText = textChange.newText.replace('import ' + originalName + ' from ', 'import ' + newName + ' from ');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// @ts-expect-error
|
|
116
|
+
if (args[6]?.__isAutoImport) {
|
|
117
|
+
// @ts-expect-error
|
|
118
|
+
const { fileName } = args[6].__isAutoImport;
|
|
119
|
+
const sourceScript = language.scripts.get(fileName);
|
|
120
|
+
if (sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode) {
|
|
121
|
+
const { sfc } = sourceScript.generated.root;
|
|
122
|
+
if (!sfc.script && !sfc.scriptSetup) {
|
|
123
|
+
for (const codeAction of details?.codeActions ?? []) {
|
|
124
|
+
for (const change of codeAction.changes) {
|
|
125
|
+
for (const textChange of change.textChanges) {
|
|
126
|
+
textChange.newText = `<script setup lang="ts">${textChange.newText}</script>\n\n`;
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
break;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return details;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function getCodeFixesAtPosition(getCodeFixesAtPosition) {
|
|
140
|
+
return (...args) => {
|
|
141
|
+
let result = getCodeFixesAtPosition(...args);
|
|
142
|
+
// filter __VLS_
|
|
143
|
+
result = result.filter(entry => !entry.description.includes('__VLS_'));
|
|
144
|
+
return result;
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
function getDefinitionAndBoundSpan(ts, language, languageService, vueOptions, getDefinitionAndBoundSpan) {
|
|
148
|
+
return (fileName, position) => {
|
|
149
|
+
const result = getDefinitionAndBoundSpan(fileName, position);
|
|
150
|
+
if (!result?.definitions?.length) {
|
|
151
|
+
return result;
|
|
152
|
+
}
|
|
153
|
+
const program = languageService.getProgram();
|
|
154
|
+
const sourceScript = language.scripts.get(fileName);
|
|
155
|
+
if (!sourceScript?.generated) {
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
const root = sourceScript.generated.root;
|
|
159
|
+
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
160
|
+
return result;
|
|
161
|
+
}
|
|
162
|
+
if (!root.sfc.template
|
|
163
|
+
|| position < root.sfc.template.startTagEnd
|
|
164
|
+
|| position > root.sfc.template.endTagStart) {
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
const definitions = new Set(result.definitions);
|
|
168
|
+
const skippedDefinitions = [];
|
|
169
|
+
// #5275
|
|
170
|
+
if (result.definitions.length >= 2) {
|
|
171
|
+
for (const definition of result.definitions) {
|
|
172
|
+
if (root.sfc.content[definition.textSpan.start - 1] === '@'
|
|
173
|
+
|| root.sfc.content.slice(definition.textSpan.start - 5, definition.textSpan.start) === 'v-on:') {
|
|
174
|
+
skippedDefinitions.push(definition);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const definition of result.definitions) {
|
|
179
|
+
if (vueOptions.extensions.some(ext => definition.fileName.endsWith(ext))) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const sourceFile = program.getSourceFile(definition.fileName);
|
|
183
|
+
if (!sourceFile) {
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
visit(sourceFile, definition, sourceFile);
|
|
187
|
+
}
|
|
188
|
+
for (const definition of skippedDefinitions) {
|
|
189
|
+
definitions.delete(definition);
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
definitions: [...definitions],
|
|
193
|
+
textSpan: result.textSpan,
|
|
194
|
+
};
|
|
195
|
+
function visit(node, definition, sourceFile) {
|
|
196
|
+
if (ts.isPropertySignature(node) && node.type) {
|
|
197
|
+
proxy(node.name, node.type, definition, sourceFile);
|
|
198
|
+
}
|
|
199
|
+
else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.type && !node.initializer) {
|
|
200
|
+
proxy(node.name, node.type, definition, sourceFile);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
ts.forEachChild(node, child => visit(child, definition, sourceFile));
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function proxy(name, type, definition, sourceFile) {
|
|
207
|
+
const { textSpan, fileName } = definition;
|
|
208
|
+
const start = name.getStart(sourceFile);
|
|
209
|
+
const end = name.getEnd();
|
|
210
|
+
if (start !== textSpan.start || end - start !== textSpan.length) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (!ts.isIndexedAccessTypeNode(type)) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const pos = type.indexType.getStart(sourceFile);
|
|
217
|
+
const res = getDefinitionAndBoundSpan(fileName, pos);
|
|
218
|
+
if (res?.definitions?.length) {
|
|
219
|
+
for (const definition of res.definitions) {
|
|
220
|
+
definitions.add(definition);
|
|
221
|
+
}
|
|
222
|
+
skippedDefinitions.push(definition);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=proxy.js.map
|
|
@@ -5,5 +5,5 @@ interface ExtractPropsInfo {
|
|
|
5
5
|
type: string;
|
|
6
6
|
model: boolean;
|
|
7
7
|
}
|
|
8
|
-
export declare function collectExtractProps(ts: typeof import('typescript'), language: Language, program: ts.Program, sourceScript: SourceScript, virtualCode: VueVirtualCode, templateCodeRange: [number, number]): ExtractPropsInfo[];
|
|
8
|
+
export declare function collectExtractProps(ts: typeof import('typescript'), language: Language, program: ts.Program, sourceScript: SourceScript, virtualCode: VueVirtualCode, templateCodeRange: [number, number], leadingOffset?: number): ExtractPropsInfo[];
|
|
9
9
|
export {};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.collectExtractProps = collectExtractProps;
|
|
4
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
function collectExtractProps(ts, language, program, sourceScript, virtualCode, templateCodeRange) {
|
|
5
|
+
function collectExtractProps(ts, language, program, sourceScript, virtualCode, templateCodeRange, leadingOffset = 0) {
|
|
6
6
|
const result = new Map();
|
|
7
7
|
const sourceFile = program.getSourceFile(virtualCode.fileName);
|
|
8
8
|
const checker = program.getTypeChecker();
|
|
@@ -17,7 +17,7 @@ function collectExtractProps(ts, language, program, sourceScript, virtualCode, t
|
|
|
17
17
|
const { name } = node;
|
|
18
18
|
for (const map of maps) {
|
|
19
19
|
let mapped = false;
|
|
20
|
-
for (const source of map.toSourceLocation(name.getEnd() -
|
|
20
|
+
for (const source of map.toSourceLocation(name.getEnd() - leadingOffset)) {
|
|
21
21
|
if (source[0] >= sfc.template.startTagEnd + templateCodeRange[0]
|
|
22
22
|
&& source[0] <= sfc.template.startTagEnd + templateCodeRange[1]
|
|
23
23
|
&& (0, language_core_1.isSemanticTokensEnabled)(source[1].data)) {
|
|
@@ -25,8 +25,8 @@ function getComponentEvents(ts, program, fileName, tag) {
|
|
|
25
25
|
if (emitSymbol) {
|
|
26
26
|
const emitType = checker.getTypeOfSymbolAtLocation(emitSymbol, components.node);
|
|
27
27
|
for (const call of emitType.getCallSignatures()) {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
if (call.parameters.length) {
|
|
29
|
+
const eventNameParamSymbol = call.parameters[0];
|
|
30
30
|
const eventNameParamType = checker.getTypeOfSymbolAtLocation(eventNameParamSymbol, components.node);
|
|
31
31
|
if (eventNameParamType.isStringLiteral()) {
|
|
32
32
|
result.add(eventNameParamType.value);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -5,7 +5,7 @@ const utils_1 = require("./utils");
|
|
|
5
5
|
function getComponentNames(ts, program, fileName) {
|
|
6
6
|
const names = (0, utils_1.getVariableType)(ts, program, fileName, '__VLS_components')
|
|
7
7
|
?.type
|
|
8
|
-
|
|
8
|
+
.getProperties()
|
|
9
9
|
.map(c => c.name)
|
|
10
10
|
.filter(entry => !entry.includes('$') && !entry.startsWith('_'))
|
|
11
11
|
?? [];
|
|
@@ -14,8 +14,8 @@ function getComponentProps(ts, program, fileName, tag) {
|
|
|
14
14
|
const result = new Map();
|
|
15
15
|
const checker = program.getTypeChecker();
|
|
16
16
|
for (const sig of componentType.getCallSignatures()) {
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
if (sig.parameters.length) {
|
|
18
|
+
const propParam = sig.parameters[0];
|
|
19
19
|
const propsType = checker.getTypeOfSymbolAtLocation(propParam, components.node);
|
|
20
20
|
const props = propsType.getProperties();
|
|
21
21
|
for (const prop of props) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getDefineSlots = getDefineSlots;
|
|
4
|
+
const language_core_1 = require("@vue/language-core");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
function getDefineSlots(fileName) {
|
|
7
|
+
const { typescript: ts, language, languageService, getFileId } = this;
|
|
8
|
+
const volarFile = language.scripts.get(getFileId(fileName));
|
|
9
|
+
if (!(volarFile?.generated?.root instanceof language_core_1.VueVirtualCode)) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
const vueCode = volarFile.generated.root;
|
|
13
|
+
const slots = (0, utils_1.getTypeAliasType)(ts, languageService, vueCode, '__VLS_Slots');
|
|
14
|
+
return slots?.type.getProperties().map(prop => prop.getName());
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=getDefineSlots.js.map
|
|
@@ -1,4 +1,2 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
|
-
export declare function getImportPathForFile(ts: typeof import('typescript'), languageServiceHost: ts.LanguageServiceHost, program: ts.Program, fileName: string, incomingFileName: string, preferences: ts.UserPreferences):
|
|
3
|
-
path?: string;
|
|
4
|
-
};
|
|
2
|
+
export declare function getImportPathForFile(ts: typeof import('typescript'), languageServiceHost: ts.LanguageServiceHost, program: ts.Program, fileName: string, incomingFileName: string, preferences: ts.UserPreferences): string | undefined;
|
|
@@ -4,14 +4,12 @@ exports.getImportPathForFile = getImportPathForFile;
|
|
|
4
4
|
function getImportPathForFile(ts, languageServiceHost, program, fileName, incomingFileName, preferences) {
|
|
5
5
|
const incomingFile = program.getSourceFile(incomingFileName);
|
|
6
6
|
const sourceFile = program.getSourceFile(fileName);
|
|
7
|
-
if (!
|
|
8
|
-
return
|
|
7
|
+
if (!sourceFile || !incomingFile) {
|
|
8
|
+
return;
|
|
9
9
|
}
|
|
10
10
|
const getModuleSpecifiersWithCacheInfo = ts.moduleSpecifiers.getModuleSpecifiersWithCacheInfo;
|
|
11
11
|
const resolutionHost = ts.createModuleSpecifierResolutionHost(program, languageServiceHost);
|
|
12
12
|
const { moduleSpecifiers } = getModuleSpecifiersWithCacheInfo(incomingFile.symbol, program.getTypeChecker(), languageServiceHost.getCompilationSettings(), sourceFile, resolutionHost, preferences);
|
|
13
|
-
return
|
|
14
|
-
path: moduleSpecifiers[0],
|
|
15
|
-
};
|
|
13
|
+
return moduleSpecifiers[0];
|
|
16
14
|
}
|
|
17
15
|
//# sourceMappingURL=getImportPathForFile.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { RequestContext } from './types';
|
|
2
|
+
export interface ComponentPropInfo {
|
|
3
|
+
name: string;
|
|
4
|
+
required?: boolean;
|
|
5
|
+
deprecated?: boolean;
|
|
6
|
+
isAttribute?: boolean;
|
|
7
|
+
commentMarkdown?: string;
|
|
8
|
+
values?: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function getMissingPropsDiagnostics(this: RequestContext, fileName: string): undefined;
|