@vue/typescript-plugin 3.0.0-alpha.2 → 3.0.0-alpha.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.
- package/lib/client.d.ts +1 -4
- package/lib/client.js +1 -2
- package/lib/common.d.ts +1 -1
- package/lib/common.js +9 -0
- package/lib/requests/getComponentProps.d.ts +1 -0
- package/lib/requests/getComponentProps.js +44 -23
- package/lib/requests/utils.js +1 -1
- package/lib/server.d.ts +1 -1
- package/lib/server.js +0 -4
- package/lib/utils.js +3 -1
- package/package.json +8 -6
- package/lib/proxy.d.ts +0 -3
- package/lib/proxy.js +0 -356
- package/lib/requests/getSlotNames.d.ts +0 -6
- package/lib/requests/getSlotNames.js +0 -30
package/lib/client.d.ts
CHANGED
|
@@ -10,7 +10,4 @@ export declare function getComponentProps(fileName: string, componentName: strin
|
|
|
10
10
|
export declare const getComponentEvents: (fileName: string, tag: string) => Promise<string[] | null | undefined>;
|
|
11
11
|
export declare const getComponentDirectives: (fileName: string) => Promise<string[] | null | undefined>;
|
|
12
12
|
export declare function getComponentNames(fileName: string): Promise<string[] | undefined>;
|
|
13
|
-
export declare const getElementAttrs: (fileName: string, tagName: string) => Promise<
|
|
14
|
-
name: string;
|
|
15
|
-
}[] | null | undefined>;
|
|
16
|
-
export declare const getSlotNames: (fileName: string) => Promise<string[] | null | undefined>;
|
|
13
|
+
export declare const getElementAttrs: (fileName: string, tagName: string) => Promise<string[] | null | undefined>;
|
package/lib/client.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getElementAttrs = exports.getComponentDirectives = exports.getComponentEvents = exports.getQuickInfoAtPosition = exports.getPropertiesAtLocation = exports.getImportPathForFile = exports.collectExtractProps = void 0;
|
|
4
4
|
exports.getComponentProps = getComponentProps;
|
|
5
5
|
exports.getComponentNames = getComponentNames;
|
|
6
6
|
const utils_1 = require("./utils");
|
|
@@ -30,7 +30,6 @@ async function getComponentNames(fileName) {
|
|
|
30
30
|
return Object.keys(componentAndProps);
|
|
31
31
|
}
|
|
32
32
|
exports.getElementAttrs = createRequest('getElementAttrs');
|
|
33
|
-
exports.getSlotNames = createRequest('getSlotNames');
|
|
34
33
|
function createRequest(requestType) {
|
|
35
34
|
return async function (...[fileName, ...rest]) {
|
|
36
35
|
const server = await (0, utils_1.getBestServer)(fileName);
|
package/lib/common.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { Language, VueCompilerOptions } from '@vue/language-core';
|
|
1
|
+
import { type Language, type VueCompilerOptions } from '@vue/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
3
|
export declare function proxyLanguageServiceForVue<T>(ts: typeof import('typescript'), language: Language<T>, languageService: ts.LanguageService, vueOptions: VueCompilerOptions, asScriptId: (fileName: string) => T): ts.LanguageService;
|
package/lib/common.js
CHANGED
|
@@ -151,6 +151,15 @@ function getDefinitionAndBoundSpan(ts, language, languageService, vueOptions, as
|
|
|
151
151
|
}
|
|
152
152
|
const definitions = new Set(result.definitions);
|
|
153
153
|
const skippedDefinitions = [];
|
|
154
|
+
// #5275
|
|
155
|
+
if (result.definitions.length >= 2) {
|
|
156
|
+
for (const definition of result.definitions) {
|
|
157
|
+
if (root.sfc.content[definition.textSpan.start - 1] === '@'
|
|
158
|
+
|| root.sfc.content.slice(definition.textSpan.start - 5, definition.textSpan.start) === 'v-on:') {
|
|
159
|
+
skippedDefinitions.push(definition);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
154
163
|
for (const definition of result.definitions) {
|
|
155
164
|
if (vueOptions.extensions.some(ext => definition.fileName.endsWith(ext))) {
|
|
156
165
|
continue;
|
|
@@ -10,8 +10,6 @@ function getComponentProps(fileName, tag) {
|
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
12
|
const vueCode = volarFile.generated.root;
|
|
13
|
-
const program = languageService.getProgram();
|
|
14
|
-
const checker = program.getTypeChecker();
|
|
15
13
|
const components = (0, utils_1.getVariableType)(ts, languageService, vueCode, '__VLS_components');
|
|
16
14
|
if (!components) {
|
|
17
15
|
return [];
|
|
@@ -21,21 +19,15 @@ function getComponentProps(fileName, tag) {
|
|
|
21
19
|
return [];
|
|
22
20
|
}
|
|
23
21
|
const result = new Map();
|
|
22
|
+
const program = languageService.getProgram();
|
|
23
|
+
const checker = program.getTypeChecker();
|
|
24
24
|
for (const sig of componentType.getCallSignatures()) {
|
|
25
25
|
const propParam = sig.parameters[0];
|
|
26
26
|
if (propParam) {
|
|
27
27
|
const propsType = checker.getTypeOfSymbolAtLocation(propParam, components.node);
|
|
28
28
|
const props = propsType.getProperties();
|
|
29
29
|
for (const prop of props) {
|
|
30
|
-
|
|
31
|
-
const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
|
|
32
|
-
const { content: commentMarkdown, deprecated } = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags());
|
|
33
|
-
result.set(name, {
|
|
34
|
-
name,
|
|
35
|
-
required,
|
|
36
|
-
deprecated,
|
|
37
|
-
commentMarkdown
|
|
38
|
-
});
|
|
30
|
+
handlePropSymbol(prop);
|
|
39
31
|
}
|
|
40
32
|
}
|
|
41
33
|
}
|
|
@@ -46,22 +38,51 @@ function getComponentProps(fileName, tag) {
|
|
|
46
38
|
const propsType = checker.getTypeOfSymbolAtLocation(propsSymbol, components.node);
|
|
47
39
|
const props = propsType.getProperties();
|
|
48
40
|
for (const prop of props) {
|
|
49
|
-
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
const name = prop.name;
|
|
53
|
-
const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
|
|
54
|
-
const { content: commentMarkdown, deprecated } = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags());
|
|
55
|
-
result.set(name, {
|
|
56
|
-
name,
|
|
57
|
-
required,
|
|
58
|
-
deprecated,
|
|
59
|
-
commentMarkdown
|
|
60
|
-
});
|
|
41
|
+
handlePropSymbol(prop);
|
|
61
42
|
}
|
|
62
43
|
}
|
|
63
44
|
}
|
|
64
45
|
return [...result.values()];
|
|
46
|
+
function handlePropSymbol(prop) {
|
|
47
|
+
if (prop.flags & ts.SymbolFlags.Method) { // #2443
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
const name = prop.name;
|
|
51
|
+
const required = !(prop.flags & ts.SymbolFlags.Optional) || undefined;
|
|
52
|
+
const { content: commentMarkdown, deprecated, } = generateCommentMarkdown(prop.getDocumentationComment(checker), prop.getJsDocTags());
|
|
53
|
+
const values = [];
|
|
54
|
+
const type = checker.getTypeOfSymbol(prop);
|
|
55
|
+
const subTypes = type.types;
|
|
56
|
+
if (subTypes) {
|
|
57
|
+
for (const subType of subTypes) {
|
|
58
|
+
const value = subType.value;
|
|
59
|
+
if (value) {
|
|
60
|
+
values.push(value);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
let isAttribute;
|
|
65
|
+
for (const { parent } of checker.getRootSymbols(prop).flatMap(root => root.declarations ?? [])) {
|
|
66
|
+
if (!ts.isInterfaceDeclaration(parent)) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
const { text } = parent.name;
|
|
70
|
+
if (text.endsWith('HTMLAttributes')
|
|
71
|
+
|| text === 'AriaAttributes'
|
|
72
|
+
|| text === 'SVGAttributes') {
|
|
73
|
+
isAttribute = true;
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
result.set(name, {
|
|
78
|
+
name,
|
|
79
|
+
required,
|
|
80
|
+
deprecated,
|
|
81
|
+
isAttribute,
|
|
82
|
+
commentMarkdown,
|
|
83
|
+
values,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
65
86
|
}
|
|
66
87
|
function generateCommentMarkdown(parts, jsDocTags) {
|
|
67
88
|
const parsedComment = _symbolDisplayPartsToMarkdown(parts);
|
package/lib/requests/utils.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.getComponentType = getComponentType;
|
|
|
4
4
|
exports.getSelfComponentName = getSelfComponentName;
|
|
5
5
|
exports.getVariableType = getVariableType;
|
|
6
6
|
const shared_1 = require("@vue/shared");
|
|
7
|
-
const path = require("
|
|
7
|
+
const path = require("path-browserify");
|
|
8
8
|
function getComponentType(ts, languageService, vueCode, components, fileName, tag) {
|
|
9
9
|
const program = languageService.getProgram();
|
|
10
10
|
const checker = program.getTypeChecker();
|
package/lib/server.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Language } from '@vue/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
export type RequestType = 'containsFile' | 'projectInfo' | 'collectExtractProps' | 'getImportPathForFile' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' | 'subscribeComponentProps' | 'getComponentEvents' | 'getComponentDirectives' | 'getElementAttrs'
|
|
3
|
+
export type RequestType = 'containsFile' | 'projectInfo' | 'collectExtractProps' | 'getImportPathForFile' | 'getPropertiesAtLocation' | 'getQuickInfoAtPosition' | 'subscribeComponentProps' | 'getComponentEvents' | 'getComponentDirectives' | 'getElementAttrs';
|
|
4
4
|
export type NotificationType = 'componentNamesUpdated' | 'componentPropsUpdated';
|
|
5
5
|
export type RequestData = [
|
|
6
6
|
seq: number,
|
package/lib/server.js
CHANGED
|
@@ -13,7 +13,6 @@ const getElementAttrs_1 = require("./requests/getElementAttrs");
|
|
|
13
13
|
const getImportPathForFile_1 = require("./requests/getImportPathForFile");
|
|
14
14
|
const getPropertiesAtLocation_1 = require("./requests/getPropertiesAtLocation");
|
|
15
15
|
const getQuickInfoAtPosition_1 = require("./requests/getQuickInfoAtPosition");
|
|
16
|
-
const getSlotNames_1 = require("./requests/getSlotNames");
|
|
17
16
|
const utils_1 = require("./utils");
|
|
18
17
|
async function startNamedPipeServer(ts, info, language, projectKind) {
|
|
19
18
|
let lastProjectVersion;
|
|
@@ -194,9 +193,6 @@ async function startNamedPipeServer(ts, info, language, projectKind) {
|
|
|
194
193
|
else if (requestType === 'getElementAttrs') {
|
|
195
194
|
return getElementAttrs_1.getElementAttrs.apply(requestContext, args);
|
|
196
195
|
}
|
|
197
|
-
else if (requestType === 'getSlotNames') {
|
|
198
|
-
return getSlotNames_1.getSlotNames.apply(requestContext, args);
|
|
199
|
-
}
|
|
200
196
|
console.warn('[Vue Named Pipe Server] Unknown request:', requestType);
|
|
201
197
|
debugger;
|
|
202
198
|
return undefined;
|
package/lib/utils.js
CHANGED
|
@@ -153,7 +153,9 @@ class NamedPipeServer {
|
|
|
153
153
|
else if (type === 'componentPropsUpdated') {
|
|
154
154
|
const components = this.componentNamesAndProps.get(fileName) ?? {};
|
|
155
155
|
const [name, props] = data;
|
|
156
|
-
|
|
156
|
+
if (name in components) {
|
|
157
|
+
components[name] = props;
|
|
158
|
+
}
|
|
157
159
|
}
|
|
158
160
|
else {
|
|
159
161
|
console.error('Unknown notification type:', type);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/typescript-plugin",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.6",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"files": [
|
|
6
6
|
"**/*.js",
|
|
@@ -13,12 +13,14 @@
|
|
|
13
13
|
"directory": "packages/typescript-plugin"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@volar/typescript": "~2.4.
|
|
17
|
-
"@vue/language-core": "3.0.0-alpha.
|
|
18
|
-
"@vue/shared": "^3.5.0"
|
|
16
|
+
"@volar/typescript": "~2.4.13",
|
|
17
|
+
"@vue/language-core": "3.0.0-alpha.6",
|
|
18
|
+
"@vue/shared": "^3.5.0",
|
|
19
|
+
"path-browserify": "^1.0.1"
|
|
19
20
|
},
|
|
20
21
|
"devDependencies": {
|
|
21
|
-
"@types/node": "^22.10.4"
|
|
22
|
+
"@types/node": "^22.10.4",
|
|
23
|
+
"@types/path-browserify": "^1.0.1"
|
|
22
24
|
},
|
|
23
|
-
"gitHead": "
|
|
25
|
+
"gitHead": "a7b5649ab4957cd2228f4bbc9205b2008bff58a2"
|
|
24
26
|
}
|
package/lib/proxy.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { Language, VueCompilerOptions } from '@vue/language-core';
|
|
2
|
-
import type * as ts from 'typescript';
|
|
3
|
-
export declare function proxyLanguageServiceForVue<T>(ts: typeof import('typescript'), language: Language<T>, languageService: ts.LanguageService, vueOptions: VueCompilerOptions, asScriptId: (fileName: string) => T): ts.LanguageService;
|
package/lib/proxy.js
DELETED
|
@@ -1,356 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.proxyLanguageServiceForVue = proxyLanguageServiceForVue;
|
|
4
|
-
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
const shared_1 = require("@vue/shared");
|
|
6
|
-
const getComponentNames_1 = require("./requests/getComponentNames");
|
|
7
|
-
const windowsPathReg = /\\/g;
|
|
8
|
-
function proxyLanguageServiceForVue(ts, language, languageService, vueOptions, asScriptId) {
|
|
9
|
-
const proxyCache = new Map();
|
|
10
|
-
const getProxyMethod = (target, p) => {
|
|
11
|
-
switch (p) {
|
|
12
|
-
case 'getCompletionsAtPosition': return getCompletionsAtPosition(vueOptions, target[p]);
|
|
13
|
-
case 'getCompletionEntryDetails': return getCompletionEntryDetails(language, asScriptId, target[p]);
|
|
14
|
-
case 'getCodeFixesAtPosition': return getCodeFixesAtPosition(target[p]);
|
|
15
|
-
case 'getDefinitionAndBoundSpan': return getDefinitionAndBoundSpan(ts, language, languageService, vueOptions, asScriptId, target[p]);
|
|
16
|
-
case 'getEncodedSemanticClassifications': return getEncodedSemanticClassifications(ts, language, target, asScriptId, target[p]);
|
|
17
|
-
case 'getQuickInfoAtPosition': return getQuickInfoAtPosition(ts, target, target[p]);
|
|
18
|
-
case 'getSemanticDiagnostics': return getSemanticDiagnostics(ts, language, languageService, asScriptId, target[p]);
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
|
-
return new Proxy(languageService, {
|
|
22
|
-
get(target, p, receiver) {
|
|
23
|
-
if (getProxyMethod) {
|
|
24
|
-
if (!proxyCache.has(p)) {
|
|
25
|
-
proxyCache.set(p, getProxyMethod(target, p));
|
|
26
|
-
}
|
|
27
|
-
const proxyMethod = proxyCache.get(p);
|
|
28
|
-
if (proxyMethod) {
|
|
29
|
-
return proxyMethod;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return Reflect.get(target, p, receiver);
|
|
33
|
-
},
|
|
34
|
-
set(target, p, value, receiver) {
|
|
35
|
-
return Reflect.set(target, p, value, receiver);
|
|
36
|
-
},
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
function getCompletionsAtPosition(vueOptions, getCompletionsAtPosition) {
|
|
40
|
-
return (filePath, position, options, formattingSettings) => {
|
|
41
|
-
const fileName = filePath.replace(windowsPathReg, '/');
|
|
42
|
-
const result = getCompletionsAtPosition(fileName, position, options, formattingSettings);
|
|
43
|
-
if (result) {
|
|
44
|
-
// filter __VLS_
|
|
45
|
-
result.entries = result.entries.filter(entry => !entry.name.includes('__VLS_')
|
|
46
|
-
&& !entry.labelDetails?.description?.includes('__VLS_'));
|
|
47
|
-
// modify label
|
|
48
|
-
for (const item of result.entries) {
|
|
49
|
-
if (item.source) {
|
|
50
|
-
const originalName = item.name;
|
|
51
|
-
for (const vueExt of vueOptions.extensions) {
|
|
52
|
-
const suffix = (0, shared_1.capitalize)(vueExt.slice(1)); // .vue -> Vue
|
|
53
|
-
if (item.source.endsWith(vueExt) && item.name.endsWith(suffix)) {
|
|
54
|
-
item.name = (0, shared_1.capitalize)(item.name.slice(0, -suffix.length));
|
|
55
|
-
if (item.insertText) {
|
|
56
|
-
// #2286
|
|
57
|
-
item.insertText = item.insertText.replace(`${suffix}$1`, '$1');
|
|
58
|
-
}
|
|
59
|
-
if (item.data) {
|
|
60
|
-
// @ts-expect-error
|
|
61
|
-
item.data.__isComponentAutoImport = {
|
|
62
|
-
ext: vueExt,
|
|
63
|
-
suffix,
|
|
64
|
-
originalName,
|
|
65
|
-
newName: item.insertText,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
if (item.data) {
|
|
72
|
-
// @ts-expect-error
|
|
73
|
-
item.data.__isAutoImport = {
|
|
74
|
-
fileName,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
return result;
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
function getCompletionEntryDetails(language, asScriptId, getCompletionEntryDetails) {
|
|
84
|
-
return (...args) => {
|
|
85
|
-
const details = getCompletionEntryDetails(...args);
|
|
86
|
-
// modify import statement
|
|
87
|
-
// @ts-expect-error
|
|
88
|
-
if (args[6]?.__isComponentAutoImport) {
|
|
89
|
-
// @ts-expect-error
|
|
90
|
-
const { ext, suffix, originalName, newName } = args[6]?.__isComponentAutoImport;
|
|
91
|
-
for (const codeAction of details?.codeActions ?? []) {
|
|
92
|
-
for (const change of codeAction.changes) {
|
|
93
|
-
for (const textChange of change.textChanges) {
|
|
94
|
-
textChange.newText = textChange.newText.replace('import ' + originalName + ' from ', 'import ' + newName + ' from ');
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// @ts-expect-error
|
|
100
|
-
if (args[6]?.__isAutoImport) {
|
|
101
|
-
// @ts-expect-error
|
|
102
|
-
const { fileName } = args[6]?.__isAutoImport;
|
|
103
|
-
const sourceScript = language.scripts.get(asScriptId(fileName));
|
|
104
|
-
if (sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode) {
|
|
105
|
-
const sfc = sourceScript.generated.root.vueSfc;
|
|
106
|
-
if (!sfc?.descriptor.script && !sfc?.descriptor.scriptSetup) {
|
|
107
|
-
for (const codeAction of details?.codeActions ?? []) {
|
|
108
|
-
for (const change of codeAction.changes) {
|
|
109
|
-
for (const textChange of change.textChanges) {
|
|
110
|
-
textChange.newText = `<script setup lang="ts">${textChange.newText}</script>\n\n`;
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
break;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return details;
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
function getCodeFixesAtPosition(getCodeFixesAtPosition) {
|
|
124
|
-
return (...args) => {
|
|
125
|
-
let result = getCodeFixesAtPosition(...args);
|
|
126
|
-
// filter __VLS_
|
|
127
|
-
result = result.filter(entry => !entry.description.includes('__VLS_'));
|
|
128
|
-
return result;
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
function getDefinitionAndBoundSpan(ts, language, languageService, vueOptions, asScriptId, getDefinitionAndBoundSpan) {
|
|
132
|
-
return (fileName, position) => {
|
|
133
|
-
const result = getDefinitionAndBoundSpan(fileName, position);
|
|
134
|
-
if (!result?.definitions?.length) {
|
|
135
|
-
return result;
|
|
136
|
-
}
|
|
137
|
-
const program = languageService.getProgram();
|
|
138
|
-
const sourceScript = language.scripts.get(asScriptId(fileName));
|
|
139
|
-
if (!sourceScript?.generated) {
|
|
140
|
-
return result;
|
|
141
|
-
}
|
|
142
|
-
const root = sourceScript.generated.root;
|
|
143
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
144
|
-
return result;
|
|
145
|
-
}
|
|
146
|
-
if (!root.sfc.template
|
|
147
|
-
|| position < root.sfc.template.startTagEnd
|
|
148
|
-
|| position > root.sfc.template.endTagStart) {
|
|
149
|
-
return result;
|
|
150
|
-
}
|
|
151
|
-
const definitions = new Set(result.definitions);
|
|
152
|
-
const skippedDefinitions = [];
|
|
153
|
-
for (const definition of result.definitions) {
|
|
154
|
-
if (vueOptions.extensions.some(ext => definition.fileName.endsWith(ext))) {
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
const sourceFile = program.getSourceFile(definition.fileName);
|
|
158
|
-
if (!sourceFile) {
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
visit(sourceFile, definition, sourceFile);
|
|
162
|
-
}
|
|
163
|
-
for (const definition of skippedDefinitions) {
|
|
164
|
-
definitions.delete(definition);
|
|
165
|
-
}
|
|
166
|
-
return {
|
|
167
|
-
definitions: [...definitions],
|
|
168
|
-
textSpan: result.textSpan,
|
|
169
|
-
};
|
|
170
|
-
function visit(node, definition, sourceFile) {
|
|
171
|
-
if (ts.isPropertySignature(node) && node.type) {
|
|
172
|
-
proxy(node.name, node.type, definition, sourceFile);
|
|
173
|
-
}
|
|
174
|
-
else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.type && !node.initializer) {
|
|
175
|
-
proxy(node.name, node.type, definition, sourceFile);
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
ts.forEachChild(node, child => visit(child, definition, sourceFile));
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
function proxy(name, type, definition, sourceFile) {
|
|
182
|
-
const { textSpan, fileName } = definition;
|
|
183
|
-
const start = name.getStart(sourceFile);
|
|
184
|
-
const end = name.getEnd();
|
|
185
|
-
if (start !== textSpan.start || end - start !== textSpan.length) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
if (!ts.isIndexedAccessTypeNode(type)) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
const pos = type.indexType.getStart(sourceFile);
|
|
192
|
-
const res = getDefinitionAndBoundSpan(fileName, pos);
|
|
193
|
-
if (res?.definitions?.length) {
|
|
194
|
-
for (const definition of res.definitions) {
|
|
195
|
-
definitions.add(definition);
|
|
196
|
-
}
|
|
197
|
-
skippedDefinitions.push(definition);
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
};
|
|
201
|
-
}
|
|
202
|
-
function getQuickInfoAtPosition(ts, languageService, getQuickInfoAtPosition) {
|
|
203
|
-
return (...args) => {
|
|
204
|
-
const result = getQuickInfoAtPosition(...args);
|
|
205
|
-
if (result && result.documentation?.length === 1 && result.documentation[0].text.startsWith('__VLS_emit,')) {
|
|
206
|
-
const [_, emitVarName, eventName] = result.documentation[0].text.split(',');
|
|
207
|
-
const program = languageService.getProgram();
|
|
208
|
-
const typeChecker = program.getTypeChecker();
|
|
209
|
-
const sourceFile = program.getSourceFile(args[0]);
|
|
210
|
-
result.documentation = undefined;
|
|
211
|
-
let symbolNode;
|
|
212
|
-
sourceFile?.forEachChild(function visit(node) {
|
|
213
|
-
if (ts.isIdentifier(node) && node.text === emitVarName) {
|
|
214
|
-
symbolNode = node;
|
|
215
|
-
}
|
|
216
|
-
if (symbolNode) {
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
ts.forEachChild(node, visit);
|
|
220
|
-
});
|
|
221
|
-
if (symbolNode) {
|
|
222
|
-
const emitSymbol = typeChecker.getSymbolAtLocation(symbolNode);
|
|
223
|
-
if (emitSymbol) {
|
|
224
|
-
const type = typeChecker.getTypeOfSymbolAtLocation(emitSymbol, symbolNode);
|
|
225
|
-
const calls = type.getCallSignatures();
|
|
226
|
-
for (const call of calls) {
|
|
227
|
-
const callEventName = typeChecker.getTypeOfSymbolAtLocation(call.parameters[0], symbolNode).value;
|
|
228
|
-
call.getJsDocTags();
|
|
229
|
-
if (callEventName === eventName) {
|
|
230
|
-
result.documentation = call.getDocumentationComment(typeChecker);
|
|
231
|
-
result.tags = call.getJsDocTags();
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
return result;
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
function getSemanticDiagnostics(ts, language, languageService, asScriptId, getSemanticDiagnostics) {
|
|
241
|
-
return (fileName) => {
|
|
242
|
-
const result = getSemanticDiagnostics(fileName);
|
|
243
|
-
const program = languageService.getProgram();
|
|
244
|
-
const sourceScript = language.scripts.get(asScriptId(fileName));
|
|
245
|
-
if (!sourceScript?.generated) {
|
|
246
|
-
return result;
|
|
247
|
-
}
|
|
248
|
-
const root = sourceScript.generated.root;
|
|
249
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
250
|
-
return result;
|
|
251
|
-
}
|
|
252
|
-
const { template } = root.sfc;
|
|
253
|
-
if (!template) {
|
|
254
|
-
return result;
|
|
255
|
-
}
|
|
256
|
-
const sourceFile = program.getSourceFile(fileName);
|
|
257
|
-
if (!sourceFile) {
|
|
258
|
-
return result;
|
|
259
|
-
}
|
|
260
|
-
const additionalResult = [];
|
|
261
|
-
const { commentDirectives } = template;
|
|
262
|
-
for (const dir of commentDirectives) {
|
|
263
|
-
const start = template.startTagEnd + dir.start;
|
|
264
|
-
const end = template.startTagEnd + dir.end;
|
|
265
|
-
const rangeStart = template.startTagEnd + dir.rangeStart;
|
|
266
|
-
const rangeEnd = template.startTagEnd + dir.rangeEnd;
|
|
267
|
-
if (dir.name === 'expect-error') {
|
|
268
|
-
let containError = false;
|
|
269
|
-
for (let i = 0; i < result.length; i++) {
|
|
270
|
-
const diag = result[i];
|
|
271
|
-
if (diag.start >= rangeStart && diag.start + diag.length <= rangeEnd) {
|
|
272
|
-
containError = true;
|
|
273
|
-
result.splice(i, 1);
|
|
274
|
-
i--;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
if (!containError) {
|
|
278
|
-
additionalResult.push({
|
|
279
|
-
category: ts.DiagnosticCategory.Error,
|
|
280
|
-
code: 2578,
|
|
281
|
-
file: sourceFile,
|
|
282
|
-
start,
|
|
283
|
-
length: end - start,
|
|
284
|
-
messageText: `Unused '@vue-expect-error' directive.`,
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
else if (dir.name === 'ignore') {
|
|
289
|
-
for (let i = 0; i < result.length; i++) {
|
|
290
|
-
const diag = result[i];
|
|
291
|
-
if (diag.start >= rangeStart && diag.start + diag.length <= rangeEnd) {
|
|
292
|
-
result.splice(i, 1);
|
|
293
|
-
i--;
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
return [...result, ...additionalResult];
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
function getEncodedSemanticClassifications(ts, language, languageService, asScriptId, getEncodedSemanticClassifications) {
|
|
302
|
-
return (filePath, span, format) => {
|
|
303
|
-
const fileName = filePath.replace(windowsPathReg, '/');
|
|
304
|
-
const result = getEncodedSemanticClassifications(fileName, span, format);
|
|
305
|
-
const sourceScript = language.scripts.get(asScriptId(fileName));
|
|
306
|
-
const root = sourceScript?.generated?.root;
|
|
307
|
-
if (root instanceof language_core_1.VueVirtualCode) {
|
|
308
|
-
const { template } = root.sfc;
|
|
309
|
-
if (template) {
|
|
310
|
-
for (const componentSpan of getComponentSpans.call({ typescript: ts, languageService }, root, template, {
|
|
311
|
-
start: span.start - template.startTagEnd,
|
|
312
|
-
length: span.length,
|
|
313
|
-
})) {
|
|
314
|
-
result.spans.push(componentSpan.start + template.startTagEnd, componentSpan.length, 256 // class
|
|
315
|
-
);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
return result;
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
function getComponentSpans(vueCode, template, spanTemplateRange) {
|
|
323
|
-
const { typescript: ts, languageService } = this;
|
|
324
|
-
const result = [];
|
|
325
|
-
const validComponentNames = (0, getComponentNames_1._getComponentNames)(ts, languageService, vueCode);
|
|
326
|
-
const elements = new Set((0, getComponentNames_1._getElementNames)(ts, languageService, vueCode));
|
|
327
|
-
const components = new Set([
|
|
328
|
-
...validComponentNames,
|
|
329
|
-
...validComponentNames.map(language_core_1.hyphenateTag),
|
|
330
|
-
]);
|
|
331
|
-
if (template.ast) {
|
|
332
|
-
for (const node of (0, language_core_1.forEachTemplateChild)(template.ast)) {
|
|
333
|
-
if (node.loc.end.offset <= spanTemplateRange.start || node.loc.start.offset >= (spanTemplateRange.start + spanTemplateRange.length)) {
|
|
334
|
-
continue;
|
|
335
|
-
}
|
|
336
|
-
if (components.has(node.tag) && !elements.has(node.tag)) {
|
|
337
|
-
let start = node.loc.start.offset;
|
|
338
|
-
if (template.lang === 'html') {
|
|
339
|
-
start += '<'.length;
|
|
340
|
-
}
|
|
341
|
-
result.push({
|
|
342
|
-
start,
|
|
343
|
-
length: node.tag.length,
|
|
344
|
-
});
|
|
345
|
-
if (template.lang === 'html' && !node.isSelfClosing) {
|
|
346
|
-
result.push({
|
|
347
|
-
start: node.loc.start.offset + node.loc.source.lastIndexOf(node.tag),
|
|
348
|
-
length: node.tag.length,
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
}
|
|
353
|
-
}
|
|
354
|
-
return result;
|
|
355
|
-
}
|
|
356
|
-
//# sourceMappingURL=proxy.js.map
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSlotNames = getSlotNames;
|
|
4
|
-
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
function getSlotNames(fileName) {
|
|
6
|
-
const { typescript: ts, language, languageService, getFileId } = this;
|
|
7
|
-
const sourceScript = language.scripts.get(getFileId(fileName));
|
|
8
|
-
if (!sourceScript?.generated) {
|
|
9
|
-
return;
|
|
10
|
-
}
|
|
11
|
-
const root = sourceScript.generated.root;
|
|
12
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
13
|
-
return;
|
|
14
|
-
}
|
|
15
|
-
const program = languageService.getProgram();
|
|
16
|
-
const tsSourceFile = program.getSourceFile(fileName);
|
|
17
|
-
if (!tsSourceFile) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
const checker = program.getTypeChecker();
|
|
21
|
-
const typeNode = tsSourceFile.statements
|
|
22
|
-
.filter(ts.isTypeAliasDeclaration)
|
|
23
|
-
.find(node => node.name.getText() === '__VLS_Slots');
|
|
24
|
-
if (typeNode) {
|
|
25
|
-
const attrs = checker.getTypeFromTypeNode(typeNode.type).getProperties();
|
|
26
|
-
return attrs.map(attr => attr.name);
|
|
27
|
-
}
|
|
28
|
-
return [];
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=getSlotNames.js.map
|