@vue/language-service 3.0.3 → 3.0.5

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.
Files changed (40) hide show
  1. package/index.d.ts +1 -12
  2. package/index.js +25 -20
  3. package/lib/data.d.ts +4 -0
  4. package/lib/data.js +148 -0
  5. package/lib/plugins/css.js +9 -17
  6. package/lib/plugins/typescript-semantic-tokens.d.ts +2 -2
  7. package/lib/plugins/typescript-semantic-tokens.js +7 -15
  8. package/lib/plugins/vue-autoinsert-dotvalue.d copy.d.ts +2 -0
  9. package/lib/plugins/vue-autoinsert-dotvalue.d copy.js +3 -0
  10. package/lib/plugins/vue-autoinsert-dotvalue.d.ts +2 -2
  11. package/lib/plugins/vue-autoinsert-dotvalue.js +19 -47
  12. package/lib/plugins/vue-autoinsert-space.js +2 -6
  13. package/lib/plugins/vue-compiler-dom-errors.js +17 -35
  14. package/lib/plugins/vue-component-semantic-tokens.d.ts +2 -2
  15. package/lib/plugins/vue-component-semantic-tokens.js +35 -49
  16. package/lib/plugins/vue-destructured-props-hints.d.ts +7 -0
  17. package/lib/plugins/vue-destructured-props-hints.js +220 -0
  18. package/lib/plugins/vue-document-drop.d.ts +2 -2
  19. package/lib/plugins/vue-document-drop.js +14 -31
  20. package/lib/plugins/vue-document-highlights.d.ts +1 -2
  21. package/lib/plugins/vue-document-highlights.js +5 -12
  22. package/lib/plugins/vue-extract-file.d.ts +2 -2
  23. package/lib/plugins/vue-extract-file.js +11 -26
  24. package/lib/plugins/vue-global-types-error.js +17 -14
  25. package/lib/plugins/vue-inlayhints.js +14 -15
  26. package/lib/plugins/vue-missing-props-hints.d.ts +2 -2
  27. package/lib/plugins/vue-missing-props-hints.js +10 -26
  28. package/lib/plugins/vue-scoped-class-links.d.ts +2 -0
  29. package/lib/plugins/vue-scoped-class-links.js +62 -0
  30. package/lib/plugins/vue-sfc.js +141 -144
  31. package/lib/plugins/vue-suggest-define-assignment.js +4 -14
  32. package/lib/plugins/vue-template-ref-links.d.ts +2 -0
  33. package/lib/plugins/vue-template-ref-links.js +57 -0
  34. package/lib/plugins/vue-template.d.ts +2 -2
  35. package/lib/plugins/vue-template.js +322 -356
  36. package/lib/plugins/vue-twoslash-queries.d.ts +2 -2
  37. package/lib/plugins/vue-twoslash-queries.js +7 -16
  38. package/lib/utils.d.ts +8 -0
  39. package/lib/utils.js +43 -0
  40. package/package.json +7 -7
@@ -2,10 +2,10 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = create;
4
4
  const language_core_1 = require("@vue/language-core");
