Skip to content

Commit

Permalink
refactor(language-server): reorganize the code structure (#4507)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Jun 26, 2024
1 parent 4a295b6 commit 0fc957e
Show file tree
Hide file tree
Showing 28 changed files with 549 additions and 506 deletions.
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

0 comments on commit 0fc957e

Please sign in to comment.