Skip to content

Commit 9f15d5f

Browse files
committed
refactor(language-service): simplified getEmbeddedInfo
1 parent 320fc62 commit 9f15d5f

18 files changed

+133
-182
lines changed

packages/language-service/lib/plugins/css.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type { LanguageServicePlugin, TextDocument, VirtualCode } from '@volar/la
22
import { isRenameEnabled } from '@vue/language-core';
33
import { create as baseCreate, type Provide } from 'volar-service-css';
44
import type * as css from 'vscode-css-languageservice';
5-
import { getEmbeddedInfo } from '../utils';
5+
import { resolveEmbeddedCode } from '../utils';
66

77
export function create(): LanguageServicePlugin {
88
const base = baseCreate({ scssDocumentSelector: ['scss', 'postcss'] });
@@ -54,19 +54,17 @@ export function create(): LanguageServicePlugin {
5454
document: TextDocument,
5555
position: css.Position,
5656
) {
57-
const info = getEmbeddedInfo(context, document, id => id.startsWith('style_'));
58-
if (!info) {
57+
const info = resolveEmbeddedCode(context, document.uri);
58+
if (!info?.code.id.startsWith('style_')) {
5959
return false;
6060
}
61-
const { sourceScript, virtualCode, root } = info;
62-
63-
const block = root.sfc.styles.find(style => style.name === virtualCode.id);
61+
const block = info.root.sfc.styles.find(style => style.name === info.code.id);
6462
if (!block) {
6563
return false;
6664
}
6765

6866
let script: VirtualCode | undefined;
69-
for (const [key, value] of sourceScript.generated.embeddedCodes) {
67+
for (const [key, value] of info.script.generated.embeddedCodes) {
7068
if (key.startsWith('script_')) {
7169
script = value;
7270
break;

packages/language-service/lib/plugins/typescript-semantic-tokens.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { LanguageServicePlugin } from '@volar/language-service';
22
import { convertClassificationsToSemanticTokens } from 'volar-service-typescript/lib/semanticFeatures/semanticTokens';
3-
import { getEmbeddedInfo } from '../utils';
3+
import { resolveEmbeddedCode } from '../utils';
44

55
export function create(
66
{ getEncodedSemanticClassifications }: import('@vue/typescript-plugin/lib/requests').Requests,
@@ -38,23 +38,20 @@ export function create(
3838
create(context) {
3939
return {
4040
async provideDocumentSemanticTokens(document, range, legend) {
41-
const info = getEmbeddedInfo(context, document, 'main');
42-
if (!info) {
41+
const info = resolveEmbeddedCode(context, document.uri);
42+
if (info?.code.id !== 'main') {
4343
return;
4444
}
45-
const { root } = info;
46-
4745
const start = document.offsetAt(range.start);
4846
const end = document.offsetAt(range.end);
4947
const span = {
5048
start: start,
5149
length: end - start,
5250
};
5351
const classifications = await getEncodedSemanticClassifications(
54-
root.fileName,
52+
info.root.fileName,
5553
span,
5654
);
57-
5855
if (classifications) {
5956
return convertClassificationsToSemanticTokens(document, span, legend, classifications);
6057
}

packages/language-service/lib/plugins/vue-autoinsert-dotvalue.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { LanguageServicePlugin, TextDocument } from '@volar/language-service';
22
import { hyphenateAttr } from '@vue/language-core';
33
import type * as ts from 'typescript';
4-
import { getEmbeddedInfo } from '../utils';
4+
import { resolveEmbeddedCode } from '../utils';
55

66
export function create(
77
ts: typeof import('typescript'),
@@ -18,8 +18,8 @@ export function create(
1818
create(context) {
1919
return {
2020
async provideAutoInsertSnippet(document, selection, change) {
21-
const info = getEmbeddedInfo(context, document, id => id.startsWith('script_'));
22-
if (!info) {
21+
const info = resolveEmbeddedCode(context, document.uri);
22+
if (!info?.code.id.startsWith('script_')) {
2323
return;
2424
}
2525

@@ -34,10 +34,9 @@ export function create(
3434

3535
let sourceOffset: number | undefined;
3636

37-
const { sourceScript, virtualCode, root } = info;
38-
const { sfc } = root;
37+
const { sfc } = info.root;
3938
const scriptBlocks = [sfc.script, sfc.scriptSetup].filter(block => !!block);
40-
const map = context.language.maps.get(virtualCode, sourceScript);
39+
const map = context.language.maps.get(info.code, info.script);
4140

4241
if (!scriptBlocks.length) {
4342
return;
@@ -61,7 +60,7 @@ export function create(
6160
}
6261
}
6362

64-
const props = await getPropertiesAtLocation(root.fileName, sourceOffset) ?? [];
63+
const props = await getPropertiesAtLocation(info.root.fileName, sourceOffset) ?? [];
6564
if (props.some(prop => prop === 'value')) {
6665
return '${1:.value}';
6766
}

packages/language-service/lib/plugins/vue-compiler-dom-errors.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Diagnostic, DiagnosticSeverity, LanguageServicePlugin } from '@volar/language-service';
2-
import { getEmbeddedInfo } from '../utils';
2+
import { resolveEmbeddedCode } from '../utils';
33

44
export function create(): LanguageServicePlugin {
55
return {
@@ -13,13 +13,12 @@ export function create(): LanguageServicePlugin {
1313
create(context) {
1414
return {
1515
provideDiagnostics(document) {
16-
const info = getEmbeddedInfo(context, document, 'template');
17-
if (!info) {
16+
const info = resolveEmbeddedCode(context, document.uri);
17+
if (info?.code.id !== 'template') {
1818
return;
1919
}
20-
const { root } = info;
2120

22-
const { template } = root.sfc;
21+
const { template } = info.root.sfc;
2322
if (!template) {
2423
return;
2524
}

packages/language-service/lib/plugins/vue-component-semantic-tokens.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { LanguageServicePlugin, SemanticToken } from '@volar/language-service';
22
import { forEachElementNode, hyphenateTag } from '@vue/language-core';
33
import type * as ts from 'typescript';
4-
import { getEmbeddedInfo } from '../utils';
4+
import { resolveEmbeddedCode } from '../utils';
55

66
export function create(
77
{ getComponentNames, getElementNames }: import('@vue/typescript-plugin/lib/requests').Requests,
@@ -19,13 +19,12 @@ export function create(
1919
create(context) {
2020
return {
2121
async provideDocumentSemanticTokens(document, range, legend) {
22-
const info = getEmbeddedInfo(context, document, 'template');
23-
if (!info) {
22+
const info = resolveEmbeddedCode(context, document.uri);
23+
if (info?.code.id !== 'template') {
2424
return;
2525
}
26-
const { root } = info;
2726

28-
const { template } = root.sfc;
27+
const { template } = info.root.sfc;
2928
if (!template?.ast) {
3029
return;
3130
}
@@ -34,8 +33,8 @@ export function create(
3433
const start = document.offsetAt(range.start);
3534
const end = document.offsetAt(range.end);
3635

37-
const validComponentNames = await getComponentNames(root.fileName) ?? [];
38-
const elements = new Set(await getElementNames(root.fileName) ?? []);
36+
const validComponentNames = await getComponentNames(info.root.fileName) ?? [];
37+
const elements = new Set(await getElementNames(info.root.fileName) ?? []);
3938
const components = new Set([
4039
...validComponentNames,
4140
...validComponentNames.map(hyphenateTag),

packages/language-service/lib/plugins/vue-document-drop.ts

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { getUserPreferences } from 'volar-service-typescript/lib/configs/getUser
66
import { URI } from 'vscode-uri';
77
import { checkCasing, TagNameCasing } from '../nameCasing';
88
import { createAddComponentToOptionEdit, getLastImportNode } from '../plugins/vue-extract-file';
9-
import { getEmbeddedInfo } from '../utils';
9+
import { resolveEmbeddedCode } from '../utils';
1010

1111
export function create(
1212
ts: typeof import('typescript'),
@@ -20,44 +20,46 @@ export function create(
2020
create(context) {
2121
return {
2222
async provideDocumentDropEdits(document, _position, dataTransfer) {
23-
const info = getEmbeddedInfo(context, document, 'template', 'html');
24-
if (!info) {
23+
if (document.languageId !== 'html') {
24+
return;
25+
}
26+
const info = resolveEmbeddedCode(context, document.uri);
27+
if (info?.code.id !== 'template') {
2528
return;
2629
}
27-
const { sourceScript, root } = info;
2830

2931
let importUri: string | undefined;
3032
for (const [mimeType, item] of dataTransfer) {
3133
if (mimeType === 'text/uri-list') {
3234
importUri = item.value as string;
3335
}
3436
}
35-
if (!importUri || !root.vueCompilerOptions.extensions.some(ext => importUri.endsWith(ext))) {
37+
if (!importUri || !info.root.vueCompilerOptions.extensions.some(ext => importUri.endsWith(ext))) {
3638
return;
3739
}
3840

39-
const { sfc } = root;
41+
const { sfc } = info.root;
4042
const script = sfc.scriptSetup ?? sfc.script;
4143
if (!script) {
4244
return;
4345
}
4446

45-
const casing = await checkCasing(context, sourceScript.id);
47+
const casing = await checkCasing(context, info.script.id);
4648
const baseName = path.basename(importUri);
4749
const newName = capitalize(camelize(baseName.slice(0, baseName.lastIndexOf('.'))));
4850

4951
const additionalEdit: WorkspaceEdit = {};
50-
const code = [...forEachEmbeddedCode(root)].find(code =>
52+
const code = [...forEachEmbeddedCode(info.root)].find(code =>
5153
code.id === (sfc.scriptSetup ? 'scriptsetup_raw' : 'script_raw')
5254
)!;
5355
const lastImportNode = getLastImportNode(ts, script.ast);
5456
const incomingFileName = URI.parse(importUri).fsPath.replace(/\\/g, '/');
5557

5658
let importPath: string | undefined;
5759

58-
const serviceScript = sourceScript.generated.languagePlugin.typescript?.getServiceScript(root);
60+
const serviceScript = info.script.generated.languagePlugin.typescript?.getServiceScript(info.root);
5961
if (serviceScript) {
60-
const tsDocumentUri = context.encodeEmbeddedDocumentUri(sourceScript.id, serviceScript.code.id);
62+
const tsDocumentUri = context.encodeEmbeddedDocumentUri(info.script.id, serviceScript.code.id);
6163
const tsDocument = context.documents.get(
6264
tsDocumentUri,
6365
serviceScript.code.languageId,
@@ -66,23 +68,23 @@ export function create(
6668
const preferences = await getUserPreferences(context, tsDocument);
6769
importPath = (
6870
await getImportPathForFile(
69-
root.fileName,
71+
info.root.fileName,
7072
incomingFileName,
7173
preferences,
7274
) ?? {}
7375
).path;
7476
}
7577

7678
if (!importPath) {
77-
importPath = path.relative(path.dirname(root.fileName), incomingFileName)
79+
importPath = path.relative(path.dirname(info.root.fileName), incomingFileName)
7880
|| importUri.slice(importUri.lastIndexOf('/') + 1);
7981

8082
if (!importPath.startsWith('./') && !importPath.startsWith('../')) {
8183
importPath = './' + importPath;
8284
}
8385
}
8486

85-
const embeddedDocumentUriStr = context.encodeEmbeddedDocumentUri(sourceScript.id, code.id).toString();
87+
const embeddedDocumentUriStr = context.encodeEmbeddedDocumentUri(info.script.id, code.id).toString();
8688

8789
additionalEdit.changes ??= {};
8890
additionalEdit.changes[embeddedDocumentUriStr] = [];

packages/language-service/lib/plugins/vue-document-highlights.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { DocumentHighlightKind, LanguageServicePlugin } from '@volar/language-service';
22
import { forEachElementNode, getElementTagOffsets } from '@vue/language-core';
3-
import { getEmbeddedInfo } from '../utils';
3+
import { resolveEmbeddedCode } from '../utils';
44

55
export function create(
66
{ getDocumentHighlights }: import('@vue/typescript-plugin/lib/requests').Requests,
@@ -13,13 +13,12 @@ export function create(
1313
create(context) {
1414
return {
1515
async provideDocumentHighlights(document, position) {
16-
const info = getEmbeddedInfo(context, document, 'main');
17-
if (!info) {
16+
const info = resolveEmbeddedCode(context, document.uri);
17+
if (info?.code.id !== 'main') {
1818
return;
1919
}
20-
const { root } = info;
2120

22-
const { template } = root.sfc;
21+
const { template } = info.root.sfc;
2322
const offset = document.offsetAt(position);
2423

2524
if (template?.ast && offset >= template.startTagEnd && offset <= template.endTagStart) {
@@ -36,10 +35,10 @@ export function create(
3635
}
3736
}
3837

39-
const result = await getDocumentHighlights(root.fileName, offset);
38+
const result = await getDocumentHighlights(info.root.fileName, offset);
4039

4140
return result
42-
?.filter(({ fileName }) => fileName === root.fileName)
41+
?.filter(({ fileName }) => fileName === info.root.fileName)
4342
.flatMap(({ highlightSpans }) => highlightSpans)
4443
.map(({ textSpan, kind }) => ({
4544
range: {

packages/language-service/lib/plugins/vue-extract-file.ts

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { ExpressionNode, TemplateChildNode } from '@vue/compiler-dom';
33
import { type Sfc, tsCodegen } from '@vue/language-core';
44
import type * as ts from 'typescript';
55
import { URI } from 'vscode-uri';
6-
import { getEmbeddedInfo } from '../utils';
6+
import { resolveEmbeddedCode } from '../utils';
77

88
interface ActionData {
99
uri: string;
@@ -38,13 +38,12 @@ export function create(
3838
return;
3939
}
4040

41-
const info = getEmbeddedInfo(context, document, 'template');
42-
if (!info) {
41+
const info = resolveEmbeddedCode(context, document.uri);
42+
if (info?.code.id !== 'template') {
4343
return;
4444
}
45-
const { root } = info;
4645

47-
const { sfc } = root;
46+
const { sfc } = info.root;
4847
const script = sfc.scriptSetup ?? sfc.script;
4948
if (!sfc.template || !script) {
5049
return;
@@ -72,13 +71,12 @@ export function create(
7271
const { uri, range, newName } = codeAction.data as ActionData;
7372
const [startOffset, endOffset]: [number, number] = range;
7473

75-
const info = getEmbeddedInfo(context, { uri } as any, 'template');
76-
if (!info) {
74+
const info = resolveEmbeddedCode(context, uri);
75+
if (info?.code.id !== 'template') {
7776
return codeAction;
7877
}
79-
const { sourceScript, virtualCode, root } = info;
8078

81-
const { sfc } = root;
79+
const { sfc } = info.root;
8280
const script = sfc.scriptSetup ?? sfc.script;
8381
if (!sfc.template || !script) {
8482
return codeAction;
@@ -89,15 +87,15 @@ export function create(
8987
return codeAction;
9088
}
9189

92-
const toExtract = await collectExtractProps(root.fileName, templateCodeRange) ?? [];
90+
const toExtract = await collectExtractProps(info.root.fileName, templateCodeRange) ?? [];
9391

9492
const templateInitialIndent =
9593
await context.env.getConfiguration!<boolean>('vue.format.template.initialIndent') ?? true;
9694
const scriptInitialIndent = await context.env.getConfiguration!<boolean>('vue.format.script.initialIndent')
9795
?? false;
9896

99-
const document = context.documents.get(URI.parse(uri), virtualCode.languageId, virtualCode.snapshot);
100-
const sfcDocument = context.documents.get(sourceScript.id, sourceScript.languageId, sourceScript.snapshot);
97+
const document = context.documents.get(URI.parse(uri), info.code.languageId, info.code.snapshot);
98+
const sfcDocument = context.documents.get(info.script.id, info.script.languageId, info.script.snapshot);
10199
const newUri = sfcDocument.uri.slice(0, sfcDocument.uri.lastIndexOf('/') + 1) + `${newName}.vue`;
102100
const lastImportNode = getLastImportNode(ts, script.ast);
103101

@@ -175,7 +173,7 @@ export function create(
175173
// editing vue sfc
176174
{
177175
textDocument: {
178-
uri: sourceScript.id.toString(),
176+
uri: info.script.id.toString(),
179177
version: null,
180178
},
181179
edits: sfcEdits,

0 commit comments

Comments
 (0)