@vue/language-service 3.0.7-alpha.1 → 3.0.8

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
@@ -1,3 +1,4 @@
1
1
  export * from '@volar/language-service';
2
2
  export * from '@volar/language-service/lib/utils/featureWorkers';
3
- export declare function createVueLanguageServicePlugins(ts: typeof import('typescript'), tsPluginClient?: import('@vue/typescript-plugin/lib/requests').Requests): import("@volar/language-service").LanguageServicePlugin<any>[];
3
+ import type { Requests } from '@vue/typescript-plugin/lib/requests';
4
+ export declare function createVueLanguageServicePlugins(ts: typeof import('typescript'), client?: Requests): import("@volar/language-service").LanguageServicePlugin<any>[];
package/index.js CHANGED
@@ -43,12 +43,12 @@ const vue_suggest_define_assignment_1 = require("./lib/plugins/vue-suggest-defin
43
43
  const vue_template_1 = require("./lib/plugins/vue-template");
44
44
  const vue_template_ref_links_1 = require("./lib/plugins/vue-template-ref-links");
45
45
  const vue_twoslash_queries_1 = require("./lib/plugins/vue-twoslash-queries");
46
- function createVueLanguageServicePlugins(ts, tsPluginClient) {
47
- tsPluginClient ??= new Proxy({}, {
48
- get() {
49
- return () => undefined;
50
- },
51
- });
46
+ const noop = () => { };
47
+ function createVueLanguageServicePlugins(ts, client = new Proxy({}, {
48
+ get() {
49
+ return noop;
50
+ },
51
+ })) {
52
52
  return [
53
53
  (0, css_1.create)(),
54
54
  (0, volar_service_json_1.create)(),
@@ -72,16 +72,16 @@ function createVueLanguageServicePlugins(ts, tsPluginClient) {
72
72
  (0, syntactic_1.create)(ts),
73
73
  (0, vue_inlayhints_1.create)(ts),
74
74
  // type aware plugins
75
- (0, typescript_semantic_tokens_1.create)(tsPluginClient),
76
- (0, vue_autoinsert_dotvalue_1.create)(ts, tsPluginClient),
77
- (0, vue_component_semantic_tokens_1.create)(tsPluginClient),
78
- (0, vue_document_drop_1.create)(ts, tsPluginClient),
79
- (0, vue_document_highlights_1.create)(tsPluginClient),
80
- (0, vue_extract_file_1.create)(ts, tsPluginClient),
81
- (0, vue_missing_props_hints_1.create)(tsPluginClient),
82
- (0, vue_template_1.create)('html', tsPluginClient),
83
- (0, vue_template_1.create)('jade', tsPluginClient),
84
- (0, vue_twoslash_queries_1.create)(tsPluginClient),
75
+ (0, typescript_semantic_tokens_1.create)(client),
76
+ (0, vue_autoinsert_dotvalue_1.create)(ts, client),
77
+ (0, vue_component_semantic_tokens_1.create)(client),
78
+ (0, vue_document_drop_1.create)(ts, client),
79
+ (0, vue_document_highlights_1.create)(client),
80
+ (0, vue_extract_file_1.create)(ts, client),
81
+ (0, vue_missing_props_hints_1.create)(client),
82
+ (0, vue_template_1.create)('html', client),
83
+ (0, vue_template_1.create)('jade', client),
84
+ (0, vue_twoslash_queries_1.create)(client),
85
85
  ];
86
86
  }
87
87
  //# sourceMappingURL=index.js.map
@@ -9,6 +9,6 @@ export declare enum AttrNameCasing {
9
9
  Camel = 1
10
10
  }
11
11
  export declare function checkCasing(context: LanguageServiceContext, uri: URI): Promise<{
12
- tag: TagNameCasing;
13
- attr: AttrNameCasing;
12
+ tag: TagNameCasing | undefined;
13
+ attr: AttrNameCasing | undefined;
14
14
  }>;
@@ -44,17 +44,16 @@ function create() {
44
44
  },
45
45
  };
46
46
  function isWithinNavigationVirtualCode(document, position) {
47
- const info = (0, utils_1.getEmbeddedInfo)(context, document, id => id.startsWith('style_'));
48
- if (!info) {
47
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
48
+ if (!info?.code.id.startsWith('style_')) {
49
49
  return false;
50
50
  }
51
- const { sourceScript, virtualCode, root } = info;
52
- const block = root.sfc.styles.find(style => style.name === virtualCode.id);
51
+ const block = info.root.sfc.styles.find(style => style.name === info.code.id);
53
52
  if (!block) {
54
53
  return false;
55
54
  }
56
55
  let script;
57
- for (const [key, value] of sourceScript.generated.embeddedCodes) {
56
+ for (const [key, value] of info.script.generated.embeddedCodes) {
58
57
  if (key.startsWith('script_')) {
59
58
  script = value;
60
59
  break;
@@ -37,18 +37,17 @@ function create({ getEncodedSemanticClassifications }) {
37
37
  create(context) {
38
38
  return {
39
39
  async provideDocumentSemanticTokens(document, range, legend) {
40
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'main');
41
- if (!info) {
40
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
41
+ if (info?.script.id.scheme !== 'file' || info.code.id !== 'main') {
42
42
  return;
43
43
  }
44
- const { root } = info;
45
44
  const start = document.offsetAt(range.start);
46
45
  const end = document.offsetAt(range.end);
47
46
  const span = {
48
47
  start: start,
49
48
  length: end - start,
50
49
  };
51
- const classifications = await getEncodedSemanticClassifications(root.fileName, span);
50
+ const classifications = await getEncodedSemanticClassifications(info.root.fileName, span);
52
51
  if (classifications) {
53
52
  return (0, semanticTokens_1.convertClassificationsToSemanticTokens)(document, span, legend, classifications);
54
53
  }
@@ -1,2 +1,2 @@
1
1
  import type { LanguageServicePlugin } from '@volar/language-service';
2
- export declare function create(ts: typeof import('typescript'), { getPropertiesAtLocation }: import('@vue/typescript-plugin/lib/requests').Requests): LanguageServicePlugin;
2
+ export declare function create(ts: typeof import('typescript'), { isRefAtPosition }: import('@vue/typescript-plugin/lib/requests').Requests): LanguageServicePlugin;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.create = create;
4
4
  const language_core_1 = require("@vue/language-core");
5
5
  const utils_1 = require("../utils");
6
- function create(ts, { getPropertiesAtLocation }) {
6
+ function create(ts, { isRefAtPosition }) {
7
7
  return {
8
8
  name: 'vue-autoinsert-dotvalue',
9
9
  capabilities: {
@@ -15,8 +15,8 @@ function create(ts, { getPropertiesAtLocation }) {
15
15
  create(context) {
16
16
  return {
17
17
  async provideAutoInsertSnippet(document, selection, change) {
18
- const info = (0, utils_1.getEmbeddedInfo)(context, document, id => id.startsWith('script_'));
19
- if (!info) {
18
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
19
+ if (!info?.code.id.startsWith('script_')) {
20
20
  return;
21
21
  }
22
22
  // selection must at end of change
@@ -27,10 +27,9 @@ function create(ts, { getPropertiesAtLocation }) {
27
27
  return;
28
28
  }
29
29
  let sourceOffset;
30
- const { sourceScript, virtualCode, root } = info;
31
- const { sfc } = root;
30
+ const { sfc } = info.root;
32
31
  const scriptBlocks = [sfc.script, sfc.scriptSetup].filter(block => !!block);
33
- const map = context.language.maps.get(virtualCode, sourceScript);
32
+ const map = context.language.maps.get(info.code, info.script);
34
33
  if (!scriptBlocks.length) {
35
34
  return;
36
35
  }
@@ -49,8 +48,7 @@ function create(ts, { getPropertiesAtLocation }) {
49
48
  return;
50
49
  }
51
50
  }
52
- const props = await getPropertiesAtLocation(root.fileName, sourceOffset) ?? [];
53
- if (props.some(prop => prop === 'value')) {
51
+ if (await isRefAtPosition(info.root.fileName, sourceOffset)) {
54
52
  return '${1:.value}';
55
53
  }
56
54
  },
@@ -14,12 +14,11 @@ function create() {
14
14
  create(context) {
15
15
  return {
16
16
  provideDiagnostics(document) {
17
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template');
18
- if (!info) {
17
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
18
+ if (info?.code.id !== 'template') {
19
19
  return;
20
20
  }
21
- const { root } = info;
22
- const { template } = root.sfc;
21
+ const { template } = info.root.sfc;
23
22
  if (!template) {
24
23
  return;
25
24
  }
@@ -17,20 +17,19 @@ function create({ getComponentNames, getElementNames }) {
17
17
  create(context) {
18
18
  return {
19
19
  async provideDocumentSemanticTokens(document, range, legend) {
20
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template');
21
- if (!info) {
20
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
21
+ if (info?.code.id !== 'template') {
22
22
  return;
23
23
  }
24
- const { root } = info;
25
- const { template } = root.sfc;
24
+ const { template } = info.root.sfc;
26
25
  if (!template?.ast) {
27
26
  return;
28
27
  }
29
28
  const componentSpans = [];
30
29
  const start = document.offsetAt(range.start);
31
30
  const end = document.offsetAt(range.end);
32
- const validComponentNames = await getComponentNames(root.fileName) ?? [];
33
- const elements = new Set(await getElementNames(root.fileName) ?? []);
31
+ const validComponentNames = await getComponentNames(info.root.fileName) ?? [];
32
+ const elements = new Set(await getElementNames(info.root.fileName) ?? []);
34
33
  const components = new Set([
35
34
  ...validComponentNames,
36
35
  ...validComponentNames.map(language_core_1.hyphenateTag),
@@ -18,48 +18,50 @@ function create(ts, { getImportPathForFile }) {
18
18
  create(context) {
19
19
  return {
20
20
  async provideDocumentDropEdits(document, _position, dataTransfer) {
21
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template', 'html');
22
- if (!info) {
21
+ if (document.languageId !== 'html') {
22
+ return;
23
+ }
24
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
25
+ if (info?.code.id !== 'template') {
23
26
  return;
24
27
  }
25
- const { sourceScript, root } = info;
26
28
  let importUri;
27
29
  for (const [mimeType, item] of dataTransfer) {
28
30
  if (mimeType === 'text/uri-list') {
29
31
  importUri = item.value;
30
32
  }
31
33
  }
32
- if (!importUri || !root.vueCompilerOptions.extensions.some(ext => importUri.endsWith(ext))) {
34
+ if (!importUri || !info.root.vueCompilerOptions.extensions.some(ext => importUri.endsWith(ext))) {
33
35
  return;
34
36
  }
35
- const { sfc } = root;
37
+ const { sfc } = info.root;
36
38
  const script = sfc.scriptSetup ?? sfc.script;
37
39
  if (!script) {
38
40
  return;
39
41
  }
40
- const casing = await (0, nameCasing_1.checkCasing)(context, sourceScript.id);
42
+ const casing = await (0, nameCasing_1.checkCasing)(context, info.script.id);
41
43
  const baseName = path_browserify_1.posix.basename(importUri);
42
44
  const newName = (0, shared_1.capitalize)((0, shared_1.camelize)(baseName.slice(0, baseName.lastIndexOf('.'))));
43
45
  const additionalEdit = {};
44
- const code = [...(0, language_core_1.forEachEmbeddedCode)(root)].find(code => code.id === (sfc.scriptSetup ? 'scriptsetup_raw' : 'script_raw'));
46
+ const code = [...(0, language_core_1.forEachEmbeddedCode)(info.root)].find(code => code.id === (sfc.scriptSetup ? 'scriptsetup_raw' : 'script_raw'));
45
47
  const lastImportNode = (0, vue_extract_file_1.getLastImportNode)(ts, script.ast);
46
48
  const incomingFileName = vscode_uri_1.URI.parse(importUri).fsPath.replace(/\\/g, '/');
47
49
  let importPath;
48
- const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(root);
50
+ const serviceScript = info.script.generated.languagePlugin.typescript?.getServiceScript(info.root);
49
51
  if (serviceScript) {
50
- const tsDocumentUri = context.encodeEmbeddedDocumentUri(sourceScript.id, serviceScript.code.id);
52
+ const tsDocumentUri = context.encodeEmbeddedDocumentUri(info.script.id, serviceScript.code.id);
51
53
  const tsDocument = context.documents.get(tsDocumentUri, serviceScript.code.languageId, serviceScript.code.snapshot);
52
54
  const preferences = await (0, getUserPreferences_1.getUserPreferences)(context, tsDocument);
53
- importPath = (await getImportPathForFile(root.fileName, incomingFileName, preferences) ?? {}).path;
55
+ importPath = await getImportPathForFile(info.root.fileName, incomingFileName, preferences);
54
56
  }
55
57
  if (!importPath) {
56
- importPath = path_browserify_1.posix.relative(path_browserify_1.posix.dirname(root.fileName), incomingFileName)
58
+ importPath = path_browserify_1.posix.relative(path_browserify_1.posix.dirname(info.root.fileName), incomingFileName)
57
59
  || importUri.slice(importUri.lastIndexOf('/') + 1);
58
60
  if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
59
61
  importPath = './' + importPath;
60
62
  }
61
63
  }
62
- const embeddedDocumentUriStr = context.encodeEmbeddedDocumentUri(sourceScript.id, code.id).toString();
64
+ const embeddedDocumentUriStr = context.encodeEmbeddedDocumentUri(info.script.id, code.id).toString();
63
65
  additionalEdit.changes ??= {};
64
66
  additionalEdit.changes[embeddedDocumentUriStr] = [];
65
67
  additionalEdit.changes[embeddedDocumentUriStr].push({
@@ -12,12 +12,11 @@ function create({ getDocumentHighlights }) {
12
12
  create(context) {
13
13
  return {
14
14
  async provideDocumentHighlights(document, position) {
15
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'main');
16
- if (!info) {
15
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
16
+ if (info?.script.id.scheme !== 'file' || info.code.id !== 'main') {
17
17
  return;
18
18
  }
19
- const { root } = info;
20
- const { template } = root.sfc;
19
+ const { template } = info.root.sfc;
21
20
  const offset = document.offsetAt(position);
22
21
  if (template?.ast && offset >= template.startTagEnd && offset <= template.endTagStart) {
23
22
  const pos = offset - template.startTagEnd;
@@ -32,9 +31,9 @@ function create({ getDocumentHighlights }) {
32
31
  }
33
32
  }
34
33
  }
35
- const result = await getDocumentHighlights(root.fileName, offset);
34
+ const result = await getDocumentHighlights(info.root.fileName, offset);
36
35
  return result
37
- ?.filter(({ fileName }) => fileName === root.fileName)
36
+ ?.filter(({ fileName }) => fileName === info.root.fileName)
38
37
  .flatMap(({ highlightSpans }) => highlightSpans)
39
38
  .map(({ textSpan, kind }) => ({
40
39
  range: {
@@ -27,12 +27,11 @@ function create(ts, { collectExtractProps }) {
27
27
  if (startOffset === endOffset) {
28
28
  return;
29
29
  }
30
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template');
31
- if (!info) {
30
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
31
+ if (info?.code.id !== 'template') {
32
32
  return;
33
33
  }
34
- const { root } = info;
35
- const { sfc } = root;
34
+ const { sfc } = info.root;
36
35
  const script = sfc.scriptSetup ?? sfc.script;
37
36
  if (!sfc.template || !script) {
38
37
  return;
@@ -56,12 +55,11 @@ function create(ts, { collectExtractProps }) {
56
55
  async resolveCodeAction(codeAction) {
57
56
  const { uri, range, newName } = codeAction.data;
58
57
  const [startOffset, endOffset] = range;
59
- const info = (0, utils_1.getEmbeddedInfo)(context, { uri }, 'template');
60
- if (!info) {
58
+ const info = (0, utils_1.resolveEmbeddedCode)(context, uri);
59
+ if (info?.code.id !== 'template') {
61
60
  return codeAction;
62
61
  }
63
- const { sourceScript, virtualCode, root } = info;
64
- const { sfc } = root;
62
+ const { sfc } = info.root;
65
63
  const script = sfc.scriptSetup ?? sfc.script;
66
64
  if (!sfc.template || !script) {
67
65
  return codeAction;
@@ -70,12 +68,12 @@ function create(ts, { collectExtractProps }) {
70
68
  if (!templateCodeRange) {
71
69
  return codeAction;
72
70
  }
73
- const toExtract = await collectExtractProps(root.fileName, templateCodeRange) ?? [];
71
+ const toExtract = await collectExtractProps(info.root.fileName, templateCodeRange) ?? [];
74
72
  const templateInitialIndent = await context.env.getConfiguration('vue.format.template.initialIndent') ?? true;
75
73
  const scriptInitialIndent = await context.env.getConfiguration('vue.format.script.initialIndent')
76
74
  ?? false;
77
- const document = context.documents.get(vscode_uri_1.URI.parse(uri), virtualCode.languageId, virtualCode.snapshot);
78
- const sfcDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
75
+ const document = context.documents.get(vscode_uri_1.URI.parse(uri), info.code.languageId, info.code.snapshot);
76
+ const sfcDocument = context.documents.get(info.script.id, info.script.languageId, info.script.snapshot);
79
77
  const newUri = sfcDocument.uri.slice(0, sfcDocument.uri.lastIndexOf('/') + 1) + `${newName}.vue`;
80
78
  const lastImportNode = getLastImportNode(ts, script.ast);
81
79
  let newFileTags = [];
@@ -136,7 +134,7 @@ function create(ts, { collectExtractProps }) {
136
134
  // editing vue sfc
137
135
  {
138
136
  textDocument: {
139
- uri: sourceScript.id.toString(),
137
+ uri: info.script.id.toString(),
140
138
  version: null,
141
139
  },
142
140
  edits: sfcEdits,
@@ -261,7 +259,7 @@ function createAddComponentToOptionEdit(ts, sfc, ast, componentName) {
261
259
  newText: unescape(printText.replace(unicodeReg, '%u')),
262
260
  };
263
261
  }
264
- else if (exportDefault.args && exportDefault.argsNode) {
262
+ else {
265
263
  const newNode = {
266
264
  ...exportDefault.argsNode,
267
265
  properties: [
@@ -14,16 +14,15 @@ function create() {
14
14
  create(context) {
15
15
  return {
16
16
  provideDiagnostics(document) {
17
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'root_tags');
18
- if (!info) {
17
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
18
+ if (info?.code.id !== 'root_tags') {
19
19
  return;
20
20
  }
21
- const { sourceScript, root } = info;
22
- if (sourceScript.id.scheme !== 'file') {
21
+ if (info.script.id.scheme !== 'file') {
23
22
  return;
24
23
  }
25
- const { vueCompilerOptions } = root;
26
- const globalTypesPath = vueCompilerOptions.globalTypesPath(root.fileName);
24
+ const { vueCompilerOptions } = info.root;
25
+ const globalTypesPath = vueCompilerOptions.globalTypesPath(info.root.fileName);
27
26
  if (globalTypesPath) {
28
27
  return;
29
28
  }
@@ -13,21 +13,20 @@ function create(ts) {
13
13
  create(context) {
14
14
  return {
15
15
  async provideInlayHints(document, range) {
16
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'main');
17
- if (!info) {
16
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
17
+ if (info?.code.id !== 'main') {
18
18
  return;
19
19
  }
20
- const { root } = info;
21
20
  const settings = {};
22
21
  async function getSettingEnabled(key) {
23
22
  return settings[key] ??= await context.env.getConfiguration?.(key) ?? false;
24
23
  }
25
24
  const result = [];
26
- const { sfc } = root;
25
+ const { sfc } = info.root;
27
26
  const codegen = language_core_1.tsCodegen.get(sfc);
28
27
  const inlayHints = [
29
28
  ...codegen?.getGeneratedTemplate()?.inlayHints ?? [],
30
- ...codegen?.getGeneratedScript()?.inlayHints ?? [],
29
+ ...codegen?.getGeneratedScript().inlayHints ?? [],
31
30
  ];
32
31
  const scriptSetupRanges = codegen?.getScriptSetupRanges();
33
32
  if (scriptSetupRanges?.defineProps?.destructured && sfc.scriptSetup?.ast) {
@@ -96,7 +95,6 @@ function findDestructuredProps(ts, ast, props) {
96
95
  const scopeStack = [rootScope];
97
96
  let currentScope = rootScope;
98
97
  const excludedIds = new WeakSet();
99
- const parentStack = [];
100
98
  for (const prop of props) {
101
99
  rootScope[prop] = true;
102
100
  }
@@ -176,9 +174,6 @@ function findDestructuredProps(ts, ast, props) {
176
174
  }
177
175
  });
178
176
  function enter(node) {
179
- if (parent) {
180
- parentStack.push(parent);
181
- }
182
177
  if (ts.isTypeLiteralNode(node)
183
178
  || ts.isTypeReferenceNode(node)) {
184
179
  return false;
@@ -218,9 +213,6 @@ function findDestructuredProps(ts, ast, props) {
218
213
  }
219
214
  }
220
215
  function leave(node) {
221
- if (parent) {
222
- parentStack.pop();
223
- }
224
216
  if (ts.isFunctionLike(node)
225
217
  || ts.isCatchClause(node)
226
218
  || (ts.isBlock(node)
@@ -15,11 +15,10 @@ function create({ getComponentNames, getElementNames, getComponentProps }) {
15
15
  let intrinsicElementNames;
16
16
  return {
17
17
  async provideInlayHints(document, range, cancellationToken) {
18
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template');
19
- if (!info) {
18
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
19
+ if (info?.code.id !== 'template') {
20
20
  return;
21
21
  }
22
- const { sourceScript, root } = info;
23
22
  const enabled = await context.env.getConfiguration?.('vue.inlayHints.missingProps') ?? false;
24
23
  if (!enabled) {
25
24
  return;
@@ -29,10 +28,10 @@ function create({ getComponentNames, getElementNames, getComponentProps }) {
29
28
  return;
30
29
  }
31
30
  const result = [];
32
- const casing = await (0, nameCasing_1.checkCasing)(context, sourceScript.id);
33
- const components = await getComponentNames(root.fileName) ?? [];
34
- const componentProps = {};
35
- intrinsicElementNames ??= new Set(await getElementNames(root.fileName) ?? []);
31
+ const casing = await (0, nameCasing_1.checkCasing)(context, info.script.id);
32
+ const components = await getComponentNames(info.root.fileName) ?? [];
33
+ const componentProps = new Map();
34
+ intrinsicElementNames ??= new Set(await getElementNames(info.root.fileName) ?? []);
36
35
  let token;
37
36
  let current;
38
37
  while ((token = scanner.scan()) !== html.TokenType.EOS) {
@@ -51,16 +50,16 @@ function create({ getComponentNames, getElementNames, getComponentProps }) {
51
50
  if (tagOffset > document.offsetAt(range.end)) {
52
51
  break;
53
52
  }
54
- if (!componentProps[checkTag]) {
53
+ if (!componentProps.has(checkTag)) {
55
54
  if (cancellationToken.isCancellationRequested) {
56
55
  break;
57
56
  }
58
- componentProps[checkTag] = (await getComponentProps(root.fileName, checkTag) ?? [])
57
+ componentProps.set(checkTag, (await getComponentProps(info.root.fileName, checkTag) ?? [])
59
58
  .filter(prop => prop.required)
60
- .map(prop => prop.name);
59
+ .map(prop => prop.name));
61
60
  }
62
61
  current = {
63
- unburnedRequiredProps: [...componentProps[checkTag]],
62
+ unburnedRequiredProps: [...componentProps.get(checkTag)],
64
63
  labelOffset: scanner.getTokenOffset() + scanner.getTokenLength(),
65
64
  };
66
65
  }
@@ -86,7 +85,7 @@ function create({ getComponentNames, getElementNames, getComponentProps }) {
86
85
  attrText = attrText.slice('v-model:'.length);
87
86
  }
88
87
  else if (attrText === 'v-model') {
89
- attrText = root.vueCompilerOptions.target >= 3 ? 'modelValue' : 'value'; // TODO: support for experimentalModelPropName?
88
+ attrText = info.root.vueCompilerOptions.target >= 3 ? 'modelValue' : 'value'; // TODO: support for experimentalModelPropName?
90
89
  }
91
90
  else if (attrText.startsWith('v-on:')) {
92
91
  attrText = 'on-' + (0, language_core_1.hyphenateAttr)(attrText.slice('v-on:'.length));
@@ -12,14 +12,13 @@ function create() {
12
12
  create(context) {
13
13
  return {
14
14
  provideDocumentLinks(document) {
15
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template');
16
- if (!info) {
15
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
16
+ if (info?.code.id !== 'template') {
17
17
  return;
18
18
  }
19
- const { sourceScript, root } = info;
20
- const { sfc } = root;
19
+ const { sfc } = info.root;
21
20
  const codegen = language_core_1.tsCodegen.get(sfc);
22
- const option = root.vueCompilerOptions.resolveStyleClassNames;
21
+ const option = info.root.vueCompilerOptions.resolveStyleClassNames;
23
22
  const scopedClasses = codegen?.getGeneratedTemplate()?.scopedClasses ?? [];
24
23
  const styleClasses = new Map();
25
24
  for (let i = 0; i < sfc.styles.length; i++) {
@@ -27,8 +26,8 @@ function create() {
27
26
  if (option !== true && !(option === 'scoped' && style.scoped)) {
28
27
  continue;
29
28
  }
30
- const styleDocumentUri = context.encodeEmbeddedDocumentUri(sourceScript.id, 'style_' + i);
31
- const styleVirtualCode = sourceScript.generated.embeddedCodes.get('style_' + i);
29
+ const styleDocumentUri = context.encodeEmbeddedDocumentUri(info.script.id, 'style_' + i);
30
+ const styleVirtualCode = info.script.generated.embeddedCodes.get('style_' + i);
32
31
  if (!styleVirtualCode) {
33
32
  continue;
34
33
  }
@@ -16,14 +16,13 @@ function create() {
16
16
  return [sfcDataProvider];
17
17
  },
18
18
  async getFormattingOptions(document, options, context) {
19
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'root_tags');
20
- if (!info) {
19
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
20
+ if (info?.code.id !== 'root_tags') {
21
21
  return {};
22
22
  }
23
- const { root } = info;
24
23
  const formatSettings = await context.env.getConfiguration?.('html.format') ?? {};
25
24
  const blockTypes = ['template', 'script', 'style'];
26
- for (const customBlock of root.sfc.customBlocks) {
25
+ for (const customBlock of info.root.sfc.customBlocks) {
27
26
  blockTypes.push(customBlock.type);
28
27
  }
29
28
  return {
@@ -76,12 +75,11 @@ function create() {
76
75
  return options;
77
76
  },
78
77
  async provideDiagnostics(document, token) {
79
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'root_tags');
80
- if (!info) {
78
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
79
+ if (info?.code.id !== 'root_tags') {
81
80
  return [];
82
81
  }
83
- const { root } = info;
84
- const { vueSfc, sfc } = root;
82
+ const { vueSfc, sfc } = info.root;
85
83
  if (!vueSfc) {
86
84
  return;
87
85
  }
@@ -113,13 +111,12 @@ function create() {
113
111
  ];
114
112
  },
115
113
  provideDocumentSymbols(document) {
116
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'root_tags');
117
- if (!info) {
114
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
115
+ if (info?.code.id !== 'root_tags') {
118
116
  return;
119
117
  }
120
- const { root } = info;
121
118
  const result = [];
122
- const { sfc } = root;
119
+ const { sfc } = info.root;
123
120
  if (sfc.template) {
124
121
  result.push({
125
122
  name: 'template',
@@ -185,7 +182,7 @@ function create() {
185
182
  }
186
183
  for (const customBlock of sfc.customBlocks) {
187
184
  result.push({
188
- name: `${customBlock.type}`,
185
+ name: customBlock.type,
189
186
  kind: 2,
190
187
  range: {
191
188
  start: document.positionAt(customBlock.start),
@@ -13,16 +13,15 @@ function create() {
13
13
  return {
14
14
  isAdditionalCompletion: true,
15
15
  async provideCompletionItems(document) {
16
- const info = (0, utils_1.getEmbeddedInfo)(context, document, id => id.startsWith('script_'));
17
- if (!info) {
16
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
17
+ if (!info?.code.id.startsWith('script_')) {
18
18
  return;
19
19
  }
20
- const { virtualCode, root } = info;
21
20
  const enabled = await context.env.getConfiguration?.('vue.suggest.defineAssignment') ?? true;
22
21
  if (!enabled) {
23
22
  return;
24
23
  }
25
- const { sfc } = root;
24
+ const { sfc } = info.root;
26
25
  const codegen = language_core_1.tsCodegen.get(sfc);
27
26
  const scriptSetup = sfc.scriptSetup;
28
27
  const scriptSetupRanges = codegen?.getScriptSetupRanges();
@@ -30,7 +29,7 @@ function create() {
30
29
  return;
31
30
  }
32
31
  const result = [];
33
- const mappings = [...context.language.maps.forEach(virtualCode)];
32
+ const mappings = [...context.language.maps.forEach(info.code)];
34
33
  addDefineCompletionItem(scriptSetupRanges.defineProps?.statement, scriptSetupRanges.withDefaults?.exp ?? scriptSetupRanges.defineProps?.exp, 'props');
35
34
  addDefineCompletionItem(scriptSetupRanges.defineEmits?.statement, scriptSetupRanges.defineEmits?.exp, 'emit');
36
35
  addDefineCompletionItem(scriptSetupRanges.defineSlots?.statement, scriptSetupRanges.defineSlots?.exp, 'slots');
@@ -12,21 +12,20 @@ function create() {
12
12
  create(context) {
13
13
  return {
14
14
  provideDocumentLinks(document) {
15
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'scriptsetup_raw');
16
- if (!info) {
15
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
16
+ if (info?.code.id !== 'scriptsetup_raw') {
17
17
  return;
18
18
  }
19
- const { sourceScript, root } = info;
20
- const { sfc } = root;
19
+ const { sfc } = info.root;
21
20
  const codegen = language_core_1.tsCodegen.get(sfc);
22
21
  if (!sfc.scriptSetup) {
23
22
  return;
24
23
  }
25
- const templateVirtualCode = sourceScript.generated.embeddedCodes.get('template');
24
+ const templateVirtualCode = info.script.generated.embeddedCodes.get('template');
26
25
  if (!templateVirtualCode) {
27
26
  return;
28
27
  }
29
- const templateDocumentUri = context.encodeEmbeddedDocumentUri(sourceScript.id, 'template');
28
+ const templateDocumentUri = context.encodeEmbeddedDocumentUri(info.script.id, 'template');
30
29
  const templateDocument = context.documents.get(templateDocumentUri, templateVirtualCode.languageId, templateVirtualCode.snapshot);
31
30
  const templateRefs = codegen?.getGeneratedTemplate()?.templateRefs;
32
31
  const useTemplateRefs = codegen?.getScriptSetupRanges()?.useTemplateRef ?? [];
@@ -128,12 +128,14 @@ function create(languageId, { getComponentNames, getElementAttrs, getComponentPr
128
128
  disposable?.dispose();
129
129
  },
130
130
  async provideCompletionItems(document, position, completionContext, token) {
131
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template', languageId);
132
- if (!info) {
131
+ if (document.languageId !== languageId) {
133
132
  return;
134
133
  }
135
- const { sourceScript, root } = info;
136
- const { result: completionList, target, info: { components, propMap, }, } = await runWithVueData(sourceScript.id, root, () => baseServiceInstance.provideCompletionItems(document, position, completionContext, token));
134
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
135
+ if (info?.code.id !== 'template') {
136
+ return;
137
+ }
138
+ const { result: completionList, target, info: { components, propMap, }, } = await runWithVueData(info.script.id, info.root, () => baseServiceInstance.provideCompletionItems(document, position, completionContext, token));
137
139
  if (!completionList) {
138
140
  return;
139
141
  }
@@ -248,8 +250,11 @@ function create(languageId, { getComponentNames, getElementAttrs, getComponentPr
248
250
  }
249
251
  },
250
252
  provideHover(document, position, token) {
251
- const info = (0, utils_1.getEmbeddedInfo)(context, document, 'template', languageId);
252
- if (!info) {
253
+ if (document.languageId !== languageId) {
254
+ return;
255
+ }
256
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
257
+ if (info?.code.id !== 'template') {
253
258
  return;
254
259
  }
255
260
  if (context.decodeEmbeddedDocumentUri(vscode_uri_1.URI.parse(document.uri))) {
@@ -341,7 +346,7 @@ function create(languageId, { getComponentNames, getElementAttrs, getComponentPr
341
346
  if (casing.tag === nameCasing_1.TagNameCasing.Kebab) {
342
347
  names.add((0, language_core_1.hyphenateTag)(tag));
343
348
  }
344
- else if (casing.tag === nameCasing_1.TagNameCasing.Pascal) {
349
+ else {
345
350
  names.add(tag);
346
351
  }
347
352
  }
@@ -350,7 +355,7 @@ function create(languageId, { getComponentNames, getElementAttrs, getComponentPr
350
355
  if (casing.tag === nameCasing_1.TagNameCasing.Kebab) {
351
356
  names.add((0, language_core_1.hyphenateTag)(name));
352
357
  }
353
- else if (casing.tag === nameCasing_1.TagNameCasing.Pascal) {
358
+ else {
354
359
  names.add(name);
355
360
  }
356
361
  }
@@ -572,7 +577,7 @@ function create(languageId, { getComponentNames, getElementAttrs, getComponentPr
572
577
  for (const customDataPath of customData) {
573
578
  for (const workspaceFolder of context.env.workspaceFolders) {
574
579
  const uri = vscode_uri_1.Utils.resolvePath(workspaceFolder, customDataPath);
575
- const json = await context.env.fs?.readFile?.(uri);
580
+ const json = await context.env.fs?.readFile(uri);
576
581
  if (json) {
577
582
  try {
578
583
  const data = JSON.parse(json);
@@ -13,14 +13,14 @@ function create({ getQuickInfoAtPosition }) {
13
13
  create(context) {
14
14
  return {
15
15
  async provideInlayHints(document, range) {
16
- const info = (0, utils_1.getEmbeddedInfo)(context, document, id => id === 'template' || id.startsWith('script_'));
17
- if (!info) {
16
+ const info = (0, utils_1.resolveEmbeddedCode)(context, document.uri);
17
+ if (info?.code.id !== 'template' && !info?.code.id.startsWith('script_')) {
18
18
  return;
19
19
  }
20
- const { sourceScript, virtualCode, root } = info;
21
20
  const hoverOffsets = [];
22
21
  const inlayHints = [];
23
- const twoslashReg = virtualCode.id === 'template' ? twoslashTemplateReg : twoslashScriptReg;
22
+ const twoslashReg = info.code.id === 'template' ? twoslashTemplateReg : twoslashScriptReg;
23
+ const sourceDocument = context.documents.get(info.script.id, info.script.languageId, info.script.snapshot);
24
24
  for (const pointer of document.getText(range).matchAll(twoslashReg)) {
25
25
  const offset = pointer.index + pointer[0].indexOf('^?') + document.offsetAt(range.start);
26
26
  const position = document.positionAt(offset);
@@ -32,11 +32,10 @@ function create({ getQuickInfoAtPosition }) {
32
32
  }),
33
33
  ]);
34
34
  }
35
- const sourceDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
36
35
  for (const [pointerPosition, hoverOffset] of hoverOffsets) {
37
- const map = context.language.maps.get(virtualCode, sourceScript);
36
+ const map = context.language.maps.get(info.code, info.script);
38
37
  for (const [sourceOffset] of map.toSourceLocation(hoverOffset)) {
39
- const quickInfo = await getQuickInfoAtPosition(root.fileName, sourceDocument.positionAt(sourceOffset));
38
+ const quickInfo = await getQuickInfoAtPosition(info.root.fileName, sourceDocument.positionAt(sourceOffset));
40
39
  if (quickInfo) {
41
40
  inlayHints.push({
42
41
  position: { line: pointerPosition.line, character: pointerPosition.character + 2 },
package/lib/utils.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { type LanguageServiceContext, type SourceScript, type TextDocument } from '@volar/language-service';
2
- import { VueVirtualCode } from '@vue/language-core';
1
+ import type { LanguageServiceContext, SourceScript } from '@volar/language-service';
2
+ import type { VueVirtualCode } from '@vue/language-core';
3
3
  import { URI } from 'vscode-uri';
4
- export declare function getEmbeddedInfo(context: LanguageServiceContext, document: TextDocument, embeddedCodeId?: string | ((id: string) => boolean), languageId?: string): {
5
- sourceScript: Required<SourceScript<URI>>;
6
- virtualCode: import("@volar/language-service").VirtualCode;
4
+ export declare function resolveEmbeddedCode(context: LanguageServiceContext, uriStr: string): {
5
+ script: Required<SourceScript<URI>>;
6
+ code: import("@volar/language-service").VirtualCode;
7
7
  root: VueVirtualCode;
8
8
  } | undefined;
package/lib/utils.js CHANGED
@@ -1,43 +1,19 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getEmbeddedInfo = getEmbeddedInfo;
4
- const language_core_1 = require("@vue/language-core");
3
+ exports.resolveEmbeddedCode = resolveEmbeddedCode;
5
4
  const vscode_uri_1 = require("vscode-uri");
6
- function getEmbeddedInfo(context, document, embeddedCodeId, languageId) {
7
- const uri = vscode_uri_1.URI.parse(document.uri);
5
+ function resolveEmbeddedCode(context, uriStr) {
6
+ const uri = vscode_uri_1.URI.parse(uriStr);
8
7
  const decoded = context.decodeEmbeddedDocumentUri(uri);
9
8
  if (!decoded) {
10
9
  return;
11
10
  }
12
- if (embeddedCodeId) {
13
- if (typeof embeddedCodeId === 'string') {
14
- if (decoded[1] !== embeddedCodeId) {
15
- return;
16
- }
17
- }
18
- else if (!embeddedCodeId(decoded[1])) {
19
- return;
20
- }
21
- }
22
- if (languageId && document.languageId !== languageId) {
23
- return;
24
- }
25
11
  const sourceScript = context.language.scripts.get(decoded[0]);
26
- if (!sourceScript?.generated) {
27
- return;
28
- }
29
- const virtualCode = sourceScript.generated.embeddedCodes.get(decoded[1]);
30
- if (!virtualCode) {
31
- return;
32
- }
33
- const root = sourceScript.generated.root;
34
- if (!(root instanceof language_core_1.VueVirtualCode)) {
35
- return;
36
- }
12
+ const code = sourceScript.generated.embeddedCodes.get(decoded[1]);
37
13
  return {
38
- sourceScript: sourceScript,
39
- virtualCode,
40
- root,
14
+ script: sourceScript,
15
+ code,
16
+ root: sourceScript.generated.root,
41
17
  };
42
18
  }
43
19
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/language-service",
3
- "version": "3.0.7-alpha.1",
3
+ "version": "3.0.8",
4
4
  "license": "MIT",
5
5
  "files": [
6
6
  "data",
@@ -18,7 +18,7 @@
18
18
  },
19
19
  "dependencies": {
20
20
  "@volar/language-service": "2.4.23",
21
- "@vue/language-core": "3.0.7-alpha.1",
21
+ "@vue/language-core": "3.0.8",
22
22
  "@vue/shared": "^3.5.0",
23
23
  "path-browserify": "^1.0.1",
24
24
  "volar-service-css": "0.0.65",
@@ -37,8 +37,8 @@
37
37
  "@volar/kit": "2.4.23",
38
38
  "@volar/typescript": "2.4.23",
39
39
  "@vue/compiler-dom": "^3.5.0",
40
- "@vue/typescript-plugin": "3.0.7-alpha.1",
40
+ "@vue/typescript-plugin": "3.0.8",
41
41
  "vscode-css-languageservice": "^6.3.1"
42
42
  },
43
- "gitHead": "320fc626c871e9ff17c0e4e92ea7ddb0c7641f34"
43
+ "gitHead": "f7bdeaa7bb476df1fc8ff46c504d75c1869b0be9"
44
44
  }