@vue/language-service 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export * from '@volar/language-service';
2
2
  export * from '@vue/language-core';
3
3
  export * from './lib/ideFeatures/nameCasing';
4
4
  export * from './lib/types';
5
- import type { ServiceEnvironment, ServicePlugin } from '@volar/language-service';
5
+ import type { ServiceContext, ServiceEnvironment, ServicePlugin } from '@volar/language-service';
6
6
  import type { VueCompilerOptions } from './lib/types';
7
- export declare function createVueServicePlugins(ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): ServicePlugin[];
7
+ export declare function createVueServicePlugins(ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions, getTsPluginClient?: (context: ServiceContext) => typeof import("@vue/typescript-plugin/lib/client") | undefined, hybridMode?: boolean): ServicePlugin[];
8
+ export declare function createDefaultGetTsPluginClient(ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions): (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined;
package/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.createVueServicePlugins = void 0;
17
+ exports.createDefaultGetTsPluginClient = exports.createVueServicePlugins = void 0;
18
18
  __exportStar(require("@volar/language-service"), exports);
19
19
  __exportStar(require("@vue/language-core"), exports);
20
20
  __exportStar(require("./lib/ideFeatures/nameCasing"), exports);
@@ -24,6 +24,8 @@ const volar_service_json_1 = require("volar-service-json");
24
24
  const volar_service_pug_beautify_1 = require("volar-service-pug-beautify");
25
25
  const volar_service_typescript_1 = require("volar-service-typescript");
26
26
  const volar_service_typescript_twoslash_queries_1 = require("volar-service-typescript-twoslash-queries");
27
+ const docCommentTemplate_1 = require("volar-service-typescript/lib/plugins/docCommentTemplate");
28
+ const syntactic_1 = require("volar-service-typescript/lib/plugins/syntactic");
27
29
  const css_1 = require("./lib/plugins/css");
28
30
  const vue_autoinsert_dotvalue_1 = require("./lib/plugins/vue-autoinsert-dotvalue");
29
31
  const vue_autoinsert_parentheses_1 = require("./lib/plugins/vue-autoinsert-parentheses");
@@ -37,28 +39,83 @@ const vue_template_1 = require("./lib/plugins/vue-template");
37
39
  const vue_toggle_v_bind_codeaction_1 = require("./lib/plugins/vue-toggle-v-bind-codeaction");
38
40
  const vue_twoslash_queries_1 = require("./lib/plugins/vue-twoslash-queries");
39
41
  const vue_visualize_hidden_callback_param_1 = require("./lib/plugins/vue-visualize-hidden-callback-param");
40
- function createVueServicePlugins(ts, getVueOptions, tsPluginClient) {
41
- return [
42
- (0, volar_service_typescript_1.create)(ts),
43
- (0, volar_service_typescript_twoslash_queries_1.create)(),
44
- (0, css_1.create)(),
45
- (0, volar_service_pug_beautify_1.create)(),
46
- (0, volar_service_json_1.create)(),
47
- (0, vue_template_1.create)('html', ts, getVueOptions, tsPluginClient),
48
- (0, vue_template_1.create)('pug', ts, getVueOptions, tsPluginClient),
49
- (0, vue_sfc_1.create)(),
50
- (0, vue_twoslash_queries_1.create)(ts, tsPluginClient),
51
- (0, vue_codelens_references_1.create)(),
52
- (0, vue_document_drop_1.create)(ts),
53
- (0, vue_autoinsert_dotvalue_1.create)(ts, tsPluginClient),
54
- (0, vue_autoinsert_parentheses_1.create)(ts),
55
- (0, vue_autoinsert_space_1.create)(),
56
- (0, vue_visualize_hidden_callback_param_1.create)(),
57
- (0, vue_directive_comments_1.create)(),
58
- (0, vue_extract_file_1.create)(ts, tsPluginClient),
59
- (0, vue_toggle_v_bind_codeaction_1.create)(ts),
60
- (0, volar_service_emmet_1.create)(),
61
- ];
42
+ const common_1 = require("@vue/typescript-plugin/lib/common");
43
+ const collectExtractProps_1 = require("@vue/typescript-plugin/lib/requests/collectExtractProps");
44
+ const componentInfos_1 = require("@vue/typescript-plugin/lib/requests/componentInfos");
45
+ const getPropertiesAtLocation_1 = require("@vue/typescript-plugin/lib/requests/getPropertiesAtLocation");
46
+ const getQuickInfoAtPosition_1 = require("@vue/typescript-plugin/lib/requests/getQuickInfoAtPosition");
47
+ function createVueServicePlugins(ts, getVueOptions, getTsPluginClient = createDefaultGetTsPluginClient(ts, getVueOptions), hybridMode = false) {
48
+ const plugins = [];
49
+ if (!hybridMode) {
50
+ plugins.push(...(0, volar_service_typescript_1.create)(ts));
51
+ for (let i = 0; i < plugins.length; i++) {
52
+ const plugin = plugins[i];
53
+ if (plugin.name === 'typescript-semantic') {
54
+ plugins[i] = {
55
+ ...plugin,
56
+ create(context) {
57
+ const created = plugin.create(context);
58
+ if (!context.language.typescript) {
59
+ return created;
60
+ }
61
+ const languageService = created.provide['typescript/languageService']();
62
+ const vueOptions = getVueOptions(context.env);
63
+ (0, common_1.decorateLanguageServiceForVue)(context.language.files, languageService, vueOptions, ts, false);
64
+ return created;
65
+ },
66
+ };
67
+ break;
68
+ }
69
+ }
70
+ }
71
+ else {
72
+ plugins.push((0, syntactic_1.create)(ts), (0, docCommentTemplate_1.create)(ts));
73
+ }
74
+ plugins.push((0, volar_service_typescript_twoslash_queries_1.create)(ts), (0, css_1.create)(), (0, volar_service_pug_beautify_1.create)(), (0, volar_service_json_1.create)(), (0, vue_template_1.create)('html', ts, getVueOptions, getTsPluginClient), (0, vue_template_1.create)('pug', ts, getVueOptions, getTsPluginClient), (0, vue_sfc_1.create)(), (0, vue_twoslash_queries_1.create)(ts, getTsPluginClient), (0, vue_codelens_references_1.create)(), (0, vue_document_drop_1.create)(ts), (0, vue_autoinsert_dotvalue_1.create)(ts, getTsPluginClient), (0, vue_autoinsert_parentheses_1.create)(ts), (0, vue_autoinsert_space_1.create)(), (0, vue_visualize_hidden_callback_param_1.create)(), (0, vue_directive_comments_1.create)(), (0, vue_extract_file_1.create)(ts, getTsPluginClient), (0, vue_toggle_v_bind_codeaction_1.create)(ts), (0, volar_service_emmet_1.create)());
75
+ return plugins;
62
76
  }
63
77
  exports.createVueServicePlugins = createVueServicePlugins;
78
+ function createDefaultGetTsPluginClient(ts, getVueOptions) {
79
+ return context => {
80
+ if (!context.language.typescript) {
81
+ return;
82
+ }
83
+ const requestContext = {
84
+ typescript: ts,
85
+ files: context.language.files,
86
+ languageService: context.inject('typescript/languageService'),
87
+ vueOptions: getVueOptions(context.env),
88
+ isTsPlugin: false,
89
+ getFileId: context.env.typescript.fileNameToUri,
90
+ };
91
+ return {
92
+ async collectExtractProps(...args) {
93
+ return await collectExtractProps_1.collectExtractProps.apply(requestContext, args);
94
+ },
95
+ async getPropertiesAtLocation(...args) {
96
+ return await getPropertiesAtLocation_1.getPropertiesAtLocation.apply(requestContext, args);
97
+ },
98
+ async getComponentEvents(...args) {
99
+ return await componentInfos_1.getComponentEvents.apply(requestContext, args);
100
+ },
101
+ async getComponentNames(...args) {
102
+ return await componentInfos_1.getComponentNames.apply(requestContext, args);
103
+ },
104
+ async getComponentProps(...args) {
105
+ return await componentInfos_1.getComponentProps.apply(requestContext, args);
106
+ },
107
+ async getElementAttrs(...args) {
108
+ return await componentInfos_1.getElementAttrs.apply(requestContext, args);
109
+ },
110
+ async getTemplateContextProps(...args) {
111
+ return await componentInfos_1.getTemplateContextProps.apply(requestContext, args);
112
+ },
113
+ async getQuickInfoAtPosition(...args) {
114
+ return await getQuickInfoAtPosition_1.getQuickInfoAtPosition.apply(requestContext, args);
115
+ },
116
+ };
117
+ };
118
+ ;
119
+ }
120
+ exports.createDefaultGetTsPluginClient = createDefaultGetTsPluginClient;
64
121
  //# sourceMappingURL=index.js.map
@@ -1,8 +1,8 @@
1
1
  import type { ServiceContext } from '@volar/language-service';
2
2
  import type * as vscode from 'vscode-languageserver-protocol';
3
3
  import { AttrNameCasing, TagNameCasing } from '../types';
4
- export declare function convertTagName(context: ServiceContext, uri: string, casing: TagNameCasing, tsPluginClient: typeof import('@vue/typescript-plugin/lib/client')): Promise<vscode.TextEdit[] | undefined>;
5
- export declare function convertAttrName(context: ServiceContext, uri: string, casing: AttrNameCasing, tsPluginClient: typeof import('@vue/typescript-plugin/lib/client')): Promise<vscode.TextEdit[] | undefined>;
4
+ export declare function convertTagName(context: ServiceContext, uri: string, casing: TagNameCasing, tsPluginClient: typeof import('@vue/typescript-plugin/lib/client') | undefined): Promise<vscode.TextEdit[] | undefined>;
5
+ export declare function convertAttrName(context: ServiceContext, uri: string, casing: AttrNameCasing, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): Promise<vscode.TextEdit[] | undefined>;
6
6
  export declare function getNameCasing(context: ServiceContext, uri: string, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): Promise<{
7
7
  tag: TagNameCasing;
8
8
  attr: AttrNameCasing;
@@ -7,18 +7,21 @@ const computeds_1 = require("computeds");
7
7
  const types_1 = require("../types");
8
8
  async function convertTagName(context, uri, casing, tsPluginClient) {
9
9
  const sourceFile = context.language.files.get(uri);
10
- if (!sourceFile)
10
+ if (!sourceFile) {
11
11
  return;
12
+ }
12
13
  const rootCode = sourceFile?.generated?.code;
13
- if (!(rootCode instanceof language_core_1.VueGeneratedCode))
14
+ if (!(rootCode instanceof language_core_1.VueGeneratedCode)) {
14
15
  return;
16
+ }
15
17
  const desc = rootCode.sfc;
16
- if (!desc.template)
18
+ if (!desc.template) {
17
19
  return;
20
+ }
18
21
  const template = desc.template;
19
22
  const document = context.documents.get(sourceFile.id, sourceFile.languageId, sourceFile.snapshot);
20
23
  const edits = [];
21
- const components = await tsPluginClient.getComponentNames(rootCode.fileName) ?? [];
24
+ const components = await tsPluginClient?.getComponentNames(rootCode.fileName) ?? [];
22
25
  const tags = getTemplateTagsAndAttrs(rootCode);
23
26
  for (const [tagName, { offsets }] of tags) {
24
27
  const componentName = components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
@@ -41,23 +44,26 @@ async function convertTagName(context, uri, casing, tsPluginClient) {
41
44
  exports.convertTagName = convertTagName;
42
45
  async function convertAttrName(context, uri, casing, tsPluginClient) {
43
46
  const sourceFile = context.language.files.get(uri);
44
- if (!sourceFile)
47
+ if (!sourceFile) {
45
48
  return;
49
+ }
46
50
  const rootCode = sourceFile?.generated?.code;
47
- if (!(rootCode instanceof language_core_1.VueGeneratedCode))
51
+ if (!(rootCode instanceof language_core_1.VueGeneratedCode)) {
48
52
  return;
53
+ }
49
54
  const desc = rootCode.sfc;
50
- if (!desc.template)
55
+ if (!desc.template) {
51
56
  return;
57
+ }
52
58
  const template = desc.template;
53
59
  const document = context.documents.get(uri, sourceFile.languageId, sourceFile.snapshot);
54
60
  const edits = [];
55
- const components = await tsPluginClient.getComponentNames(rootCode.fileName) ?? [];
61
+ const components = await tsPluginClient?.getComponentNames(rootCode.fileName) ?? [];
56
62
  const tags = getTemplateTagsAndAttrs(rootCode);
57
63
  for (const [tagName, { attrs }] of tags) {
58
64
  const componentName = components.find(component => component === tagName || (0, language_core_1.hyphenateTag)(component) === tagName);
59
65
  if (componentName) {
60
- const props = await tsPluginClient.getComponentProps(rootCode.fileName, componentName) ?? [];
66
+ const props = await tsPluginClient?.getComponentProps(rootCode.fileName, componentName) ?? [];
61
67
  for (const [attrName, { offsets }] of attrs) {
62
68
  const propName = props.find(prop => prop === attrName || (0, language_core_1.hyphenateAttr)(prop) === attrName);
63
69
  if (propName) {
@@ -163,8 +169,9 @@ const map = new WeakMap();
163
169
  function getTemplateTagsAndAttrs(sourceFile) {
164
170
  if (!map.has(sourceFile)) {
165
171
  const getter = (0, computeds_1.computed)(() => {
166
- if (!(sourceFile instanceof vue.VueGeneratedCode))
172
+ if (!(sourceFile instanceof vue.VueGeneratedCode)) {
167
173
  return;
174
+ }
168
175
  const ast = sourceFile.sfc.template?.ast;
169
176
  const tags = new Map();
170
177
  if (ast) {
@@ -33,12 +33,15 @@ function loadTemplateData(lang) {
33
33
  const vOn = data.globalAttributes?.find(d => d.name === 'v-on');
34
34
  const vSlot = data.globalAttributes?.find(d => d.name === 'v-slot');
35
35
  const vBind = data.globalAttributes?.find(d => d.name === 'v-bind');
36
- if (vOn)
36
+ if (vOn) {
37
37
  data.globalAttributes?.push({ ...vOn, name: '@' });
38
- if (vSlot)
38
+ }
39
+ if (vSlot) {
39
40
  data.globalAttributes?.push({ ...vSlot, name: '#' });
40
- if (vBind)
41
+ }
42
+ if (vBind) {
41
43
  data.globalAttributes?.push({ ...vBind, name: ':' });
44
+ }
42
45
  return data;
43
46
  }
44
47
  exports.loadTemplateData = loadTemplateData;
@@ -1,8 +1,8 @@
1
- import type { ServicePlugin } from '@volar/language-service';
1
+ import type { ServiceContext, ServicePlugin } from '@volar/language-service';
2
2
  import type * as ts from 'typescript';
3
3
  import type * as vscode from 'vscode-languageserver-protocol';
4
4
  import type { TextDocument } from 'vscode-languageserver-textdocument';
5
- export declare function create(ts: typeof import('typescript'), tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): ServicePlugin;
5
+ export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): ServicePlugin;
6
6
  export declare function isCharacterTyping(document: TextDocument, lastChange: {
7
7
  range: vscode.Range;
8
8
  text: string;
@@ -11,28 +11,34 @@ function getAst(ts, fileName, snapshot, scriptKind) {
11
11
  }
12
12
  return ast;
13
13
  }
14
- function create(ts, tsPluginClient) {
14
+ function create(ts, getTsPluginClient) {
15
15
  return {
16
16
  name: 'vue-autoinsert-dotvalue',
17
17
  create(context) {
18
+ const tsPluginClient = getTsPluginClient?.(context);
18
19
  let currentReq = 0;
19
20
  return {
20
21
  async provideAutoInsertionEdit(document, position, lastChange) {
21
- if (!isTsDocument(document))
22
+ if (!isTsDocument(document)) {
22
23
  return;
23
- if (!isCharacterTyping(document, lastChange))
24
+ }
25
+ if (!isCharacterTyping(document, lastChange)) {
24
26
  return;
27
+ }
25
28
  const req = ++currentReq;
26
29
  // Wait for tsserver to sync
27
30
  await sleep(250);
28
- if (req !== currentReq)
31
+ if (req !== currentReq) {
29
32
  return;
33
+ }
30
34
  const enabled = await context.env.getConfiguration?.('vue.autoInsert.dotValue') ?? true;
31
- if (!enabled)
35
+ if (!enabled) {
32
36
  return;
37
+ }
33
38
  const [code, file] = context.documents.getVirtualCodeByUri(document.uri);
34
- if (!file)
39
+ if (!file) {
35
40
  return;
41
+ }
36
42
  let ast;
37
43
  let sourceCodeOffset = document.offsetAt(position);
38
44
  const fileName = context.env.typescript.uriToFileName(file.id);
@@ -58,8 +64,9 @@ function create(ts, tsPluginClient) {
58
64
  else {
59
65
  ast = getAst(ts, fileName, file.snapshot);
60
66
  }
61
- if (isBlacklistNode(ts, ast, document.offsetAt(position), false))
67
+ if (isBlacklistNode(ts, ast, document.offsetAt(position), false)) {
62
68
  return;
69
+ }
63
70
  const props = await tsPluginClient?.getPropertiesAtLocation(fileName, sourceCodeOffset) ?? [];
64
71
  if (props.some(prop => prop === 'value')) {
65
72
  return '${1:.value}';
@@ -137,8 +144,9 @@ function isBlacklistNode(ts, node, pos, allowAccessDotValue) {
137
144
  else {
138
145
  let _isBlacklistNode = false;
139
146
  node.forEachChild(node => {
140
- if (_isBlacklistNode)
147
+ if (_isBlacklistNode) {
141
148
  return;
149
+ }
142
150
  if (pos >= node.getFullStart() && pos <= node.getEnd()) {
143
151
  if (isBlacklistNode(ts, node, pos, allowAccessDotValue)) {
144
152
  _isBlacklistNode = true;
@@ -9,13 +9,16 @@ function create(ts) {
9
9
  return {
10
10
  async provideAutoInsertionEdit(document, position, lastChange) {
11
11
  const enabled = await context.env.getConfiguration?.('vue.autoInsert.parentheses') ?? false;
12
- if (!enabled)
12
+ if (!enabled) {
13
13
  return;
14
- if (!(0, vue_autoinsert_dotvalue_1.isCharacterTyping)(document, lastChange))
14
+ }
15
+ if (!(0, vue_autoinsert_dotvalue_1.isCharacterTyping)(document, lastChange)) {
15
16
  return;
17
+ }
16
18
  const [virtualCode] = context.documents.getVirtualCodeByUri(document.uri);
17
- if (virtualCode?.id !== 'template_format')
19
+ if (virtualCode?.id !== 'template_format') {
18
20
  return;
21
+ }
19
22
  const offset = document.offsetAt(position);
20
23
  for (const mappedRange of virtualCode.mappings) {
21
24
  const generatedCodeEnd = mappedRange.generatedOffsets[mappedRange.generatedOffsets.length - 1]
@@ -9,8 +9,9 @@ function create() {
9
9
  async provideAutoInsertionEdit(document, _, lastChange) {
10
10
  if (document.languageId === 'html' || document.languageId === 'jade') {
11
11
  const enabled = await context.env.getConfiguration?.('vue.autoInsert.bracketSpacing') ?? true;
12
- if (!enabled)
12
+ if (!enabled) {
13
13
  return;
14
+ }
14
15
  if (lastChange.text === '{}'
15
16
  && document.getText({
16
17
  start: { line: lastChange.range.start.line, character: lastChange.range.start.character - 1 },
@@ -12,8 +12,9 @@ function create() {
12
12
  const result = [];
13
13
  for (const map of context.documents.getMaps(virtualCode) ?? []) {
14
14
  for (const mapping of map.map.mappings) {
15
- if (!mapping.data.__referencesCodeLens)
15
+ if (!mapping.data.__referencesCodeLens) {
16
16
  continue;
17
+ }
17
18
  result.push({
18
19
  start: document.positionAt(mapping.generatedOffsets[0]),
19
20
  end: document.positionAt(mapping.generatedOffsets[mapping.generatedOffsets.length - 1]
@@ -27,8 +28,9 @@ function create() {
27
28
  };
28
29
  function worker(uri, callback) {
29
30
  const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(uri);
30
- if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || !sourceFile)
31
+ if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || !sourceFile) {
31
32
  return;
33
+ }
32
34
  return callback(virtualCode, sourceFile);
33
35
  }
34
36
  },
@@ -14,12 +14,14 @@ function create() {
14
14
  create() {
15
15
  return {
16
16
  provideCompletionItems(document, position) {
17
- if (document.languageId !== 'html')
17
+ if (document.languageId !== 'html') {
18
18
  return;
19
+ }
19
20
  const line = document.getText({ start: { line: position.line, character: 0 }, end: position });
20
21
  const cmdStart = line.match(directiveCommentReg);
21
- if (!cmdStart)
22
+ if (!cmdStart) {
22
23
  return;
24
+ }
23
25
  const startIndex = cmdStart.index + cmdStart[0].length;
24
26
  const remainText = line.substring(startIndex);
25
27
  const result = [];
@@ -27,7 +29,6 @@ function create() {
27
29
  let match = true;
28
30
  for (let i = 0; i < remainText.length; i++) {
29
31
  if (remainText[i] !== cmd[i]) {
30
- console.log(JSON.stringify(remainText[i]), JSON.stringify(cmd[i]));
31
32
  match = false;
32
33
  break;
33
34
  }
@@ -13,27 +13,31 @@ function create(ts) {
13
13
  let casing = types_1.TagNameCasing.Pascal; // TODO
14
14
  return {
15
15
  async provideDocumentDropEdits(document, _position, dataTransfer) {
16
- if (document.languageId !== 'html')
16
+ if (document.languageId !== 'html') {
17
17
  return;
18
+ }
18
19
  const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
19
20
  const vueVirtualCode = sourceFile?.generated?.code;
20
- if (!virtualCode || !(vueVirtualCode instanceof language_core_1.VueGeneratedCode))
21
+ if (!virtualCode || !(vueVirtualCode instanceof language_core_1.VueGeneratedCode)) {
21
22
  return;
23
+ }
22
24
  let importUri;
23
25
  for (const [mimeType, item] of dataTransfer) {
24
26
  if (mimeType === 'text/uri-list') {
25
27
  importUri = item.value;
26
28
  }
27
29
  }
28
- if (!importUri?.endsWith('.vue'))
30
+ if (!importUri?.endsWith('.vue')) {
29
31
  return;
32
+ }
30
33
  let baseName = importUri.substring(importUri.lastIndexOf('/') + 1);
31
34
  baseName = baseName.substring(0, baseName.lastIndexOf('.'));
32
35
  const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName));
33
36
  const { sfc } = vueVirtualCode;
34
37
  const script = sfc.scriptSetup ?? sfc.script;
35
- if (!script)
38
+ if (!script) {
36
39
  return;
40
+ }
37
41
  const additionalEdit = {};
38
42
  const code = [...(0, language_core_1.forEachEmbeddedCode)(vueVirtualCode)].find(code => code.id === (sfc.scriptSetup ? 'scriptSetupFormat' : 'scriptFormat'));
39
43
  const lastImportNode = (0, vue_extract_file_1.getLastImportNode)(ts, script.ast);
@@ -1,6 +1,6 @@
1
- import type { ServicePlugin } from '@volar/language-service';
1
+ import type { ServiceContext, ServicePlugin } from '@volar/language-service';
2
2
  import type * as ts from 'typescript';
3
- export declare function create(ts: typeof import('typescript'), tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): ServicePlugin;
3
+ export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): ServicePlugin;
4
4
  export declare function getLastImportNode(ts: typeof import('typescript'), sourceFile: ts.SourceFile): ts.Node | undefined;
5
5
  export declare function createAddComponentToOptionEdit(ts: typeof import('typescript'), ast: ts.SourceFile, componentName: string): {
6
6
  range: import("@vue/language-core").TextRange;
@@ -3,10 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createAddComponentToOptionEdit = exports.getLastImportNode = exports.create = void 0;
4
4
  const language_core_1 = require("@vue/language-core");
5
5
  const unicodeReg = /\\u/g;
6
- function create(ts, tsPluginClient) {
6
+ function create(ts, getTsPluginClient) {
7
7
  return {
8
8
  name: 'vue-extract-file',
9
9
  create(context) {
10
+ const tsPluginClient = getTsPluginClient?.(context);
10
11
  return {
11
12
  async provideCodeActions(document, range, _context) {
12
13
  const startOffset = document.offsetAt(range.start);
@@ -15,15 +16,18 @@ function create(ts, tsPluginClient) {
15
16
  return;
16
17
  }
17
18
  const [code, vueCode] = context.documents.getVirtualCodeByUri(document.uri);
18
- if (!(vueCode?.generated?.code instanceof language_core_1.VueGeneratedCode) || code?.id !== 'template')
19
+ if (!(vueCode?.generated?.code instanceof language_core_1.VueGeneratedCode) || code?.id !== 'template') {
19
20
  return;
21
+ }
20
22
  const { sfc } = vueCode.generated.code;
21
23
  const script = sfc.scriptSetup ?? sfc.script;
22
- if (!sfc.template || !script)
24
+ if (!sfc.template || !script) {
23
25
  return;
26
+ }
24
27
  const templateCodeRange = selectTemplateCode(startOffset, endOffset, sfc.template);
25
- if (!templateCodeRange)
28
+ if (!templateCodeRange) {
26
29
  return;
30
+ }
27
31
  return [
28
32
  {
29
33
  title: 'Extract into new dumb component',
@@ -40,20 +44,24 @@ function create(ts, tsPluginClient) {
40
44
  const { uri, range, newName } = codeAction.data;
41
45
  const [startOffset, endOffset] = range;
42
46
  const [code, sourceFile] = context.documents.getVirtualCodeByUri(uri);
43
- if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || code?.id !== 'template')
47
+ if (!(sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) || code?.id !== 'template') {
44
48
  return codeAction;
49
+ }
45
50
  const document = context.documents.get(uri, code.languageId, code.snapshot);
46
51
  const sfcDocument = context.documents.get(sourceFile.id, sourceFile.languageId, sourceFile.snapshot);
47
52
  const { sfc } = sourceFile.generated.code;
48
53
  const script = sfc.scriptSetup ?? sfc.script;
49
- if (!sfc.template || !script)
54
+ if (!sfc.template || !script) {
50
55
  return codeAction;
56
+ }
51
57
  const templateCodeRange = selectTemplateCode(startOffset, endOffset, sfc.template);
52
- if (!templateCodeRange)
58
+ if (!templateCodeRange) {
53
59
  return codeAction;
60
+ }
54
61
  const toExtract = await tsPluginClient?.collectExtractProps(sourceFile.generated.code.fileName, templateCodeRange) ?? [];
55
- if (!toExtract)
62
+ if (!toExtract) {
56
63
  return codeAction;
64
+ }
57
65
  const templateInitialIndent = await context.env.getConfiguration('vue.format.template.initialIndent') ?? true;
58
66
  const scriptInitialIndent = await context.env.getConfiguration('vue.format.script.initialIndent') ?? false;
59
67
  const newUri = sfcDocument.uri.substring(0, sfcDocument.uri.lastIndexOf('/') + 1) + `${newName}.vue`;
@@ -200,8 +208,9 @@ function selectTemplateCode(startOffset, endOffset, templateBlock) {
200
208
  }
201
209
  }
202
210
  function constructTag(name, attributes, initialIndent, content) {
203
- if (initialIndent)
211
+ if (initialIndent) {
204
212
  content = content.split('\n').map(line => `\t${line}`).join('\n');
213
+ }
205
214
  const attributesString = attributes.length ? ` ${attributes.join(' ')}` : '';
206
215
  return `<${name}${attributesString}>\n${content}\n</${name}>\n`;
207
216
  }
@@ -220,8 +229,9 @@ function getLastImportNode(ts, sourceFile) {
220
229
  exports.getLastImportNode = getLastImportNode;
221
230
  function createAddComponentToOptionEdit(ts, ast, componentName) {
222
231
  const exportDefault = language_core_1.scriptRanges.parseScriptRanges(ts, ast, false, true).exportDefault;
223
- if (!exportDefault)
232
+ if (!exportDefault) {
224
233
  return;
234
+ }
225
235
  // https://github.com/microsoft/TypeScript/issues/36174
226
236
  const printer = ts.createPrinter();
227
237
  if (exportDefault.componentsOption && exportDefault.componentsOptionNode) {
@@ -12,16 +12,18 @@ function create() {
12
12
  create(context) {
13
13
  const htmlPlugin = (0, volar_service_html_1.create)({
14
14
  documentSelector: ['vue'],
15
- useCustomDataProviders: false,
15
+ useDefaultDataProvider: false,
16
+ getCustomData(context) {
17
+ sfcDataProvider ??= html.newHTMLDataProvider('vue', (0, data_1.loadLanguageBlocks)(context.env.locale ?? 'en'));
18
+ return [sfcDataProvider];
19
+ },
16
20
  }).create(context);
17
21
  const htmlLanguageService = htmlPlugin.provide['html/languageService']();
18
- sfcDataProvider ??= html.newHTMLDataProvider('vue', (0, data_1.loadLanguageBlocks)(context.env.locale ?? 'en'));
19
- htmlLanguageService.setDataProviders(false, [sfcDataProvider]);
20
22
  return {
21
23
  ...htmlPlugin,
22
24
  provide: {
23
25
  'vue/vueFile': document => {
24
- return worker(document, (vueFile) => {
26
+ return worker(document, vueFile => {
25
27
  return vueFile;
26
28
  });
27
29
  },
@@ -49,7 +51,7 @@ function create() {
49
51
  },
50
52
  provideDocumentLinks: undefined,
51
53
  provideDocumentSymbols(document) {
52
- return worker(document, (vueSourceFile) => {
54
+ return worker(document, vueSourceFile => {
53
55
  const result = [];
54
56
  const descriptor = vueSourceFile.sfc;
55
57
  if (descriptor.template) {
@@ -96,10 +98,12 @@ function create() {
96
98
  }
97
99
  for (const style of descriptor.styles) {
98
100
  let name = 'style';
99
- if (style.scoped)
101
+ if (style.scoped) {
100
102
  name += ' scoped';
101
- if (style.module)
103
+ }
104
+ if (style.module) {
102
105
  name += ' module';
106
+ }
103
107
  result.push({
104
108
  name,
105
109
  kind: 2,
@@ -142,7 +146,6 @@ function create() {
142
146
  ...formatSettings,
143
147
  unformatted: '',
144
148
  contentUnformatted: blockTypes.join(','),
145
- extraLiners: blockTypes.join(','),
146
149
  endWithNewline: options.insertFinalNewline ? true
147
150
  : options.trimFinalNewlines ? false
148
151
  : document.getText().endsWith('\n'),
@@ -1,3 +1,3 @@
1
- import type { ServiceEnvironment } from '@volar/language-service';
1
+ import type { ServiceContext, ServiceEnvironment } from '@volar/language-service';
2
2
  import { ServicePlugin, VueCompilerOptions } from '../types';
3
- export declare function create(mode: 'html' | 'pug', ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions, tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): ServicePlugin;
3
+ export declare function create(mode: 'html' | 'pug', ts: typeof import('typescript'), getVueOptions: (env: ServiceEnvironment) => VueCompilerOptions, getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): ServicePlugin;
@@ -10,9 +10,10 @@ const nameCasing_1 = require("../ideFeatures/nameCasing");
10
10
  const types_1 = require("../types");
11
11
  const data_1 = require("./data");
12
12
  const vscode_uri_1 = require("vscode-uri");
13
+ const common_1 = require("@vue/typescript-plugin/lib/common");
13
14
  let builtInData;
14
15
  let modelData;
15
- function create(mode, ts, getVueOptions, tsPluginClient) {
16
+ function create(mode, ts, getVueOptions, getTsPluginClient) {
16
17
  let customData = [];
17
18
  let extraCustomData = [];
18
19
  const onDidChangeCustomDataListeners = new Set();
@@ -41,6 +42,7 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
41
42
  '@', // vue event shorthand
42
43
  ],
43
44
  create(context) {
45
+ const tsPluginClient = getTsPluginClient?.(context);
44
46
  const baseServiceInstance = baseService.create(context);
45
47
  const vueCompilerOptions = getVueOptions(context.env);
46
48
  builtInData ??= (0, data_1.loadTemplateData)(context.env.locale ?? 'en');
@@ -82,8 +84,9 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
82
84
  disposable?.dispose();
83
85
  },
84
86
  async provideCompletionItems(document, position, completionContext, token) {
85
- if (!isSupportedDocument(document))
87
+ if (!isSupportedDocument(document)) {
86
88
  return;
89
+ }
87
90
  let sync;
88
91
  let currentVersion;
89
92
  const [_, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
@@ -95,23 +98,27 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
95
98
  while (currentVersion !== (currentVersion = await sync?.())) {
96
99
  htmlComplete = await baseServiceInstance.provideCompletionItems?.(document, position, completionContext, token);
97
100
  }
98
- if (!htmlComplete)
101
+ if (!htmlComplete) {
99
102
  return;
103
+ }
100
104
  if (sourceFile?.generated?.code instanceof language_core_1.VueGeneratedCode) {
101
105
  await afterHtmlCompletion(htmlComplete, context.documents.get(sourceFile.id, sourceFile.languageId, sourceFile.snapshot), sourceFile.generated.code);
102
106
  }
103
107
  return htmlComplete;
104
108
  },
105
109
  async provideInlayHints(document) {
106
- if (!isSupportedDocument(document))
110
+ if (!isSupportedDocument(document)) {
107
111
  return;
112
+ }
108
113
  const enabled = await context.env.getConfiguration?.('vue.inlayHints.missingProps') ?? false;
109
- if (!enabled)
114
+ if (!enabled) {
110
115
  return;
116
+ }
111
117
  const result = [];
112
118
  const [virtualCode] = context.documents.getVirtualCodeByUri(document.uri);
113
- if (!virtualCode)
119
+ if (!virtualCode) {
114
120
  return;
121
+ }
115
122
  for (const map of context.documents.getMaps(virtualCode)) {
116
123
  const code = context.language.files.get(map.sourceDocument.uri)?.generated?.code;
117
124
  const scanner = getScanner(baseServiceInstance, document);
@@ -203,23 +210,28 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
203
210
  return result;
204
211
  },
205
212
  provideHover(document, position, token) {
206
- if (!isSupportedDocument(document))
213
+ if (!isSupportedDocument(document)) {
207
214
  return;
208
- if (context.documents.getVirtualCodeByUri(document.uri)[0])
215
+ }
216
+ if (context.documents.getVirtualCodeByUri(document.uri)[0]) {
209
217
  updateExtraCustomData([]);
218
+ }
210
219
  return baseServiceInstance.provideHover?.(document, position, token);
211
220
  },
212
221
  async provideDiagnostics(document, token) {
213
- if (!isSupportedDocument(document))
222
+ if (!isSupportedDocument(document)) {
214
223
  return;
224
+ }
215
225
  const originalResult = await baseServiceInstance.provideDiagnostics?.(document, token);
216
226
  const [virtualCode] = context.documents.getVirtualCodeByUri(document.uri);
217
- if (!virtualCode)
227
+ if (!virtualCode) {
218
228
  return;
229
+ }
219
230
  for (const map of context.documents.getMaps(virtualCode)) {
220
231
  const code = context.language.files.get(map.sourceDocument.uri)?.generated?.code;
221
- if (!(code instanceof language_core_1.VueGeneratedCode))
232
+ if (!(code instanceof language_core_1.VueGeneratedCode)) {
222
233
  continue;
234
+ }
223
235
  const templateErrors = [];
224
236
  const { template } = code.sfc;
225
237
  if (template) {
@@ -253,18 +265,53 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
253
265
  ];
254
266
  }
255
267
  },
268
+ provideDocumentSemanticTokens(document, range, legend) {
269
+ if (!isSupportedDocument(document)) {
270
+ return;
271
+ }
272
+ const [_virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
273
+ if (!sourceFile
274
+ || !(sourceFile.generated?.code instanceof language_core_1.VueGeneratedCode)
275
+ || !sourceFile.generated.code.sfc.template) {
276
+ return [];
277
+ }
278
+ const { template } = sourceFile.generated.code.sfc;
279
+ const spans = common_1.getComponentSpans.call({
280
+ files: context.language.files,
281
+ languageService: context.inject('typescript/languageService'),
282
+ typescript: ts,
283
+ vueOptions: getVueOptions(context.env),
284
+ }, sourceFile.generated.code, template, {
285
+ start: document.offsetAt(range.start),
286
+ length: document.offsetAt(range.end) - document.offsetAt(range.start),
287
+ });
288
+ const classTokenIndex = legend.tokenTypes.indexOf('class');
289
+ return spans.map(span => {
290
+ const start = document.positionAt(span.start);
291
+ return [
292
+ start.line,
293
+ start.character,
294
+ span.length,
295
+ classTokenIndex,
296
+ 0,
297
+ ];
298
+ });
299
+ },
256
300
  };
257
301
  async function provideHtmlData(sourceDocumentUri, vueCode) {
258
302
  await (initializing ??= initialize());
259
303
  const casing = await (0, nameCasing_1.getNameCasing)(context, sourceDocumentUri, tsPluginClient);
260
304
  if (builtInData.tags) {
261
305
  for (const tag of builtInData.tags) {
262
- if (tag.name === 'slot')
306
+ if (tag.name === 'slot') {
263
307
  continue;
264
- if (tag.name === 'component')
308
+ }
309
+ if (tag.name === 'component') {
265
310
  continue;
266
- if (tag.name === 'template')
311
+ }
312
+ if (tag.name === 'template') {
267
313
  continue;
314
+ }
268
315
  if (casing.tag === types_1.TagNameCasing.Kebab) {
269
316
  tag.name = (0, language_core_1.hyphenateTag)(tag.name);
270
317
  }
@@ -324,10 +371,8 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
324
371
  }
325
372
  return tags;
326
373
  },
327
- provideAttributes: (tag) => {
328
- tsPluginClient?.getTemplateContextProps;
329
- let failed = false;
330
- let tagInfo = tagInfos.get(tag);
374
+ provideAttributes: tag => {
375
+ const tagInfo = tagInfos.get(tag);
331
376
  if (!tagInfo) {
332
377
  promises.push((async () => {
333
378
  const attrs = await tsPluginClient?.getElementAttrs(vueCode.fileName, tag) ?? [];
@@ -342,9 +387,6 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
342
387
  })());
343
388
  return [];
344
389
  }
345
- if (failed) {
346
- return [];
347
- }
348
390
  const { attrs, props, events } = tagInfo;
349
391
  const attributes = [];
350
392
  const _tsCodegen = language_core_1.tsCodegen.get(vueCode.sfc);
@@ -467,8 +509,9 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
467
509
  const textWithoutModifier = replacement.text.split('.')[0];
468
510
  if (validModifiers && hasModifier) {
469
511
  for (const modifier in validModifiers) {
470
- if (modifiers.includes(modifier))
512
+ if (modifiers.includes(modifier)) {
471
513
  continue;
514
+ }
472
515
  const modifierDes = validModifiers[modifier];
473
516
  const insertText = textWithoutModifier + modifiers.slice(0, -1).map(m => '.' + m).join('') + '.' + modifier;
474
517
  const newItem = {
@@ -489,8 +532,9 @@ function create(mode, ts, getVueOptions, tsPluginClient) {
489
532
  }
490
533
  else if (hasModifier && isModel) {
491
534
  for (const modifier of modelData.globalAttributes ?? []) {
492
- if (modifiers.includes(modifier.name))
535
+ if (modifiers.includes(modifier.name)) {
493
536
  continue;
537
+ }
494
538
  const insertText = textWithoutModifier + modifiers.slice(0, -1).map(m => '.' + m).join('') + '.' + modifier.name;
495
539
  const newItem = {
496
540
  label: modifier.name,
@@ -15,8 +15,9 @@ function create(ts) {
15
15
  return;
16
16
  }
17
17
  const { template } = virtualCode.sfc;
18
- if (!template?.ast)
18
+ if (!template?.ast) {
19
19
  return;
20
+ }
20
21
  const templateStartOffset = template.startTagEnd;
21
22
  const result = [];
22
23
  for (const node of (0, language_core_1.eachElementNode)(template.ast)) {
@@ -1,2 +1,2 @@
1
- import type { ServicePlugin } from '@volar/language-service';
2
- export declare function create(ts: typeof import('typescript'), tsPluginClient?: typeof import('@vue/typescript-plugin/lib/client')): ServicePlugin;
1
+ import type { ServiceContext, ServicePlugin } from '@volar/language-service';
2
+ export declare function create(ts: typeof import('typescript'), getTsPluginClient?: (context: ServiceContext) => typeof import('@vue/typescript-plugin/lib/client') | undefined): ServicePlugin;
@@ -3,15 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = void 0;
4
4
  const vue = require("@vue/language-core");
5
5
  const twoslashReg = /<!--\s*\^\?\s*-->/g;
6
- function create(ts, tsPluginClient) {
6
+ function create(ts, getTsPluginClient) {
7
7
  return {
8
8
  name: 'vue-twoslash-queries',
9
9
  create(context) {
10
+ const tsPluginClient = getTsPluginClient?.(context);
10
11
  return {
11
12
  async provideInlayHints(document, range) {
12
13
  const [virtualCode, sourceFile] = context.documents.getVirtualCodeByUri(document.uri);
13
- if (!(sourceFile?.generated?.code instanceof vue.VueGeneratedCode) || virtualCode?.id !== 'template')
14
+ if (!(sourceFile?.generated?.code instanceof vue.VueGeneratedCode) || virtualCode?.id !== 'template') {
14
15
  return;
16
+ }
15
17
  const hoverOffsets = [];
16
18
  const inlayHints = [];
17
19
  for (const pointer of document.getText(range).matchAll(twoslashReg)) {
@@ -19,8 +19,9 @@ function create() {
19
19
  && mapping.generatedOffsets[mapping.generatedOffsets.length - 1] + mapping.lengths[mapping.lengths.length - 1] <= end
20
20
  && hint) {
21
21
  settings[hint.setting] ??= await context.env.getConfiguration?.(hint.setting) ?? false;
22
- if (!settings[hint.setting])
22
+ if (!settings[hint.setting]) {
23
23
  continue;
24
+ }
24
25
  result.push({
25
26
  label: hint.label,
26
27
  paddingRight: hint.paddingRight,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/language-service",
3
- "version": "2.0.5",
3
+ "version": "2.0.7",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "data",
@@ -16,32 +16,32 @@
16
16
  "update-html-data": "node ./scripts/update-html-data.js"
17
17
  },
18
18
  "dependencies": {
19
- "@volar/language-core": "~2.1.1",
20
- "@volar/language-service": "~2.1.1",
21
- "@volar/typescript": "~2.1.1",
19
+ "@volar/language-core": "~2.1.3",
20
+ "@volar/language-service": "~2.1.3",
21
+ "@volar/typescript": "~2.1.3",
22
22
  "@vue/compiler-dom": "^3.4.0",
23
- "@vue/language-core": "2.0.5",
23
+ "@vue/language-core": "2.0.7",
24
24
  "@vue/shared": "^3.4.0",
25
+ "@vue/typescript-plugin": "2.0.7",
25
26
  "computeds": "^0.0.1",
26
27
  "path-browserify": "^1.0.1",
27
- "volar-service-css": "0.0.31",
28
- "volar-service-emmet": "0.0.31",
29
- "volar-service-html": "0.0.31",
30
- "volar-service-json": "0.0.31",
31
- "volar-service-pug": "0.0.31",
32
- "volar-service-pug-beautify": "0.0.31",
33
- "volar-service-typescript": "0.0.31",
34
- "volar-service-typescript-twoslash-queries": "0.0.31",
28
+ "volar-service-css": "0.0.34",
29
+ "volar-service-emmet": "0.0.34",
30
+ "volar-service-html": "0.0.34",
31
+ "volar-service-json": "0.0.34",
32
+ "volar-service-pug": "0.0.34",
33
+ "volar-service-pug-beautify": "0.0.34",
34
+ "volar-service-typescript": "0.0.34",
35
+ "volar-service-typescript-twoslash-queries": "0.0.34",
35
36
  "vscode-html-languageservice": "^5.1.0",
36
- "vscode-languageserver-textdocument": "^1.0.11"
37
+ "vscode-languageserver-textdocument": "^1.0.11",
38
+ "vscode-uri": "^3.0.8"
37
39
  },
38
40
  "devDependencies": {
39
41
  "@types/node": "latest",
40
42
  "@types/path-browserify": "latest",
41
- "@volar/kit": "~2.1.1",
42
- "@vue/typescript-plugin": "2.0.5",
43
- "vscode-languageserver-protocol": "^3.17.5",
44
- "vscode-uri": "^3.0.8"
43
+ "@volar/kit": "~2.1.3",
44
+ "vscode-languageserver-protocol": "^3.17.5"
45
45
  },
46
- "gitHead": "62b4fcb0d3f7153b5b2f5571af32f519117d8466"
46
+ "gitHead": "4a37e8f3ebcf31ecfd2ea627f7611d5990ec5df6"
47
47
  }