Skip to content

Commit

Permalink
refactor: abstract semanticService and syntacticService (#2273)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnsoncodehk committed Jan 3, 2023
1 parent 74f6d33 commit cda8551
Show file tree
Hide file tree
Showing 32 changed files with 402 additions and 892 deletions.
35 changes: 10 additions & 25 deletions examples/angular-language-server/src/index.ts
Expand Up @@ -5,32 +5,17 @@ import type { LanguageServicePlugin, DocumentsAndSourceMaps, Diagnostic } from '

const plugin: LanguageServerPlugin = () => ({
extraFileExtensions: [{ extension: 'html', isMixedContent: true, scriptKind: 7 }],
semanticService: {
getLanguageModules(host) {
return [
createTsLanguageModule(host.getTypeScriptModule()),
createHtmlLanguageModule(host.getTypeScriptModule()),
];
},
getServicePlugins(_host, service) {
return [
createTsPlugin(),
createNgTemplateLsPlugin(service.context.documents),
];
},
getLanguageModules(host) {
return [
createTsLanguageModule(host.getTypeScriptModule()),
createHtmlLanguageModule(host.getTypeScriptModule()),
];
},
syntacticService: {
getLanguageModules(ts) {
return [
createTsLanguageModule(ts),
createHtmlLanguageModule(ts),
];
},
getServicePlugins() {
return [
createTsPlugin(),
];
}
getServicePlugins(_host, service) {
return [
createTsPlugin(),
createNgTemplateLsPlugin(service.context.documents),
];
},
});

Expand Down
76 changes: 25 additions & 51 deletions examples/vue-and-svelte-language-server/src/index.ts
@@ -1,6 +1,6 @@
import { languageModule as svelteLanguageModule } from '@volar-examples/svelte-language-core';
import useTsPlugin from '@volar-plugins/typescript';
import { createLanguageServer, LanguageModule, LanguageServerInitializationOptions, LanguageServerPlugin } from '@volar/language-server/node';
import { createLanguageServer, LanguageServerInitializationOptions, LanguageServerPlugin } from '@volar/language-server/node';
import * as vue from '@volar/vue-language-core';

const plugin: LanguageServerPlugin<LanguageServerInitializationOptions, vue.LanguageServiceHost> = () => {
Expand All @@ -9,57 +9,31 @@ const plugin: LanguageServerPlugin<LanguageServerInitializationOptions, vue.Lang
{ extension: 'vue', isMixedContent: true, scriptKind: 7 },
{ extension: 'svelte', isMixedContent: true, scriptKind: 7 },
],
semanticService: {
resolveLanguageServiceHost(ts, sys, tsConfig, host) {
let vueOptions: vue.VueCompilerOptions = {};
if (typeof tsConfig === 'string') {
vueOptions = vue.createParsedCommandLine(ts, sys, tsConfig, []).vueOptions;
}
return {
...host,
getVueCompilationSettings: () => vueOptions,
};
},
getLanguageModules(host) {
const vueLanguageModules = vue.createLanguageModules(
host.getTypeScriptModule(),
host.getCompilationSettings(),
host.getVueCompilationSettings(),
);
return [
...vueLanguageModules,
svelteLanguageModule,
];
},
getServicePlugins() {
return [
useTsPlugin(),
];
},
},
syntacticService: {
getLanguageModules(ts) {
const vueLanguagePlugins = vue.getDefaultVueLanguagePlugins(ts, {}, {});
const vueLanguageModule: LanguageModule = {
createFile(fileName, snapshot) {
if (fileName.endsWith('.vue')) {
return new vue.VueFile(fileName, snapshot, ts, vueLanguagePlugins);
}
},
updateFile(sourceFile: vue.VueFile, snapshot) {
sourceFile.update(snapshot);
},
};
return [
vueLanguageModule,
svelteLanguageModule,
];
},
getServicePlugins() {
return [
useTsPlugin(),
];
resolveLanguageServiceHost(ts, sys, tsConfig, host) {
let vueOptions: vue.VueCompilerOptions = {};
if (typeof tsConfig === 'string') {
vueOptions = vue.createParsedCommandLine(ts, sys, tsConfig, []).vueOptions;
}
return {
...host,
getVueCompilationSettings: () => vueOptions,
};
},
getLanguageModules(host) {
const vueLanguageModules = vue.createLanguageModules(
host.getTypeScriptModule(),
host.getCompilationSettings(),
host.getVueCompilationSettings(),
);
return [
...vueLanguageModules,
svelteLanguageModule,
];
},
getServicePlugins() {
return [
useTsPlugin(),
];
},
};
};
Expand Down
2 changes: 1 addition & 1 deletion extensions/vscode-vue-language-features/src/common.ts
Expand Up @@ -306,7 +306,7 @@ function getInitializationOptions(
configFilePath: vscode.workspace.getConfiguration('volar').get<string>('vueserver.configFilePath'),
respectClientCapabilities: true,
serverMode,
diagnosticModel: diagnosticModel() === 'pull' ? DiagnosticModel.Pull : DiagnosticModel.Push,
diagnosticModel: serverMode === ServerMode.Syntactic ? DiagnosticModel.None : diagnosticModel() === 'pull' ? DiagnosticModel.Pull : DiagnosticModel.Push,
textDocumentSync: textDocumentSync ? {
incremental: lsp.TextDocumentSyncKind.Incremental,
full: lsp.TextDocumentSyncKind.Full,
Expand Down
69 changes: 0 additions & 69 deletions packages/language-server/src/common/features/documentFeatures.ts

This file was deleted.

46 changes: 46 additions & 0 deletions packages/language-server/src/common/features/languageFeatures.ts
Expand Up @@ -19,6 +19,52 @@ export function register(
let lastCodeActionLs: embedded.LanguageService;
let lastCallHierarchyLs: embedded.LanguageService;

connection.onDocumentFormatting(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.format(params.textDocument.uri, params.options);
});
});
connection.onDocumentRangeFormatting(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.format(params.textDocument.uri, params.options, params.range);
});
});
connection.onDocumentOnTypeFormatting(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.format(params.textDocument.uri, params.options, undefined, params);
});
});
connection.onSelectionRanges(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.getSelectionRanges(params.textDocument.uri, params.positions);
});
});
connection.onFoldingRanges(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.getFoldingRanges(params.textDocument.uri);
});
});
connection.languages.onLinkedEditingRange(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.findLinkedEditingRanges(params.textDocument.uri, params.position);
});
});
connection.onDocumentSymbol(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.findDocumentSymbols(params.textDocument.uri);
});
});
connection.onDocumentColor(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.findDocumentColors(params.textDocument.uri);
});
});
connection.onColorPresentation(async params => {
return worker(params.textDocument.uri, vueLs => {
return vueLs.getColorPresentations(params.textDocument.uri, params.color, params.range);
});
});

