Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions packages/language-core/lib/languagePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export function createVueLanguagePlugin<T>(
createVirtualCode(scriptId, languageId, snapshot) {
const fileName = asFileName(scriptId);
if (plugins.some(plugin => plugin.isValidFile?.(fileName, languageId))) {
const code = fileRegistry.get(fileName);
const code = fileRegistry.get(String(scriptId));
if (code) {
code.update(snapshot);
return code;
Expand All @@ -74,7 +74,7 @@ export function createVueLanguagePlugin<T>(
plugins,
ts,
);
fileRegistry.set(fileName, code);
fileRegistry.set(String(scriptId), code);
return code;
}
}
Expand All @@ -84,8 +84,7 @@ export function createVueLanguagePlugin<T>(
return code;
},
disposeVirtualCode(scriptId) {
const fileName = asFileName(scriptId);
fileRegistry.delete(fileName);
fileRegistry.delete(String(scriptId));
},
typescript: {
extraFileExtensions: getAllExtensions(vueCompilerOptions)
Expand Down
49 changes: 49 additions & 0 deletions packages/language-server/tests/semanticTokens.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import type { TextDocument } from '@volar/language-server';
import { afterEach, expect, test } from 'vitest';
import { URI } from 'vscode-uri';
import { getLanguageServer, testWorkspacePath } from './server.js';

const openedDocuments: TextDocument[] = [];

afterEach(async () => {
const server = await getLanguageServer();
for (const document of openedDocuments) {
await server.close(document.uri);
}
openedDocuments.length = 0;
});

test('#5572 semantic tokens stay in sync when a git view is opened', async () => {
const server = await getLanguageServer();
const fileContent = `
<script setup lang="ts">
defineProps({
foo: { type: String },
});
</script>
`;
const fileUri = URI.file(`${testWorkspacePath}/semanticTokens.vue`);

const document = await prepareDocument(fileUri, 'vue', fileContent);
const tokensBefore = (await server.vueserver.sendSemanticTokensRequest(document.uri))!.data;

// simlulate open git diff view
const gitUri = URI.from({ scheme: 'git', path: fileUri.path });
await prepareDocument(gitUri, 'vue', fileContent.replace('foo', 'fooooooo'));

const tokensAfter = (await server.vueserver.sendSemanticTokensRequest(document.uri))!.data;

expect(tokensAfter).toEqual(tokensBefore);
});

async function prepareDocument(uriOrFileName: string | URI, languageId: string, content: string) {
const server = await getLanguageServer();
const uri = typeof uriOrFileName === 'string'
? URI.file(`${testWorkspacePath}/${uriOrFileName}`)
: uriOrFileName;
const document = await server.open(uri.toString(), languageId, content);
if (openedDocuments.every(d => d.uri !== document.uri)) {
openedDocuments.push(document);
}
return document;
}
66 changes: 35 additions & 31 deletions packages/language-server/tests/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,40 +69,44 @@ export async function getLanguageServer(): Promise<{
vueserver: serverHandle,
tsserver: tsserver,
nextSeq: () => seq++,
open: async (uri: string, languageId: string, content: string) => {
const res = await tsserver.message({
seq: seq++,
type: 'request',
command: 'updateOpen',
arguments: {
changedFiles: [],
closedFiles: [],
openFiles: [
{
file: URI.parse(uri).fsPath,
fileContent: content,
},
],
},
});
if (!res.success) {
throw new Error(res.body);
open: async (uri, languageId, content) => {
if (uri.startsWith('file://')) {
const res = await tsserver.message({
seq: seq++,
type: 'request',
command: 'updateOpen',
arguments: {
changedFiles: [],
closedFiles: [],
openFiles: [
{
file: URI.parse(uri).fsPath,
fileContent: content,
},
],
},
});
if (!res.success) {
throw new Error(res.body);
}
}
return await serverHandle!.openInMemoryDocument(uri, languageId, content);
},
close: async (uri: string) => {
const res = await tsserver.message({
seq: seq++,
type: 'request',
command: 'updateOpen',
arguments: {
changedFiles: [],
closedFiles: [URI.parse(uri).fsPath],
openFiles: [],
},
});
if (!res.success) {
throw new Error(res.body);
close: async uri => {
if (uri.startsWith('file://')) {
const res = await tsserver.message({
seq: seq++,
type: 'request',
command: 'updateOpen',
arguments: {
changedFiles: [],
closedFiles: [URI.parse(uri).fsPath],
openFiles: [],
},
});
if (!res.success) {
throw new Error(res.body);
}
}
await serverHandle!.closeTextDocument(uri);
},
Expand Down