Skip to content

refactor(language-server): reorganize the code structure #4507

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jun 26, 2024
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
2 changes: 1 addition & 1 deletion extensions/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -543,7 +543,7 @@
"devDependencies": {
"@types/semver": "^7.5.3",
"@types/vscode": "^1.82.0",
"@volar/vscode": "~2.3.4",
"@volar/vscode": "~2.4.0-alpha.0",
"@vue/language-core": "2.0.22",
"@vue/language-server": "2.0.22",
"@vue/typescript-plugin": "2.0.22",
Expand Down
11 changes: 8 additions & 3 deletions extensions/vscode/src/features/doctor.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BaseLanguageClient, getTsdk } from '@volar/vscode';
import { ParseSFCRequest } from '@vue/language-server';
import { BaseLanguageClient, getTsdk, ExecuteCommandRequest, ExecuteCommandParams } from '@volar/vscode';
import { commands, SFCParseResult } from '@vue/language-server';
import * as semver from 'semver';
import * as vscode from 'vscode';
import { config } from '../config';
Expand Down Expand Up @@ -85,7 +85,12 @@ export async function register(context: vscode.ExtensionContext, client: BaseLan
async function getProblems(fileUri: vscode.Uri) {

const vueDoc = vscode.workspace.textDocuments.find(doc => doc.fileName === fileUri.fsPath);
const sfc = await (vueDoc ? client.sendRequest(ParseSFCRequest.type, vueDoc.getText()) : undefined);
const sfc: SFCParseResult = vueDoc
? await client.sendRequest(ExecuteCommandRequest.type, {
command: commands.parseSfc,
arguments: [vueDoc.getText()],
} satisfies ExecuteCommandParams)
: undefined;
const vueMod = getPackageJsonOfWorkspacePackage(fileUri.fsPath, 'vue');
const domMod = getPackageJsonOfWorkspacePackage(fileUri.fsPath, '@vue/runtime-dom');
const problems: {
Expand Down
36 changes: 24 additions & 12 deletions extensions/vscode/src/features/nameCasing.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as vscode from 'vscode';
import { quickPick } from '@volar/vscode/lib/common';
import { BaseLanguageClient, State } from '@volar/vscode';
import { AttrNameCasing, TagNameCasing, DetectNameCasingRequest, GetConvertAttrCasingEditsRequest, GetConvertTagCasingEditsRequest } from '@vue/language-server';
import { BaseLanguageClient, ExecuteCommandParams, ExecuteCommandRequest, State, TextEdit } from '@volar/vscode';
import { AttrNameCasing, TagNameCasing, commands } from '@vue/language-server';
import { config } from '../config';

export const attrNameCasings = new Map<string, AttrNameCasing>();
Expand Down Expand Up @@ -97,10 +97,13 @@ export async function activate(_context: vscode.ExtensionContext, client: BaseLa

async function convertTag(editor: vscode.TextEditor, casing: TagNameCasing) {

const response = await client.sendRequest(GetConvertTagCasingEditsRequest.type, {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
casing,
});
const response: TextEdit[] = await client.sendRequest(ExecuteCommandRequest.type, {
command: casing === TagNameCasing.Kebab
? commands.convertTagsToKebabCase
: commands.convertTagsToPascalCase,
arguments: [client.code2ProtocolConverter.asUri(editor.document.uri)],
} satisfies ExecuteCommandParams);

const edits = await client.protocol2CodeConverter.asTextEdits(response);

if (edits) {
Expand All @@ -117,10 +120,13 @@ export async function activate(_context: vscode.ExtensionContext, client: BaseLa

async function convertAttr(editor: vscode.TextEditor, casing: AttrNameCasing) {

const response = await client.sendRequest(GetConvertAttrCasingEditsRequest.type, {
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(editor.document),
casing,
});
const response: TextEdit[] = await client.sendRequest(ExecuteCommandRequest.type, {
command: casing === AttrNameCasing.Kebab
? commands.convertPropsToKebabCase
: commands.convertPropsToCamelCase,
arguments: [client.code2ProtocolConverter.asUri(editor.document.uri)],
} satisfies ExecuteCommandParams);

const edits = await client.protocol2CodeConverter.asTextEdits(response);

if (edits) {
Expand Down Expand Up @@ -188,8 +194,14 @@ export async function activate(_context: vscode.ExtensionContext, client: BaseLa
}
}

function detect(document: vscode.TextDocument) {
return client.sendRequest(DetectNameCasingRequest.type, { textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document) });
function detect(document: vscode.TextDocument): Promise<{
tag: TagNameCasing[],
attr: AttrNameCasing[],
}> {
return client.sendRequest(ExecuteCommandRequest.type, {
command: commands.detectNameCasing,
arguments: [client.code2ProtocolConverter.asUri(document.uri)],
} satisfies ExecuteCommandParams);
}

function updateStatusBarText() {
Expand Down
18 changes: 12 additions & 6 deletions extensions/vscode/src/features/splitEditors.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { BaseLanguageClient } from '@volar/vscode';
import { ParseSFCRequest } from '@vue/language-server';
import { ExecuteCommandParams, ExecuteCommandRequest, type BaseLanguageClient } from '@volar/vscode';
import { commands, type SFCParseResult } from '@vue/language-server';
import * as vscode from 'vscode';
import { config } from '../config';

type SFCBlock = ParseSFCRequest.ResponseType['descriptor']['customBlocks'][number];
type SFCBlock = SFCParseResult['descriptor']['customBlocks'][number];

export function register(context: vscode.ExtensionContext, client: BaseLanguageClient) {

Expand All @@ -20,7 +20,10 @@ export function register(context: vscode.ExtensionContext, client: BaseLanguageC

const layout = config.splitEditors.layout;
const doc = editor.document;
const { descriptor } = await getDocDescriptor(doc.getText());
const descriptor = (await getDocDescriptor(doc.getText()))?.descriptor;
if (!descriptor) {
return;
}
let leftBlocks: SFCBlock[] = [];
let rightBlocks: SFCBlock[] = [];

Expand Down Expand Up @@ -96,14 +99,17 @@ export function register(context: vscode.ExtensionContext, client: BaseLanguageC
function useDocDescriptor() {

let splitDocText: string | undefined;
let splitDocDescriptor: any;
let splitDocDescriptor: SFCParseResult | undefined;

return getDescriptor;

async function getDescriptor(text: string) {
if (text !== splitDocText) {
splitDocText = text;
splitDocDescriptor = await client.sendRequest(ParseSFCRequest.type, text);
splitDocDescriptor = await client.sendRequest(ExecuteCommandRequest.type, {
command: commands.parseSfc,
arguments: [text],
} satisfies ExecuteCommandParams);
}
return splitDocDescriptor;
}
Expand Down
7 changes: 1 addition & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,9 @@
"@lerna-lite/publish": "latest",
"@tsslint/cli": "latest",
"@tsslint/config": "latest",
"@volar/language-service": "~2.3.4",
"@volar/language-service": "~2.4.0-alpha.0",
"typescript": "latest",
"vite": "latest",
"vitest": "latest"
},
"pnpm": {
"overrides": {
"vscode-html-languageservice": "npm:@johnsoncodehk/vscode-html-languageservice"
}
}
}
3 changes: 3 additions & 0 deletions packages/component-meta/lib/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@ export function baseCreate(
asScriptId: s => s,
...createLanguageServiceHost(ts, ts.sys, language, s => s, projectHost),
};
language.vue = {
compilerOptions: vueCompilerOptions,
};
const { languageServiceHost } = language.typescript;
const tsLs = ts.createLanguageService(languageServiceHost);

Expand Down
2 changes: 1 addition & 1 deletion packages/component-meta/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"directory": "packages/component-meta"
},
"dependencies": {
"@volar/typescript": "~2.3.4",
"@volar/typescript": "~2.4.0-alpha.0",
"@vue/language-core": "2.0.22",
"path-browserify": "^1.0.1",
"vue-component-type-helpers": "2.0.22"
Expand Down
10 changes: 10 additions & 0 deletions packages/language-core/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { VueCompilerOptions } from './lib/types';

export * from './lib/codegen/template';
export * from './lib/languageModule';
export * from './lib/parsers/scriptSetupRanges';
Expand All @@ -13,3 +15,11 @@ export { tsCodegen } from './lib/plugins/vue-tsx';

export * from '@volar/language-core';
export type * as CompilerDOM from '@vue/compiler-dom';

declare module '@volar/language-core' {
export interface Language {
vue?: {
compilerOptions: VueCompilerOptions;
};
}
}
1 change: 1 addition & 0 deletions packages/language-core/lib/languageModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import * as CompilerVue2 from './utils/vue2TemplateCompiler';
import useHtmlFilePlugin from './plugins/file-html';
import useMdFilePlugin from './plugins/file-md';
import useVueFilePlugin from './plugins/file-vue';
import type * as _ from '@volar/typescript';

const normalFileRegistries: {
key: string;
Expand Down
3 changes: 2 additions & 1 deletion packages/language-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"directory": "packages/language-core"
},
"dependencies": {
"@volar/language-core": "~2.3.4",
"@volar/language-core": "~2.4.0-alpha.0",
"@vue/compiler-dom": "^3.4.0",
"@vue/shared": "^3.4.0",
"computeds": "^0.0.1",
Expand All @@ -25,6 +25,7 @@
"@types/minimatch": "^5.1.2",
"@types/node": "latest",
"@types/path-browserify": "^1.0.1",
"@volar/typescript": "~2.4.0-alpha.0",
"@vue/compiler-sfc": "^3.4.0"
},
"peerDependencies": {
Expand Down
4 changes: 2 additions & 2 deletions packages/language-plugin-pug/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"@vue/language-core": "2.0.22"
},
"dependencies": {
"@volar/source-map": "~2.3.4",
"volar-service-pug": "0.0.54"
"@volar/source-map": "~2.4.0-alpha.0",
"volar-service-pug": "0.0.55"
}
}
5 changes: 3 additions & 2 deletions packages/language-server/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
export * from './lib/protocol';
export { commands } from '@vue/language-service';
export * from './lib/types';
export * from './lib/initialize';

// export protocol and types of parent package
export * from '@volar/language-server/protocol';
export * from '@volar/language-server/lib/types';
export * from '@volar/language-server/protocol';

// only export types of depend packages
export * from '@vue/language-service/lib/types';
56 changes: 20 additions & 36 deletions packages/language-server/lib/hybridModeProject.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,24 @@
import type { LanguagePlugin, LanguageServer, LanguageServerProject, ProviderResult } from '@volar/language-server';
import type { Language, LanguagePlugin, LanguageServer, LanguageServerProject, ProviderResult } from '@volar/language-server';
import { createLanguageServiceEnvironment } from '@volar/language-server/lib/project/simpleProject';
import { createLanguage } from '@vue/language-core';
import { Disposable, LanguageService, LanguageServiceEnvironment, createLanguageService, createUriMap } from '@vue/language-service';
import { searchNamedPipeServerForFile, TypeScriptProjectHost } from '@vue/typescript-plugin/lib/utils';
import type * as ts from 'typescript';
import { createLanguageService, createUriMap, LanguageService } from '@vue/language-service';
import { searchNamedPipeServerForFile } from '@vue/typescript-plugin/lib/utils';
import { URI } from 'vscode-uri';

export type GetLanguagePlugin<T> = (params: {
serviceEnv: LanguageServiceEnvironment,
asFileName: (scriptId: T) => string,
configFileName?: string,
projectHost?: TypeScriptProjectHost,
sys?: ts.System & {
version: number;
sync(): Promise<number>;
} & Disposable,
}) => ProviderResult<LanguagePlugin<URI>[]>;

export function createHybridModeProject(
sys: ts.System,
getLanguagePlugins: GetLanguagePlugin<URI>
create: (params: {
configFileName?: string;
asFileName: (scriptId: URI) => string;
}) => ProviderResult<{
languagePlugins: LanguagePlugin<URI>[];
setup?(language: Language): void;
}>
): LanguageServerProject {
let initialized = false;
let simpleLs: Promise<LanguageService> | undefined;
let serviceEnv: LanguageServiceEnvironment | undefined;
let server: LanguageServer;

const tsconfigProjects = createUriMap<Promise<LanguageService>>(sys.useCaseSensitiveFileNames);
const tsconfigProjects = createUriMap<Promise<LanguageService>>();

return {
setup(_server) {
Expand All @@ -44,30 +36,23 @@ export function createHybridModeProject(
const tsconfigUri = URI.file(tsconfig);
if (!tsconfigProjects.has(tsconfigUri)) {
tsconfigProjects.set(tsconfigUri, (async () => {
serviceEnv ??= createLanguageServiceEnvironment(server, [...server.workspaceFolders.keys()]);
const languagePlugins = await getLanguagePlugins({
serviceEnv,
const { languagePlugins, setup } = await create({
configFileName: tsconfig,
sys: {
...sys,
version: 0,
async sync() {
return await 0;
},
dispose() { },
},
asFileName,
});
return createLs(server, serviceEnv, languagePlugins);
const languageService = createLs(server, languagePlugins);
setup?.(languageService.context.language);
return languageService;
})());
}
return await tsconfigProjects.get(tsconfigUri)!;
}
else {
simpleLs ??= (async () => {
serviceEnv ??= createLanguageServiceEnvironment(server, [...server.workspaceFolders.keys()]);
const languagePlugins = await getLanguagePlugins({ serviceEnv, asFileName });
return createLs(server, serviceEnv, languagePlugins);
const { languagePlugins, setup } = await create({ asFileName });
const languageService = createLs(server, languagePlugins);
setup?.(languageService.context.language);
return languageService;
})();
return await simpleLs;
}
Expand Down Expand Up @@ -109,7 +94,6 @@ export function createHybridModeProject(

function createLs(
server: LanguageServer,
serviceEnv: LanguageServiceEnvironment,
languagePlugins: LanguagePlugin<URI>[]
) {
const language = createLanguage([
Expand All @@ -128,7 +112,7 @@ export function createHybridModeProject(
return createLanguageService(
language,
server.languageServicePlugins,
serviceEnv
createLanguageServiceEnvironment(server, [...server.workspaceFolders.keys()])
);
}
}
Loading
Loading