5
- const vscode_uri_1 = require("vscode-uri");
6
- function create(getTsPluginClient) {
5
+ const utils_1 = require("../utils");
6
+ function create({ getComponentNames, getElementNames }) {
7
7
  return {
8
- name: 'vue-component-highlights',
8
+ name: 'vue-component-semantic-tokens',
9
9
  capabilities: {
10
10
  semanticTokensProvider: {
11
11
  legend: {
@@ -15,55 +15,29 @@ function create(getTsPluginClient) {
15
15
  },
16
16
  },
17
17
  create(context) {
18
- const tsPluginClient = getTsPluginClient?.(context);
19
18
  return {
20
19
  async provideDocumentSemanticTokens(document, range, legend) {
21
- const uri = vscode_uri_1.URI.parse(document.uri);
22
- const decoded = context.decodeEmbeddedDocumentUri(uri);
23
- const sourceScript = decoded && context.language.scripts.get(decoded[0]);
24
- const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
25
- if (!sourceScript?.generated || virtualCode?.id !== 'template') {
26
- return;
27
- }
28
- const root = sourceScript.generated.root;
29
- if (!(root instanceof language_core_1.VueVirtualCode)) {
20
+ const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template');
21
+ if (!info) {
30
22
  return;
31
23
  }
24
+ const { root } = info;
32
25
  const { template } = root.sfc;
33
- if (!template) {
26
+ if (!template?.ast) {
34
27
  return;
35
28
  }
36
- const result = [];
37
- const tokenTypes = legend.tokenTypes.indexOf('component');
38
- const componentSpans = await getComponentSpans(root.fileName, template, {
39
- start: document.offsetAt(range.start),
40
- length: document.offsetAt(range.end) - document.offsetAt(range.start),
41
- });
42
- for (const span of componentSpans) {
43
- const position = document.positionAt(span.start);
44
- result.push([
45
- position.line,
46
- position.character,
47
- span.length,
48
- tokenTypes,
49
- 0,
50
- ]);
51
- }
52
- return result;
53
- },
54
- };
55
- async function getComponentSpans(fileName, template, spanTemplateRange) {
56
- const result = [];
57
- const validComponentNames = await tsPluginClient?.getComponentNames(fileName) ?? [];
58
- const elements = new Set(await tsPluginClient?.getElementNames(fileName) ?? []);
59
- const components = new Set([
60
- ...validComponentNames,
61
- ...validComponentNames.map(language_core_1.hyphenateTag),
62
- ]);
63
- if (template.ast) {
29
+ const componentSpans = [];
30
+ const start = document.offsetAt(range.start);
31
+ const end = document.offsetAt(range.end);
32
+ const validComponentNames = await getComponentNames(root.fileName) ?? [];
33
+ const elements = new Set(await getElementNames(root.fileName) ?? []);
34
+ const components = new Set([
35
+ ...validComponentNames,
36
+ ...validComponentNames.map(language_core_1.hyphenateTag),
37
+ ]);
64
38
  for (const node of (0, language_core_1.forEachElementNode)(template.ast)) {
65
- if (node.loc.end.offset <= spanTemplateRange.start
66
- || node.loc.start.offset >= (spanTemplateRange.start + spanTemplateRange.length)) {
39
+ if (node.loc.end.offset <= start
40
+ || node.loc.start.offset >= end) {
67
41
  continue;
68
42
  }
69
43
  if (components.has(node.tag) && !elements.has(node.tag)) {
@@ -71,21 +45,33 @@ function create(getTsPluginClient) {
71
45
  if (template.lang === 'html') {
72
46
  start += '<'.length;
73
47
  }
74
- result.push({
48
+ componentSpans.push({
75
49
  start,
76
50
  length: node.tag.length,
77
51
  });
78
52
  if (template.lang === 'html' && !node.isSelfClosing) {
79
- result.push({
53
+ componentSpans.push({
80
54
  start: node.loc.start.offset + node.loc.source.lastIndexOf(node.tag),
81
55
  length: node.tag.length,
82
56
  });
83
57
  }
84
58
  }
85
59
  }
86
- }
87
- return result;
88
- }
60
+ const result = [];
61
+ const tokenType = legend.tokenTypes.indexOf('component');
62
+ for (const span of componentSpans) {
63
+ const position = document.positionAt(span.start);
64
+ result.push([
65
+ position.line,
66
+ position.character,
67
+ span.length,
68
+ tokenType,
69
+ 0,
70
+ ]);
71
+ }
72
+ return result;
73
+ },
74
+ };
89
75
  },
90
76
  };
91
77
  }
@@ -0,0 +1,7 @@
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ import type * as ts from 'typescript';
3
+ export declare function create(ts: typeof import('typescript')): LanguageServicePlugin;
4
+ /**
5
+ * Refactored from https://github.com/vuejs/core/blob/main/packages/compiler-sfc/src/script/definePropsDestructure.ts
6
+ */
7
+ export declare function findDestructuredProps(ts: typeof import('typescript'), ast: ts.SourceFile, props: MapIterator<string>): [ts.Identifier, boolean][];
@@ -0,0 +1,220 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = create;
4
+ exports.findDestructuredProps = findDestructuredProps;
5
+ const language_core_1 = require("@vue/language-core");
6
+ const vscode_uri_1 = require("vscode-uri");
7
+ function create(ts) {
8
+ return {
9
+ name: 'vue-destructured-props-hints',
10
+ capabilities: {
11
+ inlayHintProvider: {},
12
+ },
13
+ create(context) {
14
+ return {
15
+ async provideInlayHints(document) {
16
+ const enabled = await context.env.getConfiguration?.('vue.inlayHints.destructuredProps') ?? false;
17
+ if (!enabled) {
18
+ return;
19
+ }
20
+ const uri = vscode_uri_1.URI.parse(document.uri);
21
+ const decoded = context.decodeEmbeddedDocumentUri(uri);
22
+ const sourceScript = decoded && context.language.scripts.get(decoded[0]);
23
+ const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
24
+ if (!sourceScript?.generated || virtualCode?.id !== 'main') {
25
+ return;
26
+ }
27
+ const root = sourceScript.generated.root;
28
+ if (!(root instanceof language_core_1.VueVirtualCode)) {
29
+ return;
30
+ }
31
+ const result = [];
32
+ const codegen = language_core_1.tsCodegen.get(root.sfc);
33
+ const scriptSetupRanges = codegen?.getScriptSetupRanges();
34
+ if (!scriptSetupRanges?.defineProps?.destructured || !root.sfc.scriptSetup?.ast) {
35
+ return;
36
+ }
37
+ for (const [prop, isShorthand] of findDestructuredProps(ts, root.sfc.scriptSetup.ast, scriptSetupRanges.defineProps.destructured.keys())) {
38
+ const name = prop.text;
39
+ const end = prop.getEnd();
40
+ const pos = isShorthand ? end : end - name.length;
41
+ const label = isShorthand ? `: props.${name}` : 'props.';
42
+ result.push({
43
+ label,
44
+ position: document.positionAt(root.sfc.scriptSetup.startTagEnd + pos),
45
+ kind: 2,
46
+ });
47
+ }
48
+ return result;
49
+ },
50
+ };
51
+ },
52
+ };
53
+ }
54
+ /**
55
+ * Refactored from https://github.com/vuejs/core/blob/main/packages/compiler-sfc/src/script/definePropsDestructure.ts
56
+ */
57
+ function findDestructuredProps(ts, ast, props) {
58
+ const rootScope = Object.create(null);
59
+ const scopeStack = [rootScope];
60
+ let currentScope = rootScope;
61
+ const excludedIds = new WeakSet();
62
+ const parentStack = [];
63
+ for (const prop of props) {
64
+ rootScope[prop] = true;
65
+ }
66
+ function pushScope() {
67
+ scopeStack.push(currentScope = Object.create(currentScope));
68
+ }
69
+ function popScope() {
70
+ scopeStack.pop();
71
+ currentScope = scopeStack[scopeStack.length - 1] || null;
72
+ }
73
+ function registerLocalBinding(id) {
74
+ excludedIds.add(id);
75
+ if (currentScope) {
76
+ currentScope[id.text] = false;
77
+ }
78
+ }
79
+ const references = [];
80
+ walkScope(ast, true);
81
+ walk(ast);
82
+ return references;
83
+ function walkScope(node, isRoot = false) {
84
+ ts.forEachChild(node, stmt => {
85
+ if (ts.isVariableStatement(stmt)) {
86
+ for (const decl of stmt.declarationList.declarations) {
87
+ walkVariableDeclaration(decl, isRoot);
88
+ }
89
+ }
90
+ else if (ts.isFunctionDeclaration(stmt)
91
+ || ts.isClassDeclaration(stmt)) {
92
+ const declare = ts.getModifiers(stmt)?.find(modifier => modifier.kind === ts.SyntaxKind.DeclareKeyword);
93
+ if (!stmt.name || declare) {
94
+ return;
95
+ }
96
+ registerLocalBinding(stmt.name);
97
+ }
98
+ else if ((ts.isForOfStatement(stmt) || ts.isForInStatement(stmt))
99
+ && ts.isVariableDeclarationList(stmt.initializer)) {
100
+ walkVariableDeclaration(stmt.initializer.declarations[0], isRoot);
101
+ }
102
+ else if (ts.isLabeledStatement(stmt)
103
+ && ts.isVariableDeclaration(stmt.statement)) {
104
+ walkVariableDeclaration(stmt.statement, isRoot);
105
+ }
106
+ });
107
+ }
108
+ function walkVariableDeclaration(decl, isRoot = false) {
109
+ const { initializer, name } = decl;
110
+ const isDefineProps = isRoot
111
+ && initializer
112
+ && ts.isCallExpression(initializer)
113
+ && initializer.expression.getText(ast) === 'defineProps';
114
+ for (const { id } of (0, language_core_1.collectIdentifiers)(ts, name)) {
115
+ if (isDefineProps) {
116
+ excludedIds.add(id);
117
+ }
118
+ else {
119
+ registerLocalBinding(id);
120
+ }
121
+ }
122
+ }
123
+ function walkFunctionDeclaration(node) {
124
+ const { name, parameters } = node;
125
+ if (name && ts.isIdentifier(name)) {
126
+ registerLocalBinding(name);
127
+ }
128
+ for (const p of parameters) {
129
+ for (const { id } of (0, language_core_1.collectIdentifiers)(ts, p)) {
130
+ registerLocalBinding(id);
131
+ }
132
+ }
133
+ }
134
+ function walk(parent) {
135
+ ts.forEachChild(parent, node => {
136
+ if (enter(node) ?? true) {
137
+ walk(node);
138
+ leave(node);
139
+ }
140
+ });
141
+ function enter(node) {
142
+ if (parent) {
143
+ parentStack.push(parent);
144
+ }
145
+ if (ts.isTypeLiteralNode(node)
146
+ || ts.isTypeReferenceNode(node)) {
147
+ return false;
148
+ }
149
+ if (ts.isFunctionLike(node)) {
150
+ pushScope();
151
+ walkFunctionDeclaration(node);
152
+ if ('body' in node) {
153
+ walkScope(node.body);
154
+ }
155
+ return;
156
+ }
157
+ if (ts.isCatchClause(node)) {
158
+ pushScope();
159
+ const { variableDeclaration: p } = node;
160
+ if (p && ts.isIdentifier(p.name)) {
161
+ registerLocalBinding(p.name);
162
+ }
163
+ walkScope(node.block);
164
+ return;
165
+ }
166
+ if (ts.isBlock(node)
167
+ && !ts.isFunctionLike(parent)
168
+ && !ts.isCatchClause(parent)) {
169
+ pushScope();
170
+ walkScope(node);
171
+ return;
172
+ }
173
+ if (ts.isIdentifier(node)
174
+ && isReferencedIdentifier(node, parent)
175
+ && !excludedIds.has(node)) {
176
+ const name = node.text;
177
+ if (currentScope[name]) {
178
+ const isShorthand = ts.isShorthandPropertyAssignment(parent);
179
+ references.push([node, isShorthand]);
180
+ }
181
+ }
182
+ }
183
+ function leave(node) {
184
+ if (parent) {
185
+ parentStack.pop();
186
+ }
187
+ if (ts.isFunctionLike(node)
188
+ || ts.isCatchClause(node)
189
+ || (ts.isBlock(node)
190
+ && !ts.isFunctionLike(parent)
191
+ && !ts.isCatchClause(parent))) {
192
+ popScope();
193
+ }
194
+ }
195
+ }
196
+ // TODO: more conditions
197
+ function isReferencedIdentifier(id, parent) {
198
+ if (!parent) {
199
+ return false;
200
+ }
201
+ if (id.text === 'arguments') {
202
+ return false;
203
+ }
204
+ if (ts.isExpressionWithTypeArguments(parent)
205
+ || ts.isInterfaceDeclaration(parent)
206
+ || ts.isTypeAliasDeclaration(parent)
207
+ || ts.isPropertySignature(parent)) {
208
+ return false;
209
+ }
210
+ if (ts.isPropertyAccessExpression(parent)
211
+ || ts.isPropertyAssignment(parent)
212
+ || ts.isPropertyDeclaration(parent)) {
213
+ if (parent.name === id) {
214
+ return false;
215
+ }
216
+ }
217
+ return true;
218
+ }
219
+ }
220
+ //# sourceMappingURL=vue-destructured-props-hints.js.map
@@ -1,2 +1,2 @@
1
- import type { LanguageServiceContext, LanguageServicePlugin } from '@volar/language-service';
2
- export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: LanguageServiceContext) => import('@vue/typescript-plugin/lib/requests').Requests | undefined): LanguageServicePlugin;
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(ts: typeof import('typescript'), { getImportPathForFile }: import('@vue/typescript-plugin/lib/requests').Requests): LanguageServicePlugin;
@@ -8,41 +8,28 @@ const getUserPreferences_1 = require("volar-service-typescript/lib/configs/getUs
8
8
  const vscode_uri_1 = require("vscode-uri");
9
9
  const nameCasing_1 = require("../nameCasing");
10
10
  const vue_extract_file_1 = require("../plugins/vue-extract-file");
11
- function create(ts, getTsPluginClient) {
11
+ const utils_1 = require("../utils");
12
+ function create(ts, { getImportPathForFile }) {
12
13
  return {
13
14
  name: 'vue-document-drop',
14
15
  capabilities: {
15
16
  documentDropEditsProvider: true,
16
17
  },
17
18
  create(context) {
18
- if (!context.project.vue) {
19
- return {};
20
- }
21
- let casing = nameCasing_1.TagNameCasing.Pascal; // TODO
22
- const tsPluginClient = getTsPluginClient?.(context);
23
- const vueCompilerOptions = context.project.vue.compilerOptions;
24
19
  return {
25
20
  async provideDocumentDropEdits(document, _position, dataTransfer) {
26
- if (document.languageId !== 'html') {
27
- return;
28
- }
29
- const uri = vscode_uri_1.URI.parse(document.uri);
30
- const decoded = context.decodeEmbeddedDocumentUri(uri);
31
- const sourceScript = decoded && context.language.scripts.get(decoded[0]);
32
- if (!sourceScript?.generated) {
33
- return;
34
- }
35
- const root = sourceScript.generated.root;
36
- if (!(root instanceof language_core_1.VueVirtualCode)) {
21
+ const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template', 'html');
22
+ if (!info) {
37
23
  return;
38
24
  }
25
+ const { sourceScript, root } = info;
39
26
  let importUri;
40
27
  for (const [mimeType, item] of dataTransfer) {
41
28
  if (mimeType === 'text/uri-list') {
42
29
  importUri = item.value;
43
30
  }
44
31
  }
45
- if (!importUri || !vueCompilerOptions.extensions.some(ext => importUri.endsWith(ext))) {
32
+ if (!importUri || !root.vueCompilerOptions.extensions.some(ext => importUri.endsWith(ext))) {
46
33
  return;
47
34
  }
48
35
  const { sfc } = root;
@@ -50,24 +37,20 @@ function create(ts, getTsPluginClient) {
50
37
  if (!script) {
51
38
  return;
52
39
  }
53
- let baseName = importUri.slice(importUri.lastIndexOf('/') + 1);
54
- baseName = baseName.slice(0, baseName.lastIndexOf('.'));
55
- const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName));
40
+ const casing = await (0, nameCasing_1.checkCasing)(context, sourceScript.id);
41
+ const baseName = path_browserify_1.posix.basename(importUri);
42
+ const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName.slice(0, baseName.lastIndexOf('.'))));
56
43
  const additionalEdit = {};
57
44
  const code = [...(0, language_core_1.forEachEmbeddedCode)(root)].find(code => code.id === (sfc.scriptSetup ? 'scriptsetup_raw' : 'script_raw'));
58
45
  const lastImportNode = (0, vue_extract_file_1.getLastImportNode)(ts, script.ast);
59
- const incomingFileName = context.project.typescript?.uriConverter.asFileName(vscode_uri_1.URI.parse(importUri))
60
- ?? vscode_uri_1.URI.parse(importUri).fsPath.replace(/\\/g, '/');
46
+ const incomingFileName = vscode_uri_1.URI.parse(importUri).fsPath.replace(/\\/g, '/');
61
47
  let importPath;
62
- const serviceScript = sourceScript.generated?.languagePlugin.typescript?.getServiceScript(root);
63
- if (tsPluginClient && serviceScript) {
48
+ const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(root);
49
+ if (serviceScript) {
64
50
  const tsDocumentUri = context.encodeEmbeddedDocumentUri(sourceScript.id, serviceScript.code.id);
65
51
  const tsDocument = context.documents.get(tsDocumentUri, serviceScript.code.languageId, serviceScript.code.snapshot);
66
52
  const preferences = await (0, getUserPreferences_1.getUserPreferences)(context, tsDocument);
67
- const importPathRequest = await tsPluginClient.getImportPathForFile(root.fileName, incomingFileName, preferences);
68
- if (importPathRequest) {
69
- importPath = importPathRequest;
70
- }
53
+ importPath = (await getImportPathForFile(root.fileName, incomingFileName, preferences) ?? {}).path;
71
54
  }
72
55
  if (!importPath) {
73
56
  importPath = path_browserify_1.posix.relative(path_browserify_1.posix.dirname(root.fileName), incomingFileName)
@@ -105,7 +88,7 @@ function create(ts, getTsPluginClient) {
105
88
  }
106
89
  }
107
90
  return {
108
- insertText: `<${casing === nameCasing_1.TagNameCasing.Kebab ? (0, shared_1.hyphenate)(newName) : newName}$0 />`,
91
+ insertText: `<${casing.tag === nameCasing_1.TagNameCasing.Kebab ? (0, shared_1.hyphenate)(newName) : newName}$0 />`,
109
92
  insertTextFormat: 2,
110
93
  additionalEdit,
111
94
  };
@@ -1,3 +1,2 @@
1
1
  import type { LanguageServicePlugin } from '@volar/language-service';
2
- import type * as ts from 'typescript';
3
- export declare function create(getDocumentHighlights: (fileName: string, position: number) => Promise<ts.DocumentHighlights[] | null>): LanguageServicePlugin;
2
+ export declare function create({ getDocumentHighlights }: import('@vue/typescript-plugin/lib/requests').Requests): LanguageServicePlugin;
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = create;
4
- const language_core_1 = require("@vue/language-core");
5
- const vscode_uri_1 = require("vscode-uri");
6
- function create(getDocumentHighlights) {
4
+ const utils_1 = require("../utils");
5
+ function create({ getDocumentHighlights }) {
7
6
  return {
8
7
  name: 'vue-document-highlights',
9
8
  capabilities: {
@@ -12,17 +11,11 @@ function create(getDocumentHighlights) {
12
11
  create(context) {
13
12
  return {
14
13
  async provideDocumentHighlights(document, position) {
15
- const uri = vscode_uri_1.URI.parse(document.uri);
16
- const decoded = context.decodeEmbeddedDocumentUri(uri);
17
- const sourceScript = decoded && context.language.scripts.get(decoded[0]);
18
- const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
19
- if (!sourceScript?.generated || virtualCode?.id !== 'main') {
20
- return;
21
- }
22
- const root = sourceScript.generated.root;
23
- if (!(root instanceof language_core_1.VueVirtualCode)) {
14
+ const info = (0, utils_1.getEmbeddedInfo)(context, document, 'main');
15
+ if (!info) {
24
16
  return;
25
17
  }
18
+ const { root } = info;
26
19
  const result = await getDocumentHighlights(root.fileName, document.offsetAt(position));
27
20
  return result
28
21
  ?.filter(({ fileName }) => fileName === root.fileName)
@@ -1,7 +1,7 @@
1
- import type { LanguageServiceContext, LanguageServicePlugin } from '@volar/language-service';
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
2
  import { type Sfc } from '@vue/language-core';
3
3
  import type * as ts from 'typescript';
4
- export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: LanguageServiceContext) => import('@vue/typescript-plugin/lib/requests').Requests | undefined): LanguageServicePlugin;
4
+ export declare function create(ts: typeof import('typescript'), { collectExtractProps }: import('@vue/typescript-plugin/lib/requests').Requests): LanguageServicePlugin;
5
5
  export declare function getLastImportNode(ts: typeof import('typescript'), sourceFile: ts.SourceFile): ts.Node | undefined;
6
6
  export declare function createAddComponentToOptionEdit(ts: typeof import('typescript'), sfc: Sfc, ast: ts.SourceFile, componentName: string): {
7
7
  range: import("@vue/language-core").TextRange;
@@ -5,8 +5,9 @@ exports.getLastImportNode = getLastImportNode;
5
5
  exports.createAddComponentToOptionEdit = createAddComponentToOptionEdit;
6
6
  const language_core_1 = require("@vue/language-core");
7
7
  const vscode_uri_1 = require("vscode-uri");
8
+ const utils_1 = require("../utils");
8
9
  const unicodeReg = /\\u/g;
9
- function create(ts, getTsPluginClient) {
10
+ function create(ts, { collectExtractProps }) {
10
11
  return {
11
12
  name: 'vue-extract-file',
12
13
  capabilities: {
@@ -16,7 +17,6 @@ function create(ts, getTsPluginClient) {
16
17
  },
17
18
  },
18
19
  create(context) {
19
- const tsPluginClient = getTsPluginClient?.(context);
20
20
  return {
21
21
  provideCodeActions(document, range, ctx) {
22
22
  if (ctx.only && !ctx.only.includes('refactor')) {
@@ -27,17 +27,11 @@ function create(ts, getTsPluginClient) {
27
27
  if (startOffset === endOffset) {
28
28
  return;
29
29
  }
30
- const uri = vscode_uri_1.URI.parse(document.uri);
31
- const decoded = context.decodeEmbeddedDocumentUri(uri);
32
- const sourceScript = decoded && context.language.scripts.get(decoded[0]);
33
- const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
34
- if (!sourceScript?.generated || virtualCode?.id !== 'template') {
35
- return;
36
- }
37
- const root = sourceScript.generated.root;
38
- if (!(root instanceof language_core_1.VueVirtualCode)) {
30
+ const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template');
31
+ if (!info) {
39
32
  return;
40
33
  }
34
+ const { root } = info;
41
35
  const { sfc } = root;
42
36
  const script = sfc.scriptSetup ?? sfc.script;
43
37
  if (!sfc.template || !script) {
@@ -62,17 +56,11 @@ function create(ts, getTsPluginClient) {
62
56
  async resolveCodeAction(codeAction) {
63
57
  const { uri, range, newName } = codeAction.data;
64
58
  const [startOffset, endOffset] = range;
65
- const parsedUri = vscode_uri_1.URI.parse(uri);
66
- const decoded = context.decodeEmbeddedDocumentUri(parsedUri);
67
- const sourceScript = decoded && context.language.scripts.get(decoded[0]);
68
- const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
69
- if (!sourceScript?.generated || virtualCode?.id !== 'template') {
70
- return codeAction;
71
- }
72
- const root = sourceScript.generated.root;
73
- if (!(root instanceof language_core_1.VueVirtualCode)) {
59
+ const info = (0, utils_1.getEmbeddedInfo)(context, { uri }, 'template');
60
+ if (!info) {
74
61
  return codeAction;
75
62
  }
63
+ const { sourceScript, virtualCode, root } = info;
76
64
  const { sfc } = root;
77
65
  const script = sfc.scriptSetup ?? sfc.script;
78
66
  if (!sfc.template || !script) {
@@ -82,14 +70,11 @@ function create(ts, getTsPluginClient) {
82
70
  if (!templateCodeRange) {
83
71
  return codeAction;
84
72
  }
85
- const toExtract = await tsPluginClient?.collectExtractProps(root.fileName, templateCodeRange) ?? [];
86
- if (!toExtract) {
87
- return codeAction;
88
- }
73
+ const toExtract = await collectExtractProps(root.fileName, templateCodeRange) ?? [];
89
74
  const templateInitialIndent = await context.env.getConfiguration('vue.format.template.initialIndent') ?? true;
90
75
  const scriptInitialIndent = await context.env.getConfiguration('vue.format.script.initialIndent')
91
76
  ?? false;
92
- const document = context.documents.get(parsedUri, virtualCode.languageId, virtualCode.snapshot);
77
+ const document = context.documents.get(vscode_uri_1.URI.parse(uri), virtualCode.languageId, virtualCode.snapshot);
93
78
  const sfcDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
94
79
  const newUri = sfcDocument.uri.slice(0, sfcDocument.uri.lastIndexOf('/') + 1) + `${newName}.vue`;
95
80
  const lastImportNode = getLastImportNode(ts, script.ast);
@@ -184,7 +169,7 @@ function create(ts, getTsPluginClient) {
184
169
  const props = toExtract.filter(p => !p.model);
185
170
  const models = toExtract.filter(p => p.model);
186
171
  if (props.length) {
187
- lines.push(`defineProps<{ \n\t${props.map(p => `${p.name}: ${p.type};`).join('\n\t')}\n}>()`);
172
+ lines.push(`defineProps<{\n\t${props.map(p => `${p.name}: ${p.type};`).join('\n\t')}\n}>()`);
188
173
  }
189
174
  for (const model of models) {
190
175
  lines.push(`const ${model.name} = defineModel<${model.type}>('${model.name}', { required: true })`);
@@ -1,11 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = create;
4
- const language_core_1 = require("@vue/language-core");
5
- const vscode_uri_1 = require("vscode-uri");
4
+ const utils_1 = require("../utils");
6
5
  function create() {
7
6
  return {
8
- name: 'vue-compiler-dom-errors',
7
+ name: 'vue-global-types-error',
9
8
  capabilities: {
10
9
  diagnosticProvider: {
11
10
  interFileDependencies: false,
@@ -15,17 +14,12 @@ function create() {
15
14
  create(context) {
16
15
  return {
17
16
  provideDiagnostics(document) {
18
- if (document.languageId !== 'vue-root-tags') {
17
+ const info = (0, utils_1.getEmbeddedInfo)(context, document, 'root_tags');
18
+ if (!info) {
19
19
  return;
20
20
  }
21
- const uri = vscode_uri_1.URI.parse(document.uri);
22
- const decoded = context.decodeEmbeddedDocumentUri(uri);
23
- const sourceScript = decoded && context.language.scripts.get(decoded[0]);
24
- if (!sourceScript?.generated) {
25
- return;
26
- }
27
- const root = sourceScript.generated.root;
28
- if (!(root instanceof language_core_1.VueVirtualCode)) {
21
+ const { sourceScript, root } = info;
22
+ if (sourceScript.id.scheme !== 'file') {
29
23
  return;
30
24
  }
31
25
  const { vueCompilerOptions } = root;
@@ -38,10 +32,19 @@ function create() {
38
32
  start: document.positionAt(0),
39
33
  end: document.positionAt(0),
40
34
  },
41
- severity: 1,
35
+ severity: 2,
42
36
  code: 404,
43
37
  source: 'vue',
44
- message: `Write global types file failed. Please ensure that "node_modules" exists and "${vueCompilerOptions.lib}" is a direct dependency, or set "vueCompilerOptions.globalTypesPath" in "tsconfig.json" manually.`,
38
+ message: `
39
+ Failed to write the global types file. Make sure that:
40
+
41
+ 1. "node_modules" directory exists.
42
+ 2. "${vueCompilerOptions.lib}" is installed as a direct dependency.
43
+
44
+ Alternatively, you can manually set "vueCompilerOptions.globalTypesPath" in your "tsconfig.json".
45
+
46
+ If all dependencies are installed, try running the "vue.action.restartServer" command to restart Vue and TS servers.
47
+ `.trim(),
45
48
  }];
46
49
  },
47
50
  };