@vue/typescript-plugin 2.2.10 → 3.0.0-alpha.10
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.d.ts +2 -2
- package/index.js +96 -9
- package/lib/common.d.ts +1 -3
- package/lib/common.js +11 -3
- package/lib/requests/getComponentProps.d.ts +1 -0
- package/lib/requests/getComponentProps.js +44 -23
- package/lib/requests/getElementAttrs.d.ts +0 -3
- package/lib/requests/getElementAttrs.js +11 -30
- package/lib/requests/getFileReferences.d.ts +9 -0
- package/lib/requests/getFileReferences.js +71 -0
- package/lib/requests/getPropertiesAtLocation.js +1 -0
- package/lib/requests/utils.js +1 -1
- package/package.json +8 -6
- package/lib/commands.d.ts +0 -3
- package/lib/commands.js +0 -136
- package/lib/proxy.d.ts +0 -3
- package/lib/proxy.js +0 -305
- package/lib/requests/getDefineSlots.d.ts +0 -2
- package/lib/requests/getDefineSlots.js +0 -16
package/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type * as ts from 'typescript';
|
|
2
|
-
declare const
|
|
3
|
-
export =
|
|
2
|
+
declare const _default: ts.server.PluginModuleFactory;
|
|
3
|
+
export = _default;
|
package/index.js
CHANGED
|
@@ -2,21 +2,26 @@
|
|
|
2
2
|
const createLanguageServicePlugin_1 = require("@volar/typescript/lib/quickstart/createLanguageServicePlugin");
|
|
3
3
|
const vue = require("@vue/language-core");
|
|
4
4
|
const common_1 = require("./lib/common");
|
|
5
|
-
const
|
|
5
|
+
const collectExtractProps_1 = require("./lib/requests/collectExtractProps");
|
|
6
|
+
const getComponentDirectives_1 = require("./lib/requests/getComponentDirectives");
|
|
7
|
+
const getComponentEvents_1 = require("./lib/requests/getComponentEvents");
|
|
8
|
+
const getComponentNames_1 = require("./lib/requests/getComponentNames");
|
|
9
|
+
const getComponentProps_1 = require("./lib/requests/getComponentProps");
|
|
10
|
+
const getElementAttrs_1 = require("./lib/requests/getElementAttrs");
|
|
11
|
+
const getElementNames_1 = require("./lib/requests/getElementNames");
|
|
12
|
+
const getImportPathForFile_1 = require("./lib/requests/getImportPathForFile");
|
|
13
|
+
const getPropertiesAtLocation_1 = require("./lib/requests/getPropertiesAtLocation");
|
|
6
14
|
const windowsPathReg = /\\/g;
|
|
7
|
-
const
|
|
8
|
-
|
|
15
|
+
const project2Service = new WeakMap();
|
|
16
|
+
module.exports = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)((ts, info) => {
|
|
9
17
|
const vueOptions = getVueCompilerOptions();
|
|
10
18
|
const languagePlugin = vue.createVueLanguagePlugin(ts, info.languageServiceHost.getCompilationSettings(), vueOptions, id => id);
|
|
11
|
-
|
|
19
|
+
addVueCommands();
|
|
12
20
|
return {
|
|
13
21
|
languagePlugins: [languagePlugin],
|
|
14
22
|
setup: language => {
|
|
23
|
+
project2Service.set(info.project, [language, info.languageServiceHost, info.languageService]);
|
|
15
24
|
info.languageService = (0, common_1.proxyLanguageServiceForVue)(ts, language, info.languageService, vueOptions, fileName => fileName);
|
|
16
|
-
if (info.project.projectKind === ts.server.ProjectKind.Configured
|
|
17
|
-
|| info.project.projectKind === ts.server.ProjectKind.Inferred) {
|
|
18
|
-
(0, server_1.startNamedPipeServer)(ts, info, language, info.project.projectKind);
|
|
19
|
-
}
|
|
20
25
|
// #3963
|
|
21
26
|
const timer = setInterval(() => {
|
|
22
27
|
if (info.project['program']) {
|
|
@@ -35,6 +40,88 @@ const plugin = (0, createLanguageServicePlugin_1.createLanguageServicePlugin)((t
|
|
|
35
40
|
return vue.createParsedCommandLineByJson(ts, ts.sys, info.languageServiceHost.getCurrentDirectory(), {}).vueOptions;
|
|
36
41
|
}
|
|
37
42
|
}
|
|
43
|
+
// https://github.com/JetBrains/intellij-plugins/blob/6435723ad88fa296b41144162ebe3b8513f4949b/Angular/src-js/angular-service/src/index.ts#L69
|
|
44
|
+
function addVueCommands() {
|
|
45
|
+
const projectService = info.project.projectService;
|
|
46
|
+
projectService.logger.info("Vue: called handler processing " + info.project.projectKind);
|
|
47
|
+
const session = info.session;
|
|
48
|
+
if (session == undefined) {
|
|
49
|
+
projectService.logger.info("Vue: there is no session in info.");
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (session.addProtocolHandler == undefined) {
|
|
53
|
+
// addProtocolHandler was introduced in TS 4.4 or 4.5 in 2021, see https://github.com/microsoft/TypeScript/issues/43893
|
|
54
|
+
projectService.logger.info("Vue: there is no addProtocolHandler method.");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
if (session.vueCommandsAdded) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
session.vueCommandsAdded = true;
|
|
61
|
+
session.addProtocolHandler('vue:collectExtractProps', ({ arguments: args }) => {
|
|
62
|
+
return {
|
|
63
|
+
response: collectExtractProps_1.collectExtractProps.apply(getRequestContext(args[0]), args),
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
session.addProtocolHandler('vue:getImportPathForFile', ({ arguments: args }) => {
|
|
67
|
+
return {
|
|
68
|
+
response: getImportPathForFile_1.getImportPathForFile.apply(getRequestContext(args[0]), args),
|
|
69
|
+
};
|
|
70
|
+
});
|
|
71
|
+
session.addProtocolHandler('vue:getPropertiesAtLocation', ({ arguments: args }) => {
|
|
72
|
+
return {
|
|
73
|
+
response: getPropertiesAtLocation_1.getPropertiesAtLocation.apply(getRequestContext(args[0]), args),
|
|
74
|
+
};
|
|
75
|
+
});
|
|
76
|
+
session.addProtocolHandler('vue:getComponentNames', ({ arguments: args }) => {
|
|
77
|
+
return {
|
|
78
|
+
response: getComponentNames_1.getComponentNames.apply(getRequestContext(args[0]), args) ?? [],
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
session.addProtocolHandler('vue:getComponentProps', ({ arguments: args }) => {
|
|
82
|
+
return {
|
|
83
|
+
response: getComponentProps_1.getComponentProps.apply(getRequestContext(args[0]), args),
|
|
84
|
+
};
|
|
85
|
+
});
|
|
86
|
+
session.addProtocolHandler('vue:getComponentEvents', ({ arguments: args }) => {
|
|
87
|
+
return {
|
|
88
|
+
response: getComponentEvents_1.getComponentEvents.apply(getRequestContext(args[0]), args),
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
session.addProtocolHandler('vue:getComponentDirectives', ({ arguments: args }) => {
|
|
92
|
+
return {
|
|
93
|
+
response: getComponentDirectives_1.getComponentDirectives.apply(getRequestContext(args[0]), args),
|
|
94
|
+
};
|
|
95
|
+
});
|
|
96
|
+
session.addProtocolHandler('vue:getElementAttrs', ({ arguments: args }) => {
|
|
97
|
+
return {
|
|
98
|
+
response: getElementAttrs_1.getElementAttrs.apply(getRequestContext(args[0]), args),
|
|
99
|
+
};
|
|
100
|
+
});
|
|
101
|
+
session.addProtocolHandler('vue:getElementNames', ({ arguments: args }) => {
|
|
102
|
+
return {
|
|
103
|
+
response: getElementNames_1.getElementNames.apply(getRequestContext(args[0]), args),
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
projectService.logger.info('Vue specific commands are successfully added.');
|
|
107
|
+
}
|
|
108
|
+
function getRequestContext(fileName) {
|
|
109
|
+
const fileAndProject = info.session.getFileAndProject({
|
|
110
|
+
file: fileName,
|
|
111
|
+
projectFileName: undefined,
|
|
112
|
+
});
|
|
113
|
+
const service = project2Service.get(fileAndProject.project);
|
|
114
|
+
if (!service) {
|
|
115
|
+
throw 'No RequestContext';
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
typescript: ts,
|
|
119
|
+
languageService: service[2],
|
|
120
|
+
languageServiceHost: service[1],
|
|
121
|
+
language: service[0],
|
|
122
|
+
isTsPlugin: true,
|
|
123
|
+
getFileId: (fileName) => fileName,
|
|
124
|
+
};
|
|
125
|
+
}
|
|
38
126
|
});
|
|
39
|
-
module.exports = plugin;
|
|
40
127
|
//# sourceMappingURL=index.js.map
|
package/lib/common.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Language, VueCompilerOptions
|
|
1
|
+
import { type Language, type VueCompilerOptions } from '@vue/language-core';
|
|
2
2
|
import type * as ts from 'typescript';
|
|
3
|
-
import type { RequestContext } from './requests/types';
|
|
4
3
|
export declare function proxyLanguageServiceForVue<T>(ts: typeof import('typescript'), language: Language<T>, languageService: ts.LanguageService, vueOptions: VueCompilerOptions, asScriptId: (fileName: string) => T): ts.LanguageService;
|
|
5
|
-
export declare function getComponentSpans(this: Pick<RequestContext, 'typescript' | 'languageService'>, vueCode: VueVirtualCode, template: NonNullable<VueVirtualCode['_sfc']['template']>, spanTemplateRange: ts.TextSpan): ts.TextSpan[];
|
package/lib/common.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.proxyLanguageServiceForVue = proxyLanguageServiceForVue;
|
|
4
|
-
exports.getComponentSpans = getComponentSpans;
|
|
5
4
|
const language_core_1 = require("@vue/language-core");
|
|
6
5
|
const shared_1 = require("@vue/shared");
|
|
7
6
|
const getComponentNames_1 = require("./requests/getComponentNames");
|
|
8
|
-
const
|
|
7
|
+
const getElementNames_1 = require("./requests/getElementNames");
|
|
9
8
|
const windowsPathReg = /\\/g;
|
|
10
9
|
function proxyLanguageServiceForVue(ts, language, languageService, vueOptions, asScriptId) {
|
|
11
10
|
const proxyCache = new Map();
|
|
@@ -152,6 +151,15 @@ function getDefinitionAndBoundSpan(ts, language, languageService, vueOptions, as
|
|
|
152
151
|
}
|
|
153
152
|
const definitions = new Set(result.definitions);
|
|
154
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
|
+
}
|
|
155
163
|
for (const definition of result.definitions) {
|
|
156
164
|
if (vueOptions.extensions.some(ext => definition.fileName.endsWith(ext))) {
|
|
157
165
|
continue;
|
|
@@ -264,7 +272,7 @@ function getComponentSpans(vueCode, template, spanTemplateRange) {
|
|
|
264
272
|
const { typescript: ts, languageService } = this;
|
|
265
273
|
const result = [];
|
|
266
274
|
const validComponentNames = (0, getComponentNames_1._getComponentNames)(ts, languageService, vueCode);
|
|
267
|
-
const elements = new Set((0,
|
|
275
|
+
const elements = new Set((0, getElementNames_1._getElementNames)(ts, languageService, vueCode));
|
|
268
276
|
const components = new Set([
|
|
269
277
|
...validComponentNames,
|
|
270
278
|
...validComponentNames.map(language_core_1.hyphenateTag),
|
|
@@ -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);
|
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
import { VueVirtualCode } from '@vue/language-core';
|
|
2
|
-
import type * as ts from 'typescript';
|
|
3
1
|
import type { RequestContext } from './types';
|
|
4
2
|
export declare function getElementAttrs(this: RequestContext, fileName: string, tagName: string): string[] | undefined;
|
|
5
|
-
export declare function _getElementNames(ts: typeof import('typescript'), tsLs: ts.LanguageService, vueCode: VueVirtualCode): string[];
|
|
@@ -1,45 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.getElementAttrs = getElementAttrs;
|
|
4
|
-
exports._getElementNames = _getElementNames;
|
|
5
4
|
const language_core_1 = require("@vue/language-core");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
6
|
function getElementAttrs(fileName, tagName) {
|
|
7
7
|
const { typescript: ts, language, languageService, getFileId } = this;
|
|
8
8
|
const volarFile = language.scripts.get(getFileId(fileName));
|
|
9
9
|
if (!(volarFile?.generated?.root instanceof language_core_1.VueVirtualCode)) {
|
|
10
10
|
return;
|
|
11
11
|
}
|
|
12
|
+
const vueCode = volarFile.generated.root;
|
|
12
13
|
const program = languageService.getProgram();
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
.filter(ts.isTypeAliasDeclaration)
|
|
18
|
-
.find(node => node.name.getText() === '__VLS_IntrinsicElementsCompletion');
|
|
19
|
-
if (typeNode) {
|
|
20
|
-
const type = checker.getTypeFromTypeNode(typeNode.type);
|
|
21
|
-
const el = type.getProperty(tagName);
|
|
22
|
-
if (el) {
|
|
23
|
-
const attrs = checker.getTypeOfSymbolAtLocation(el, typeNode).getProperties();
|
|
24
|
-
return attrs.map(c => c.name);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
14
|
+
const checker = program.getTypeChecker();
|
|
15
|
+
const elements = (0, utils_1.getVariableType)(ts, languageService, vueCode, '__VLS_elements');
|
|
16
|
+
if (!elements) {
|
|
17
|
+
return [];
|
|
27
18
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const program = tsLs.getProgram();
|
|
32
|
-
const tsSourceFile = program.getSourceFile(vueCode.fileName);
|
|
33
|
-
if (tsSourceFile) {
|
|
34
|
-
const checker = program.getTypeChecker();
|
|
35
|
-
const typeNode = tsSourceFile.statements
|
|
36
|
-
.filter(ts.isTypeAliasDeclaration)
|
|
37
|
-
.find(node => node.name.getText() === '__VLS_IntrinsicElementsCompletion');
|
|
38
|
-
if (typeNode) {
|
|
39
|
-
const type = checker.getTypeFromTypeNode(typeNode.type);
|
|
40
|
-
return type.getProperties().map(c => c.name);
|
|
41
|
-
}
|
|
19
|
+
const elementType = elements.type.getProperty(tagName);
|
|
20
|
+
if (!elementType) {
|
|
21
|
+
return [];
|
|
42
22
|
}
|
|
43
|
-
|
|
23
|
+
const attrs = checker.getTypeOfSymbol(elementType).getProperties();
|
|
24
|
+
return attrs.map(c => c.name);
|
|
44
25
|
}
|
|
45
26
|
//# sourceMappingURL=getElementAttrs.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type * as ts from "typescript";
|
|
2
|
+
import type { RequestContext } from "./types";
|
|
3
|
+
export declare function getFileReferences(this: RequestContext, fileName: string): {
|
|
4
|
+
fileName: string;
|
|
5
|
+
range: {
|
|
6
|
+
start: ts.LineAndCharacter;
|
|
7
|
+
end: ts.LineAndCharacter;
|
|
8
|
+
};
|
|
9
|
+
}[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFileReferences = getFileReferences;
|
|
4
|
+
function getFileReferences(fileName) {
|
|
5
|
+
const { typescript: ts, languageService } = this;
|
|
6
|
+
const program = languageService.getProgram();
|
|
7
|
+
const result = languageService.getFileReferences(fileName);
|
|
8
|
+
const references = new Set(result);
|
|
9
|
+
const skippedReferences = [];
|
|
10
|
+
for (const reference of result) {
|
|
11
|
+
if (reference.fileName.endsWith('.vue')) {
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const sourceFile = program.getSourceFile(reference.fileName);
|
|
15
|
+
if (!sourceFile) {
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
visit(sourceFile, reference, sourceFile);
|
|
19
|
+
}
|
|
20
|
+
for (const reference of skippedReferences) {
|
|
21
|
+
references.delete(reference);
|
|
22
|
+
}
|
|
23
|
+
return [...references].map(({ fileName, textSpan }) => {
|
|
24
|
+
const sourceFile = program.getSourceFile(fileName);
|
|
25
|
+
const start = sourceFile.getLineAndCharacterOfPosition(textSpan.start);
|
|
26
|
+
const end = sourceFile.getLineAndCharacterOfPosition(textSpan.start + textSpan.length);
|
|
27
|
+
return {
|
|
28
|
+
fileName,
|
|
29
|
+
range: {
|
|
30
|
+
start,
|
|
31
|
+
end,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
function visit(node, reference, sourceFile) {
|
|
36
|
+
if (ts.isPropertySignature(node) && node.type) {
|
|
37
|
+
proxy(node.name, node.type, reference, sourceFile);
|
|
38
|
+
}
|
|
39
|
+
else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.type && !node.initializer) {
|
|
40
|
+
proxy(node.name, node.type, reference, sourceFile, true);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
ts.forEachChild(node, child => visit(child, reference, sourceFile));
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function proxy(name, type, reference, sourceFile, skip = false) {
|
|
47
|
+
const { textSpan, fileName } = reference;
|
|
48
|
+
const start = type.getStart(sourceFile);
|
|
49
|
+
const end = type.getEnd();
|
|
50
|
+
if (start > textSpan.start || end < textSpan.start + textSpan.length) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (skip) {
|
|
54
|
+
skippedReferences.push(reference);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const pos = name.getStart(sourceFile);
|
|
58
|
+
const res = languageService.findReferences(fileName, pos) ?? [];
|
|
59
|
+
const items = res.flatMap(({ references }) => references);
|
|
60
|
+
if (items.length) {
|
|
61
|
+
for (const reference of items) {
|
|
62
|
+
if (reference.isDefinition) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
references.add(reference);
|
|
66
|
+
}
|
|
67
|
+
skippedReferences.push(reference);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=getFileReferences.js.map
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/typescript-plugin",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-alpha.10",
|
|
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": "
|
|
18
|
-
"@vue/shared": "^3.5.0"
|
|
16
|
+
"@volar/typescript": "~2.4.13",
|
|
17
|
+
"@vue/language-core": "3.0.0-alpha.10",
|
|
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": "28308b4f76cc80c7632f39ae7e0944f1889661a2"
|
|
24
26
|
}
|
package/lib/commands.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import { type Language } from '@vue/language-core';
|
|
2
|
-
import type * as ts from 'typescript';
|
|
3
|
-
export declare function addVueCommands(ts: typeof import('typescript'), info: ts.server.PluginCreateInfo, project2Service: Map<ts.server.Project, [Language, ts.LanguageServiceHost, ts.LanguageService]>): void;
|
package/lib/commands.js
DELETED
|
@@ -1,136 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.addVueCommands = addVueCommands;
|
|
4
|
-
const language_core_1 = require("@vue/language-core");
|
|
5
|
-
const collectExtractProps_1 = require("./requests/collectExtractProps");
|
|
6
|
-
const getComponentDirectives_1 = require("./requests/getComponentDirectives");
|
|
7
|
-
const getComponentEvents_1 = require("./requests/getComponentEvents");
|
|
8
|
-
const getComponentNames_1 = require("./requests/getComponentNames");
|
|
9
|
-
const getComponentProps_1 = require("./requests/getComponentProps");
|
|
10
|
-
const getElementAttrs_1 = require("./requests/getElementAttrs");
|
|
11
|
-
const getElementNames_1 = require("./requests/getElementNames");
|
|
12
|
-
const getImportPathForFile_1 = require("./requests/getImportPathForFile");
|
|
13
|
-
const getPropertiesAtLocation_1 = require("./requests/getPropertiesAtLocation");
|
|
14
|
-
// https://github.com/JetBrains/intellij-plugins/blob/6435723ad88fa296b41144162ebe3b8513f4949b/Angular/src-js/angular-service/src/index.ts#L69
|
|
15
|
-
function addVueCommands(ts, info, project2Service) {
|
|
16
|
-
const projectService = info.project.projectService;
|
|
17
|
-
projectService.logger.info("Vue: called handler processing " + info.project.projectKind);
|
|
18
|
-
const session = info.session;
|
|
19
|
-
if (session == undefined) {
|
|
20
|
-
projectService.logger.info("Vue: there is no session in info.");
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
if (session.addProtocolHandler == undefined) {
|
|
24
|
-
// addProtocolHandler was introduced in TS 4.4 or 4.5 in 2021, see https://github.com/microsoft/TypeScript/issues/43893
|
|
25
|
-
projectService.logger.info("Vue: there is no addProtocolHandler method.");
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if (session.vueCommandsAdded) {
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
session.vueCommandsAdded = true;
|
|
32
|
-
const isCaseSensitive = info.languageServiceHost.useCaseSensitiveFileNames?.() ?? false;
|
|
33
|
-
let lastProjectVersion;
|
|
34
|
-
let scriptInfos = new language_core_1.FileMap(isCaseSensitive);
|
|
35
|
-
session.addProtocolHandler('vue:isProjectUpdated', () => {
|
|
36
|
-
const projectVersion = info.project.getProjectVersion();
|
|
37
|
-
if (projectVersion === lastProjectVersion) {
|
|
38
|
-
return { response: 'no' };
|
|
39
|
-
}
|
|
40
|
-
lastProjectVersion = projectVersion;
|
|
41
|
-
const [, [language, languageServiceHost]] = [...project2Service].find(([project]) => project.projectKind === ts.server.ProjectKind.Configured);
|
|
42
|
-
const fileNames = languageServiceHost.getScriptFileNames();
|
|
43
|
-
const infos = new language_core_1.FileMap(isCaseSensitive);
|
|
44
|
-
let isAnyScriptVersionChanged = false;
|
|
45
|
-
let isAnyScriptSnapshotChanged = false;
|
|
46
|
-
for (const file of fileNames) {
|
|
47
|
-
const scriptVersion = languageServiceHost.getScriptVersion(file);
|
|
48
|
-
const scriptInfo = scriptInfos.get(file) ?? { version: "" };
|
|
49
|
-
infos.set(file, scriptInfo);
|
|
50
|
-
if (scriptInfo.version === scriptVersion) {
|
|
51
|
-
continue;
|
|
52
|
-
}
|
|
53
|
-
scriptInfo.version = scriptVersion;
|
|
54
|
-
isAnyScriptVersionChanged = true;
|
|
55
|
-
const volarFile = language.scripts.get(file);
|
|
56
|
-
const root = volarFile?.generated?.root;
|
|
57
|
-
const serviceScript = volarFile?.generated?.languagePlugin.typescript?.getServiceScript(root);
|
|
58
|
-
if (!serviceScript) {
|
|
59
|
-
isAnyScriptSnapshotChanged = true;
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
const { snapshot } = serviceScript.code;
|
|
63
|
-
if (scriptInfo.snapshot !== snapshot) {
|
|
64
|
-
scriptInfo.snapshot = snapshot;
|
|
65
|
-
isAnyScriptSnapshotChanged = true;
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
scriptInfos = infos;
|
|
69
|
-
return { response: isAnyScriptSnapshotChanged || !isAnyScriptVersionChanged ? 'yes' : 'no' };
|
|
70
|
-
});
|
|
71
|
-
session.addProtocolHandler('vue:collectExtractProps', ({ arguments: args }) => {
|
|
72
|
-
return {
|
|
73
|
-
response: collectExtractProps_1.collectExtractProps.apply(getRequestContext(args[0]), args),
|
|
74
|
-
};
|
|
75
|
-
});
|
|
76
|
-
session.addProtocolHandler('vue:getImportPathForFile', ({ arguments: args }) => {
|
|
77
|
-
return {
|
|
78
|
-
response: getImportPathForFile_1.getImportPathForFile.apply(getRequestContext(args[0]), args),
|
|
79
|
-
};
|
|
80
|
-
});
|
|
81
|
-
session.addProtocolHandler('vue:getPropertiesAtLocation', ({ arguments: args }) => {
|
|
82
|
-
return {
|
|
83
|
-
response: getPropertiesAtLocation_1.getPropertiesAtLocation.apply(getRequestContext(args[0]), args),
|
|
84
|
-
};
|
|
85
|
-
});
|
|
86
|
-
session.addProtocolHandler('vue:getComponentNames', ({ arguments: args }) => {
|
|
87
|
-
return {
|
|
88
|
-
response: getComponentNames_1.getComponentNames.apply(getRequestContext(args[0]), args),
|
|
89
|
-
};
|
|
90
|
-
});
|
|
91
|
-
session.addProtocolHandler('vue:getComponentProps', ({ arguments: args }) => {
|
|
92
|
-
return {
|
|
93
|
-
response: getComponentProps_1.getComponentProps.apply(getRequestContext(args[0]), args),
|
|
94
|
-
};
|
|
95
|
-
});
|
|
96
|
-
session.addProtocolHandler('vue:getComponentEvents', ({ arguments: args }) => {
|
|
97
|
-
return {
|
|
98
|
-
response: getComponentEvents_1.getComponentEvents.apply(getRequestContext(args[0]), args),
|
|
99
|
-
};
|
|
100
|
-
});
|
|
101
|
-
session.addProtocolHandler('vue:getComponentDirectives', ({ arguments: args }) => {
|
|
102
|
-
return {
|
|
103
|
-
response: getComponentDirectives_1.getComponentDirectives.apply(getRequestContext(args[0]), args),
|
|
104
|
-
};
|
|
105
|
-
});
|
|
106
|
-
session.addProtocolHandler('vue:getElementAttrs', ({ arguments: args }) => {
|
|
107
|
-
return {
|
|
108
|
-
response: getElementAttrs_1.getElementAttrs.apply(getRequestContext(args[0]), args),
|
|
109
|
-
};
|
|
110
|
-
});
|
|
111
|
-
session.addProtocolHandler('vue:getElementNames', ({ arguments: args }) => {
|
|
112
|
-
return {
|
|
113
|
-
response: getElementNames_1.getElementNames.apply(getRequestContext(args[0]), args),
|
|
114
|
-
};
|
|
115
|
-
});
|
|
116
|
-
projectService.logger.info('Vue specific commands are successfully added.');
|
|
117
|
-
function getRequestContext(fileName) {
|
|
118
|
-
const fileAndProject = info.session.getFileAndProject({
|
|
119
|
-
file: fileName,
|
|
120
|
-
projectFileName: undefined,
|
|
121
|
-
});
|
|
122
|
-
const service = project2Service.get(fileAndProject.project);
|
|
123
|
-
if (!service) {
|
|
124
|
-
throw 'No RequestContext';
|
|
125
|
-
}
|
|
126
|
-
return {
|
|
127
|
-
typescript: ts,
|
|
128
|
-
languageService: service[2],
|
|
129
|
-
languageServiceHost: service[1],
|
|
130
|
-
language: service[0],
|
|
131
|
-
isTsPlugin: true,
|
|
132
|
-
getFileId: (fileName) => fileName,
|
|
133
|
-
};
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
//# sourceMappingURL=commands.js.map
|
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,305 +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 getElementNames_1 = require("./requests/getElementNames");
|
|
8
|
-
const windowsPathReg = /\\/g;
|
|
9
|
-
function proxyLanguageServiceForVue(ts, language, languageService, vueOptions, asScriptId) {
|
|
10
|
-
const proxyCache = new Map();
|
|
11
|
-
const getProxyMethod = (target, p) => {
|
|
12
|
-
switch (p) {
|
|
13
|
-
case 'getCompletionsAtPosition': return getCompletionsAtPosition(vueOptions, target[p]);
|
|
14
|
-
case 'getCompletionEntryDetails': return getCompletionEntryDetails(language, asScriptId, target[p]);
|
|
15
|
-
case 'getCodeFixesAtPosition': return getCodeFixesAtPosition(target[p]);
|
|
16
|
-
case 'getDefinitionAndBoundSpan': return getDefinitionAndBoundSpan(ts, language, languageService, vueOptions, asScriptId, target[p]);
|
|
17
|
-
case 'getQuickInfoAtPosition': return getQuickInfoAtPosition(ts, target, target[p]);
|
|
18
|
-
// TS plugin only
|
|
19
|
-
case 'getEncodedSemanticClassifications': return getEncodedSemanticClassifications(ts, language, target, asScriptId, target[p]);
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
return new Proxy(languageService, {
|
|
23
|
-
get(target, p, receiver) {
|
|
24
|
-
if (getProxyMethod) {
|
|
25
|
-
if (!proxyCache.has(p)) {
|
|
26
|
-
proxyCache.set(p, getProxyMethod(target, p));
|
|
27
|
-
}
|
|
28
|
-
const proxyMethod = proxyCache.get(p);
|
|
29
|
-
if (proxyMethod) {
|
|
30
|
-
return proxyMethod;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return Reflect.get(target, p, receiver);
|
|
34
|
-
},
|
|
35
|
-
set(target, p, value, receiver) {
|
|
36
|
-
return Reflect.set(target, p, value, receiver);
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
function getCompletionsAtPosition(vueOptions, getCompletionsAtPosition) {
|
|
41
|
-
return (filePath, position, options, formattingSettings) => {
|
|
42
|
-
const fileName = filePath.replace(windowsPathReg, '/');
|
|
43
|
-
const result = getCompletionsAtPosition(fileName, position, options, formattingSettings);
|
|
44
|
-
if (result) {
|
|
45
|
-
// filter __VLS_
|
|
46
|
-
result.entries = result.entries.filter(entry => !entry.name.includes('__VLS_')
|
|
47
|
-
&& !entry.labelDetails?.description?.includes('__VLS_'));
|
|
48
|
-
// modify label
|
|
49
|
-
for (const item of result.entries) {
|
|
50
|
-
if (item.source) {
|
|
51
|
-
const originalName = item.name;
|
|
52
|
-
for (const vueExt of vueOptions.extensions) {
|
|
53
|
-
const suffix = (0, shared_1.capitalize)(vueExt.slice(1)); // .vue -> Vue
|
|
54
|
-
if (item.source.endsWith(vueExt) && item.name.endsWith(suffix)) {
|
|
55
|
-
item.name = (0, shared_1.capitalize)(item.name.slice(0, -suffix.length));
|
|
56
|
-
if (item.insertText) {
|
|
57
|
-
// #2286
|
|
58
|
-
item.insertText = item.insertText.replace(`${suffix}$1`, '$1');
|
|
59
|
-
}
|
|
60
|
-
if (item.data) {
|
|
61
|
-
// @ts-expect-error
|
|
62
|
-
item.data.__isComponentAutoImport = {
|
|
63
|
-
ext: vueExt,
|
|
64
|
-
suffix,
|
|
65
|
-
originalName,
|
|
66
|
-
newName: item.insertText,
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
break;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (item.data) {
|
|
73
|
-
// @ts-expect-error
|
|
74
|
-
item.data.__isAutoImport = {
|
|
75
|
-
fileName,
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
return result;
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
function getCompletionEntryDetails(language, asScriptId, getCompletionEntryDetails) {
|
|
85
|
-
return (...args) => {
|
|
86
|
-
const details = getCompletionEntryDetails(...args);
|
|
87
|
-
// modify import statement
|
|
88
|
-
// @ts-expect-error
|
|
89
|
-
if (args[6]?.__isComponentAutoImport) {
|
|
90
|
-
// @ts-expect-error
|
|
91
|
-
const { ext, suffix, originalName, newName } = args[6]?.__isComponentAutoImport;
|
|
92
|
-
for (const codeAction of details?.codeActions ?? []) {
|
|
93
|
-
for (const change of codeAction.changes) {
|
|
94
|
-
for (const textChange of change.textChanges) {
|
|
95
|
-
textChange.newText = textChange.newText.replace('import ' + originalName + ' from ', 'import ' + newName + ' from ');
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
// @ts-expect-error
|
|
101
|
-
if (args[6]?.__isAutoImport) {
|
|
102
|
-
// @ts-expect-error
|
|
103
|
-
const { fileName } = args[6]?.__isAutoImport;
|
|
104
|
-
const sourceScript = language.scripts.get(asScriptId(fileName));
|
|
105
|
-
if (sourceScript?.generated?.root instanceof language_core_1.VueVirtualCode) {
|
|
106
|
-
const sfc = sourceScript.generated.root.vueSfc;
|
|
107
|
-
if (!sfc?.descriptor.script && !sfc?.descriptor.scriptSetup) {
|
|
108
|
-
for (const codeAction of details?.codeActions ?? []) {
|
|
109
|
-
for (const change of codeAction.changes) {
|
|
110
|
-
for (const textChange of change.textChanges) {
|
|
111
|
-
textChange.newText = `<script setup lang="ts">${textChange.newText}</script>\n\n`;
|
|
112
|
-
break;
|
|
113
|
-
}
|
|
114
|
-
break;
|
|
115
|
-
}
|
|
116
|
-
break;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
return details;
|
|
122
|
-
};
|
|
123
|
-
}
|
|
124
|
-
function getCodeFixesAtPosition(getCodeFixesAtPosition) {
|
|
125
|
-
return (...args) => {
|
|
126
|
-
let result = getCodeFixesAtPosition(...args);
|
|
127
|
-
// filter __VLS_
|
|
128
|
-
result = result.filter(entry => !entry.description.includes('__VLS_'));
|
|
129
|
-
return result;
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
function getDefinitionAndBoundSpan(ts, language, languageService, vueOptions, asScriptId, getDefinitionAndBoundSpan) {
|
|
133
|
-
return (fileName, position) => {
|
|
134
|
-
const result = getDefinitionAndBoundSpan(fileName, position);
|
|
135
|
-
if (!result?.definitions?.length) {
|
|
136
|
-
return result;
|
|
137
|
-
}
|
|
138
|
-
const program = languageService.getProgram();
|
|
139
|
-
const sourceScript = language.scripts.get(asScriptId(fileName));
|
|
140
|
-
if (!sourceScript?.generated) {
|
|
141
|
-
return result;
|
|
142
|
-
}
|
|
143
|
-
const root = sourceScript.generated.root;
|
|
144
|
-
if (!(root instanceof language_core_1.VueVirtualCode)) {
|
|
145
|
-
return result;
|
|
146
|
-
}
|
|
147
|
-
if (!root.sfc.template
|
|
148
|
-
|| position < root.sfc.template.startTagEnd
|
|
149
|
-
|| position > root.sfc.template.endTagStart) {
|
|
150
|
-
return result;
|
|
151
|
-
}
|
|
152
|
-
const definitions = new Set(result.definitions);
|
|
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
|
-
}
|
|
163
|
-
for (const definition of result.definitions) {
|
|
164
|
-
if (vueOptions.extensions.some(ext => definition.fileName.endsWith(ext))) {
|
|
165
|
-
continue;
|
|
166
|
-
}
|
|
167
|
-
const sourceFile = program.getSourceFile(definition.fileName);
|
|
168
|
-
if (!sourceFile) {
|
|
169
|
-
continue;
|
|
170
|
-
}
|
|
171
|
-
visit(sourceFile, definition, sourceFile);
|
|
172
|
-
}
|
|
173
|
-
for (const definition of skippedDefinitions) {
|
|
174
|
-
definitions.delete(definition);
|
|
175
|
-
}
|
|
176
|
-
return {
|
|
177
|
-
definitions: [...definitions],
|
|
178
|
-
textSpan: result.textSpan,
|
|
179
|
-
};
|
|
180
|
-
function visit(node, definition, sourceFile) {
|
|
181
|
-
if (ts.isPropertySignature(node) && node.type) {
|
|
182
|
-
proxy(node.name, node.type, definition, sourceFile);
|
|
183
|
-
}
|
|
184
|
-
else if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.type && !node.initializer) {
|
|
185
|
-
proxy(node.name, node.type, definition, sourceFile);
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
ts.forEachChild(node, child => visit(child, definition, sourceFile));
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
function proxy(name, type, definition, sourceFile) {
|
|
192
|
-
const { textSpan, fileName } = definition;
|
|
193
|
-
const start = name.getStart(sourceFile);
|
|
194
|
-
const end = name.getEnd();
|
|
195
|
-
if (start !== textSpan.start || end - start !== textSpan.length) {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
if (!ts.isIndexedAccessTypeNode(type)) {
|
|
199
|
-
return;
|
|
200
|
-
}
|
|
201
|
-
const pos = type.indexType.getStart(sourceFile);
|
|
202
|
-
const res = getDefinitionAndBoundSpan(fileName, pos);
|
|
203
|
-
if (res?.definitions?.length) {
|
|
204
|
-
for (const definition of res.definitions) {
|
|
205
|
-
definitions.add(definition);
|
|
206
|
-
}
|
|
207
|
-
skippedDefinitions.push(definition);
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
function getQuickInfoAtPosition(ts, languageService, getQuickInfoAtPosition) {
|
|
213
|
-
return (...args) => {
|
|
214
|
-
const result = getQuickInfoAtPosition(...args);
|
|
215
|
-
if (result && result.documentation?.length === 1 && result.documentation[0].text.startsWith('__VLS_emit,')) {
|
|
216
|
-
const [_, emitVarName, eventName] = result.documentation[0].text.split(',');
|
|
217
|
-
const program = languageService.getProgram();
|
|
218
|
-
const typeChecker = program.getTypeChecker();
|
|
219
|
-
const sourceFile = program.getSourceFile(args[0]);
|
|
220
|
-
result.documentation = undefined;
|
|
221
|
-
let symbolNode;
|
|
222
|
-
sourceFile?.forEachChild(function visit(node) {
|
|
223
|
-
if (ts.isIdentifier(node) && node.text === emitVarName) {
|
|
224
|
-
symbolNode = node;
|
|
225
|
-
}
|
|
226
|
-
if (symbolNode) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
ts.forEachChild(node, visit);
|
|
230
|
-
});
|
|
231
|
-
if (symbolNode) {
|
|
232
|
-
const emitSymbol = typeChecker.getSymbolAtLocation(symbolNode);
|
|
233
|
-
if (emitSymbol) {
|
|
234
|
-
const type = typeChecker.getTypeOfSymbolAtLocation(emitSymbol, symbolNode);
|
|
235
|
-
const calls = type.getCallSignatures();
|
|
236
|
-
for (const call of calls) {
|
|
237
|
-
const callEventName = typeChecker.getTypeOfSymbolAtLocation(call.parameters[0], symbolNode).value;
|
|
238
|
-
call.getJsDocTags();
|
|
239
|
-
if (callEventName === eventName) {
|
|
240
|
-
result.documentation = call.getDocumentationComment(typeChecker);
|
|
241
|
-
result.tags = call.getJsDocTags();
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
return result;
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
function getEncodedSemanticClassifications(ts, language, languageService, asScriptId, getEncodedSemanticClassifications) {
|
|
251
|
-
return (filePath, span, format) => {
|
|
252
|
-
const fileName = filePath.replace(windowsPathReg, '/');
|
|
253
|
-
const result = getEncodedSemanticClassifications(fileName, span, format);
|
|
254
|
-
const sourceScript = language.scripts.get(asScriptId(fileName));
|
|
255
|
-
const root = sourceScript?.generated?.root;
|
|
256
|
-
if (root instanceof language_core_1.VueVirtualCode) {
|
|
257
|
-
const { template } = root.sfc;
|
|
258
|
-
if (template) {
|
|
259
|
-
for (const componentSpan of getComponentSpans.call({ typescript: ts, languageService }, root, template, {
|
|
260
|
-
start: span.start - template.startTagEnd,
|
|
261
|
-
length: span.length,
|
|
262
|
-
})) {
|
|
263
|
-
result.spans.push(componentSpan.start + template.startTagEnd, componentSpan.length, 256 // class
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
}
|
|
268
|
-
return result;
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
function getComponentSpans(vueCode, template, spanTemplateRange) {
|
|
272
|
-
const { typescript: ts, languageService } = this;
|
|
273
|
-
const result = [];
|
|
274
|
-
const validComponentNames = (0, getComponentNames_1._getComponentNames)(ts, languageService, vueCode);
|
|
275
|
-
const elements = new Set((0, getElementNames_1._getElementNames)(ts, languageService, vueCode));
|
|
276
|
-
const components = new Set([
|
|
277
|
-
...validComponentNames,
|
|
278
|
-
...validComponentNames.map(language_core_1.hyphenateTag),
|
|
279
|
-
]);
|
|
280
|
-
if (template.ast) {
|
|
281
|
-
for (const node of (0, language_core_1.forEachElementNode)(template.ast)) {
|
|
282
|
-
if (node.loc.end.offset <= spanTemplateRange.start || node.loc.start.offset >= (spanTemplateRange.start + spanTemplateRange.length)) {
|
|
283
|
-
continue;
|
|
284
|
-
}
|
|
285
|
-
if (components.has(node.tag) && !elements.has(node.tag)) {
|
|
286
|
-
let start = node.loc.start.offset;
|
|
287
|
-
if (template.lang === 'html') {
|
|
288
|
-
start += '<'.length;
|
|
289
|
-
}
|
|
290
|
-
result.push({
|
|
291
|
-
start,
|
|
292
|
-
length: node.tag.length,
|
|
293
|
-
});
|
|
294
|
-
if (template.lang === 'html' && !node.isSelfClosing) {
|
|
295
|
-
result.push({
|
|
296
|
-
start: node.loc.start.offset + node.loc.source.lastIndexOf(node.tag),
|
|
297
|
-
length: node.tag.length,
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
return result;
|
|
304
|
-
}
|
|
305
|
-
//# sourceMappingURL=proxy.js.map
|
|
@@ -1,16 +0,0 @@
|
|
|
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
|