@vue/language-service 2.2.2 → 2.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,7 +17,7 @@ async function convertTagName(context, uri, casing, tsPluginClient) {
17
17
  if (!(root instanceof language_core_1.VueVirtualCode)) {
18
18
  return;
19
19
  }
20
- const { template } = root._sfc;
20
+ const { template } = root.sfc;
21
21
  if (!template) {
22
22
  return;
23
23
  }
@@ -52,7 +52,7 @@ async function convertAttrName(context, uri, casing, tsPluginClient) {
52
52
  if (!(root instanceof language_core_1.VueVirtualCode)) {
53
53
  return;
54
54
  }
55
- const { template } = root._sfc;
55
+ const { template } = root.sfc;
56
56
  if (!template) {
57
57
  return;
58
58
  }
@@ -132,8 +132,8 @@ async function detect(context, uri) {
132
132
  }
133
133
  function getTagNameCase(file) {
134
134
  const result = new Set();
135
- if (file._sfc.template?.ast) {
136
- for (const element of vue.forEachElementNode(file._sfc.template.ast)) {
135
+ if (file.sfc.template?.ast) {
136
+ for (const element of vue.forEachElementNode(file.sfc.template.ast)) {
137
137
  if (element.tagType === 1) {
138
138
  if (element.tag !== (0, language_core_1.hyphenateTag)(element.tag)) {
139
139
  // TagName
@@ -157,7 +157,7 @@ function getTemplateTagsAndAttrs(sourceFile) {
157
157
  if (!(sourceFile instanceof vue.VueVirtualCode)) {
158
158
  return;
159
159
  }
160
- const ast = sourceFile._sfc.template?.ast;
160
+ const ast = sourceFile.sfc.template?.ast;
161
161
  const tags = new Map();
162
162
  if (ast) {
163
163
  for (const node of vue.forEachElementNode(ast)) {
@@ -1,13 +1,16 @@
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");
4
5
  const volar_service_css_1 = require("volar-service-css");
6
+ const vscode_uri_1 = require("vscode-uri");
5
7
  function create() {
6
8
  const base = (0, volar_service_css_1.create)({ scssDocumentSelector: ['scss', 'postcss'] });
7
9
  return {
8
10
  ...base,
9
11
  create(context) {
10
12
  const baseInstance = base.create(context);
13
+ const { 'css/languageService': getCssLs, 'css/stylesheet': getStylesheet, } = baseInstance.provide;
11
14
  return {
12
15
  ...baseInstance,
13
16
  async provideDiagnostics(document, token) {
@@ -19,7 +22,63 @@ function create() {
19
22
  }
20
23
  return diagnostics;
21
24
  },
25
+ /**
26
+ * If the editing position is within the virtual code and navigation is enabled,
27
+ * skip the CSS renaming feature.
28
+ */
29
+ provideRenameRange(document, position) {
30
+ do {
31
+ const uri = vscode_uri_1.URI.parse(document.uri);
32
+ const decoded = context.decodeEmbeddedDocumentUri(uri);
33
+ const sourceScript = decoded && context.language.scripts.get(decoded[0]);
34
+ const virtualCode = decoded && sourceScript?.generated?.embeddedCodes.get(decoded[1]);
35
+ if (!sourceScript?.generated || !virtualCode?.id.startsWith('style_')) {
36
+ break;
37
+ }
38
+ const root = sourceScript.generated.root;
39
+ if (!(root instanceof language_core_1.VueVirtualCode)) {
40
+ break;
41
+ }
42
+ const block = root.sfc.styles.find(style => style.name === decoded[1]);
43
+ if (!block) {
44
+ break;
45
+ }
46
+ let script;
47
+ for (const [key, value] of sourceScript.generated.embeddedCodes) {
48
+ if (key.startsWith('script_')) {
49
+ script = value;
50
+ break;
51
+ }
52
+ }
53
+ if (!script) {
54
+ break;
55
+ }
56
+ const offset = document.offsetAt(position) + block.startTagEnd;
57
+ for (const { sourceOffsets, lengths, data } of script.mappings) {
58
+ if (!sourceOffsets.length
59
+ || !data.navigation
60
+ || typeof data.navigation === 'object' && !data.navigation.shouldRename) {
61
+ continue;
62
+ }
63
+ const start = sourceOffsets[0];
64
+ const end = sourceOffsets.at(-1) + lengths.at(-1);
65
+ if (offset >= start && offset <= end) {
66
+ return;
67
+ }
68
+ }
69
+ } while (0);
70
+ return worker(document, (stylesheet, cssLs) => {
71
+ return cssLs.prepareRename(document, position, stylesheet);
72
+ });
73
+ }
22
74
  };
75
+ function worker(document, callback) {
76
+ const cssLs = getCssLs(document);
77
+ if (!cssLs) {
78
+ return;
79
+ }
80
+ return callback(getStylesheet(document, cssLs), cssLs);
81
+ }
23
82
  },
24
83
  };
25
84
  }
@@ -49,10 +49,8 @@ function create(ts, getTsPluginClient) {
49
49
  if (!(root instanceof language_core_1.VueVirtualCode)) {
50
50
  return;
51
51
  }
52
- const blocks = [
53
- root._sfc.script,
54
- root._sfc.scriptSetup,
55
- ].filter(block => !!block);
52
+ const { sfc } = root;
53
+ const blocks = [sfc.script, sfc.scriptSetup].filter(block => !!block);
56
54
  if (!blocks.length) {
57
55
  return;
58
56
  }
@@ -0,0 +1,2 @@
1
+ import type { LanguageServicePlugin } from '@volar/language-service';
2
+ export declare function create(): LanguageServicePlugin;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.create = create;
4
+ function create() {
5
+ return {
6
+ name: 'vue-autoinsert-selfClosing',
7
+ capabilities: {
8
+ autoInsertionProvider: {
9
+ triggerCharacters: ['/'],
10
+ configurationSections: ['vue.autoInsert.selfClosing'],
11
+ },
12
+ },
13
+ create(context) {
14
+ return {
15
+ async provideAutoInsertSnippet(document, selection, change) {
16
+ if (document.languageId !== 'html') {
17
+ return;
18
+ }
19
+ const enabled = await context.env.getConfiguration?.('vue.autoInsert.selfClosing') ?? true;
20
+ if (!enabled) {
21
+ return;
22
+ }
23
+ if (change.text === '{}'
24
+ && document.getText().slice(change.rangeOffset - 1, change.rangeOffset + 3) === '{{}}'
25
+ && document.offsetAt(selection) === change.rangeOffset + 1) {
26
+ return ` $0 `;
27
+ }
28
+ },
29
+ };
30
+ },
31
+ };
32
+ }
33
+ //# sourceMappingURL=vue-autoinsert-self-closing.js.map
@@ -32,8 +32,9 @@ function create() {
32
32
  if (!(root instanceof language_core_1.VueVirtualCode)) {
33
33
  return;
34
34
  }
35
- const codegen = language_core_1.tsCodegen.get(root._sfc);
36
- const scriptSetup = root._sfc.scriptSetup;
35
+ const { sfc } = root;
36
+ const codegen = language_core_1.tsCodegen.get(sfc);
37
+ const scriptSetup = sfc.scriptSetup;
37
38
  const scriptSetupRanges = codegen?.getScriptSetupRanges();
38
39
  if (!scriptSetup || !scriptSetupRanges) {
39
40
  return;
@@ -1,2 +1,6 @@
1
1
  import type { LanguageServicePlugin } from '@volar/language-service';
2
+ /**
3
+ * A language service plugin that provides completion for Vue directive comments,
4
+ * e.g. if user is writing `<!-- |` in they'll be provided completions for `@vue-expect-error`, `@vue-generic`, etc.
5
+ */
2
6
  export declare function create(): LanguageServicePlugin;
@@ -8,6 +8,10 @@ const cmds = [
8
8
  ['vue-generic', 'vue-generic {$1}'],
9
9
  ];
10
10
  const directiveCommentReg = /<!--\s*@/;
11
+ /**
12
+ * A language service plugin that provides completion for Vue directive comments,
13
+ * e.g. if user is writing `<!-- |` in they'll be provided completions for `@vue-expect-error`, `@vue-generic`, etc.
14
+ */
11
15
  function create() {
12
16
  return {
13
17
  name: 'vue-directive-comments',
@@ -45,14 +45,14 @@ function create(ts, getTsPluginClient) {
45
45
  if (!importUri || !vueCompilerOptions.extensions.some(ext => importUri.endsWith(ext))) {
46
46
  return;
47
47
  }
48
- let baseName = importUri.slice(importUri.lastIndexOf('/') + 1);
49
- baseName = baseName.slice(0, baseName.lastIndexOf('.'));
50
- const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName));
51
- const sfc = root._sfc;
48
+ const { sfc } = root;
52
49
  const script = sfc.scriptSetup ?? sfc.script;
53
50
  if (!script) {
54
51
  return;
55
52
  }
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));
56
56
  const additionalEdit = {};
57
57
  const code = [...(0, language_core_1.forEachEmbeddedCode)(root)].find(code => code.id === (sfc.scriptSetup ? 'scriptsetup_raw' : 'script_raw'));
58
58
  const lastImportNode = (0, vue_extract_file_1.getLastImportNode)(ts, script.ast);
@@ -24,12 +24,13 @@ function create() {
24
24
  return;
25
25
  }
26
26
  const result = [];
27
- const codegen = language_core_1.tsCodegen.get(root._sfc);
27
+ const { sfc } = root;
28
+ const codegen = language_core_1.tsCodegen.get(sfc);
28
29
  const scopedClasses = codegen?.getGeneratedTemplate()?.scopedClasses ?? [];
29
30
  const styleClasses = new Map();
30
31
  const option = root.vueCompilerOptions.experimentalResolveStyleCssClasses;
31
- for (let i = 0; i < root._sfc.styles.length; i++) {
32
- const style = root._sfc.styles[i];
32
+ for (let i = 0; i < sfc.styles.length; i++) {
33
+ const style = sfc.styles[i];
33
34
  if (option === 'always' || (option === 'scoped' && style.scoped)) {
34
35
  for (const className of style.classNames) {
35
36
  if (!styleClasses.has(className.text.slice(1))) {
@@ -38,7 +38,7 @@ function create(ts, getTsPluginClient) {
38
38
  if (!(root instanceof language_core_1.VueVirtualCode)) {
39
39
  return;
40
40
  }
41
- const sfc = root._sfc;
41
+ const { sfc } = root;
42
42
  const script = sfc.scriptSetup ?? sfc.script;
43
43
  if (!sfc.template || !script) {
44
44
  return;
@@ -73,7 +73,7 @@ function create(ts, getTsPluginClient) {
73
73
  if (!(root instanceof language_core_1.VueVirtualCode)) {
74
74
  return codeAction;
75
75
  }
76
- const sfc = root._sfc;
76
+ const { sfc } = root;
77
77
  const script = sfc.scriptSetup ?? sfc.script;
78
78
  if (!sfc.template || !script) {
79
79
  return codeAction;
@@ -26,17 +26,17 @@ function create(ts) {
26
26
  return settings[key] ??= await context.env.getConfiguration?.(key) ?? false;
27
27
  }
28
28
  const result = [];
29
- const codegen = language_core_1.tsCodegen.get(virtualCode._sfc);
29
+ const codegen = language_core_1.tsCodegen.get(virtualCode.sfc);
30
30
  const inlayHints = [
31
31
  ...codegen?.getGeneratedTemplate()?.inlayHints ?? [],
32
32
  ...codegen?.getGeneratedScript()?.inlayHints ?? [],
33
33
  ];
34
34
  const scriptSetupRanges = codegen?.getScriptSetupRanges();
35
- if (scriptSetupRanges?.defineProps?.destructured && virtualCode._sfc.scriptSetup?.ast) {
35
+ if (scriptSetupRanges?.defineProps?.destructured && virtualCode.sfc.scriptSetup?.ast) {
36
36
  const setting = 'vue.inlayHints.destructuredProps';
37
37
  const enabled = await getSettingEnabled(setting);
38
38
  if (enabled) {
39
- for (const [prop, isShorthand] of findDestructuredProps(ts, virtualCode._sfc.scriptSetup.ast, scriptSetupRanges.defineProps.destructured.keys())) {
39
+ for (const [prop, isShorthand] of findDestructuredProps(ts, virtualCode.sfc.scriptSetup.ast, scriptSetupRanges.defineProps.destructured.keys())) {
40
40
  const name = prop.text;
41
41
  const end = prop.getEnd();
42
42
  const pos = isShorthand ? end : end - name.length;
@@ -51,9 +51,9 @@ function create(ts) {
51
51
  }
52
52
  }
53
53
  const blocks = [
54
- virtualCode._sfc.template,
55
- virtualCode._sfc.script,
56
- virtualCode._sfc.scriptSetup,
54
+ virtualCode.sfc.template,
55
+ virtualCode.sfc.script,
56
+ virtualCode.sfc.scriptSetup,
57
57
  ];
58
58
  const start = document.offsetAt(range.start);
59
59
  const end = document.offsetAt(range.end);
@@ -8,7 +8,7 @@ const vscode_uri_1 = require("vscode-uri");
8
8
  const data_1 = require("./data");
9
9
  let sfcDataProvider;
10
10
  function create() {
11
- const htmlPlugin = (0, volar_service_html_1.create)({
11
+ const htmlService = (0, volar_service_html_1.create)({
12
12
  documentSelector: ['vue-root-tags'],
13
13
  useDefaultDataProvider: false,
14
14
  getCustomData(context) {
@@ -19,7 +19,7 @@ function create() {
19
19
  return await worker(document, context, async (root) => {
20
20
  const formatSettings = await context.env.getConfiguration?.('html.format') ?? {};
21
21
  const blockTypes = ['template', 'script', 'style'];
22
- for (const customBlock of root._sfc.customBlocks) {
22
+ for (const customBlock of root.sfc.customBlocks) {
23
23
  blockTypes.push(customBlock.type);
24
24
  }
25
25
  return {
@@ -36,12 +36,19 @@ function create() {
36
36
  },
37
37
  });
38
38
  return {
39
- ...htmlPlugin,
39
+ ...htmlService,
40
40
  name: 'vue-sfc',
41
+ capabilities: {
42
+ ...htmlService.capabilities,
43
+ diagnosticProvider: {
44
+ interFileDependencies: false,
45
+ workspaceDiagnostics: false,
46
+ }
47
+ },
41
48
  create(context) {
42
- const htmlPluginInstance = htmlPlugin.create(context);
49
+ const htmlServiceInstance = htmlService.create(context);
43
50
  return {
44
- ...htmlPluginInstance,
51
+ ...htmlServiceInstance,
45
52
  provideDocumentLinks: undefined,
46
53
  async resolveEmbeddedCodeFormattingOptions(sourceScript, virtualCode, options) {
47
54
  if (sourceScript.generated?.root instanceof language_core_1.VueVirtualCode) {
@@ -63,10 +70,44 @@ function create() {
63
70
  }
64
71
  return options;
65
72
  },
73
+ provideDiagnostics(document, token) {
74
+ return worker(document, context, async (root) => {
75
+ const { vueSfc, sfc } = root;
76
+ if (!vueSfc) {
77
+ return;
78
+ }
79
+ const originalResult = await htmlServiceInstance.provideDiagnostics?.(document, token);
80
+ const sfcErrors = [];
81
+ const { template } = sfc;
82
+ const { startTagEnd = Infinity, endTagStart = -Infinity } = template ?? {};
83
+ for (const error of vueSfc.errors) {
84
+ if ('code' in error) {
85
+ const start = error.loc?.start.offset ?? 0;
86
+ const end = error.loc?.end.offset ?? 0;
87
+ if (end < startTagEnd || start >= endTagStart) {
88
+ sfcErrors.push({
89
+ range: {
90
+ start: document.positionAt(start),
91
+ end: document.positionAt(end),
92
+ },
93
+ severity: 1,
94
+ code: error.code,
95
+ source: 'vue',
96
+ message: error.message,
97
+ });
98
+ }
99
+ }
100
+ }
101
+ return [
102
+ ...originalResult ?? [],
103
+ ...sfcErrors
104
+ ];
105
+ });
106
+ },
66
107
  provideDocumentSymbols(document) {
67
108
  return worker(document, context, root => {
68
109
  const result = [];
69
- const sfc = root._sfc;
110
+ const { sfc } = root;
70
111
  if (sfc.template) {
71
112
  result.push({
72
113
  name: 'template',
@@ -148,7 +189,7 @@ function create() {
148
189
  });
149
190
  },
150
191
  async provideCompletionItems(document, position, context, token) {
151
- const result = await htmlPluginInstance.provideCompletionItems?.(document, position, context, token);
192
+ const result = await htmlServiceInstance.provideCompletionItems?.(document, position, context, token);
152
193
  if (!result) {
153
194
  return;
154
195
  }
@@ -0,0 +1,6 @@
1
+ import type { LanguageServiceContext, LanguageServicePluginInstance } from '@volar/language-service';
2
+ import * as html from 'vscode-html-languageservice';
3
+ import type { TextDocument } from 'vscode-languageserver-textdocument';
4
+ export declare function provideAutoInsertSelfClosingTags(context: LanguageServiceContext, service: LanguageServicePluginInstance, document: TextDocument, position: html.Position, change: {
5
+ text: string;
6
+ }): Promise<">" | undefined>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.provideAutoInsertSelfClosingTags = provideAutoInsertSelfClosingTags;
4
+ const html = require("vscode-html-languageservice");
5
+ const vue_template_1 = require("../vue-template");
6
+ async function provideAutoInsertSelfClosingTags(context, service, document, position, change) {
7
+ if (document.languageId !== 'html') {
8
+ return;
9
+ }
10
+ const enabled = await context.env.getConfiguration?.('vue.autoInsert.selfClosing') ?? true;
11
+ if (!enabled) {
12
+ return;
13
+ }
14
+ if (change.text !== '/') {
15
+ return;
16
+ }
17
+ const scanner = (0, vue_template_1.getScanner)(service, document, 'html');
18
+ if (!scanner) {
19
+ return;
20
+ }
21
+ const offset = document.offsetAt(position);
22
+ let token;
23
+ let inStartTag = false;
24
+ while ((token = scanner.scan()) !== html.TokenType.EOS) {
25
+ if (token === html.TokenType.StartTagOpen) {
26
+ inStartTag = true;
27
+ }
28
+ else if (token === html.TokenType.StartTagClose || token === html.TokenType.StartTagSelfClose) {
29
+ inStartTag = false;
30
+ }
31
+ else if (scanner.getTokenOffset() + 1 === offset) {
32
+ if (token === html.TokenType.Unknown) {
33
+ return '>';
34
+ }
35
+ return;
36
+ }
37
+ }
38
+ }
39
+ //# sourceMappingURL=autoinsert-self-closing-tags.js.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=autoinsert-selfClosingTags.js.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=autoinsert-selfclosing-tags.js.map
@@ -301,7 +301,7 @@ function create(mode, ts, getTsPluginClient) {
301
301
  }
302
302
  const originalResult = await baseServiceInstance.provideDiagnostics?.(document, token);
303
303
  const templateErrors = [];
304
- const { template } = root._sfc;
304
+ const { template } = root.sfc;
305
305
  if (template) {
306
306
  for (const error of template.errors) {
307
307
  onCompilerError(error, 1);
@@ -351,7 +351,7 @@ function create(mode, ts, getTsPluginClient) {
351
351
  if (!(root instanceof language_core_1.VueVirtualCode)) {
352
352
  return;
353
353
  }
354
- const { template } = root._sfc;
354
+ const { template } = root.sfc;
355
355
  if (!template) {
356
356
  return;
357
357
  }
@@ -420,7 +420,7 @@ function create(mode, ts, getTsPluginClient) {
420
420
  })());
421
421
  return [];
422
422
  }
423
- const scriptSetupRanges = language_core_1.tsCodegen.get(vueCode._sfc)?.getScriptSetupRanges();
423
+ const scriptSetupRanges = language_core_1.tsCodegen.get(vueCode.sfc)?.getScriptSetupRanges();
424
424
  const names = new Set();
425
425
  const tags = [];
426
426
  for (const tag of components) {
@@ -432,7 +432,7 @@ function create(mode, ts, getTsPluginClient) {
432
432
  }
433
433
  }
434
434
  for (const binding of scriptSetupRanges?.bindings ?? []) {
435
- const name = vueCode._sfc.scriptSetup.content.slice(binding.range.start, binding.range.end);
435
+ const name = vueCode.sfc.scriptSetup.content.slice(binding.range.start, binding.range.end);
436
436
  if (casing.tag === types_1.TagNameCasing.Kebab) {
437
437
  names.add((0, language_core_1.hyphenateTag)(name));
438
438
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/language-service",
3
- "version": "2.2.2",
3
+ "version": "2.2.6",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "data",
@@ -21,9 +21,9 @@
21
21
  "@volar/language-service": "~2.4.11",
22
22
  "@volar/typescript": "~2.4.11",
23
23
  "@vue/compiler-dom": "^3.5.0",
24
- "@vue/language-core": "2.2.2",
24
+ "@vue/language-core": "2.2.6",
25
25
  "@vue/shared": "^3.5.0",
26
- "@vue/typescript-plugin": "2.2.2",
26
+ "@vue/typescript-plugin": "2.2.6",
27
27
  "alien-signals": "^1.0.3",
28
28
  "path-browserify": "^1.0.1",
29
29
  "volar-service-css": "0.0.62",
@@ -34,6 +34,7 @@
34
34
  "volar-service-pug-beautify": "0.0.62",
35
35
  "volar-service-typescript": "0.0.62",
36
36
  "volar-service-typescript-twoslash-queries": "0.0.62",
37
+ "vscode-css-languageservice": "^6.3.1",
37
38
  "vscode-html-languageservice": "^5.2.0",
38
39
  "vscode-languageserver-textdocument": "^1.0.11",
39
40
  "vscode-uri": "^3.0.8"
@@ -44,5 +45,5 @@
44
45
  "@volar/kit": "~2.4.11",
45
46
  "vscode-languageserver-protocol": "^3.17.5"
46
47
  },
47
- "gitHead": "30757908b67f40f779c36795665163634fb81868"
48
+ "gitHead": "f2088e256dc0220db9549d28d9f865a5711dcfbe"
48
49
  }