connection.onCompletion(async (params) => {
return worker(params.textDocument.uri, async vueLs => {
lastCompleteUri = params.textDocument.uri;
Expand Down
23 changes: 17 additions & 6 deletions packages/language-server/src/common/project.ts
Expand Up @@ -6,7 +6,7 @@ import type * as ts from 'typescript/lib/tsserverlibrary';
import * as html from 'vscode-html-languageservice';
import * as vscode from 'vscode-languageserver';
import { URI } from 'vscode-uri';
import { FileSystem, LanguageServerPlugin } from '../types';
import { FileSystem, LanguageServerPlugin, ServerMode } from '../types';
import { createUriMap } from './utils/uriMap';
import { WorkspaceContext } from './workspace';
import { ServerConfig } from './utils/serverConfig';
Expand All @@ -23,7 +23,18 @@ export type Project = ReturnType<typeof createProject>;

export async function createProject(context: ProjectContext) {

const sys = context.workspace.workspaces.fileSystemHost.getWorkspaceFileSystem(context.rootUri);
const sys: FileSystem = context.workspace.workspaces.initOptions.serverMode === ServerMode.Syntactic
? {
newLine: '\n',
useCaseSensitiveFileNames: false,
fileExists: () => false,
readFile: () => undefined,
readDirectory: () => [],
getCurrentDirectory: () => '',
realpath: () => '',
resolvePath: () => '',
}
: context.workspace.workspaces.fileSystemHost.getWorkspaceFileSystem(context.rootUri);

let typeRootVersion = 0;
let projectVersion = 0;
Expand Down Expand Up @@ -66,15 +77,15 @@ export async function createProject(context: ProjectContext) {
function getLanguageService() {
if (!languageService) {

const languageModules = context.workspace.workspaces.plugins.map(plugin => plugin.semanticService?.getLanguageModules?.(languageServiceHost) ?? []).flat();
const languageModules = context.workspace.workspaces.plugins.map(plugin => plugin.getLanguageModules?.(languageServiceHost) ?? []).flat();
const languageContext = embedded.createLanguageContext(languageServiceHost, languageModules);
const languageServiceContext = embeddedLS.createLanguageServiceContext({
host: languageServiceHost,
context: languageContext,
getPlugins() {
return [
...context.serverConfig?.plugins ?? [],
...context.workspace.workspaces.plugins.map(plugin => plugin.semanticService?.getServicePlugins?.(languageServiceHost, languageService!) ?? []).flat(),
...context.workspace.workspaces.plugins.map(plugin => plugin.getServicePlugins?.(languageServiceHost, languageService!) ?? []).flat(),
];
},
env: {
Expand Down Expand Up @@ -189,8 +200,8 @@ export async function createProject(context: ProjectContext) {
}

for (const plugin of context.workspace.workspaces.plugins) {
if (plugin.semanticService?.resolveLanguageServiceHost) {
host = plugin.semanticService.resolveLanguageServiceHost(context.workspace.workspaces.ts, sys, context.tsConfig, host);
if (plugin.resolveLanguageServiceHost) {
host = plugin.resolveLanguageServiceHost(context.workspace.workspaces.ts, sys, context.tsConfig, host);
}
}

Expand Down

0 comments on commit cda8551

Please sign in to comment.