227 lines
9.4 KiB
Plaintext
227 lines
9.4 KiB
Plaintext
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.startCommonLanguageServer = void 0;
|
|
const index_js_1 = require("@volar/language-service/index.js");
|
|
const l10n = require("@vscode/l10n");
|
|
const vscode = require("vscode-languageserver");
|
|
const vscode_uri_1 = require("vscode-uri");
|
|
const types_js_1 = require("../types.js");
|
|
const configurationHost_js_1 = require("./configurationHost.js");
|
|
const documents_js_1 = require("./documents.js");
|
|
const registerFeatures_js_1 = require("./utils/registerFeatures.js");
|
|
const serverConfig_js_1 = require("./utils/serverConfig.js");
|
|
const workspaces_js_1 = require("./workspaces.js");
|
|
const request_light_1 = require("request-light");
|
|
function startCommonLanguageServer(connection, _plugins, getRuntimeEnv) {
|
|
let initParams;
|
|
let options;
|
|
let roots = [];
|
|
let workspaces;
|
|
let plugins;
|
|
let documents;
|
|
let context;
|
|
let ts;
|
|
let tsLocalized;
|
|
const didChangeWatchedFilesCallbacks = new Set();
|
|
connection.onInitialize(async (_params) => {
|
|
initParams = _params;
|
|
options = initParams.initializationOptions;
|
|
const env = getRuntimeEnv(initParams, options);
|
|
context = {
|
|
server: {
|
|
initializeParams: initParams,
|
|
connection,
|
|
runtimeEnv: {
|
|
...env,
|
|
fs: createFsWithCache(env.fs),
|
|
},
|
|
plugins: _plugins,
|
|
configurationHost: initParams.capabilities.workspace?.configuration ? (0, configurationHost_js_1.createConfigurationHost)(initParams, connection) : undefined,
|
|
onDidChangeWatchedFiles: cb => {
|
|
didChangeWatchedFilesCallbacks.add(cb);
|
|
return {
|
|
dispose: () => {
|
|
didChangeWatchedFilesCallbacks.delete(cb);
|
|
},
|
|
};
|
|
},
|
|
},
|
|
};
|
|
ts = await context.server.runtimeEnv.loadTypeScript(options);
|
|
tsLocalized = initParams.locale
|
|
? await context.server.runtimeEnv.loadTypeScriptLocalized(options, initParams.locale)
|
|
: undefined;
|
|
plugins = context.server.plugins.map(plugin => plugin(options, { typescript: ts }));
|
|
documents = (0, documents_js_1.createDocuments)(context.server.runtimeEnv, connection);
|
|
if (options.l10n) {
|
|
await l10n.config({ uri: options.l10n.location });
|
|
}
|
|
if (initParams.capabilities.workspace?.workspaceFolders && initParams.workspaceFolders) {
|
|
roots = initParams.workspaceFolders.map(folder => vscode_uri_1.URI.parse(folder.uri));
|
|
}
|
|
else if (initParams.rootUri) {
|
|
roots = [vscode_uri_1.URI.parse(initParams.rootUri)];
|
|
}
|
|
else if (initParams.rootPath) {
|
|
roots = [vscode_uri_1.URI.file(initParams.rootPath)];
|
|
}
|
|
const result = {
|
|
capabilities: {
|
|
textDocumentSync: vscode.TextDocumentSyncKind.Incremental,
|
|
workspace: {
|
|
// #18
|
|
workspaceFolders: {
|
|
supported: true,
|
|
changeNotifications: true,
|
|
},
|
|
},
|
|
},
|
|
};
|
|
let config = {};
|
|
for (const root of roots) {
|
|
if (root.scheme === 'file') {
|
|
const workspaceConfig = (0, serverConfig_js_1.loadConfig)(env.console, root.path, options.configFilePath);
|
|
if (workspaceConfig) {
|
|
config = workspaceConfig;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
for (const plugin of plugins) {
|
|
if (plugin.resolveConfig) {
|
|
config = await plugin.resolveConfig(config, undefined);
|
|
}
|
|
}
|
|
(0, registerFeatures_js_1.setupCapabilities)(result.capabilities, options, plugins, getSemanticTokensLegend(), config.services ?? {});
|
|
await createLanguageServiceHost();
|
|
try {
|
|
// show version on LSP logs
|
|
const packageJson = require('../package.json');
|
|
result.serverInfo = {
|
|
name: packageJson.name,
|
|
version: packageJson.version,
|
|
};
|
|
}
|
|
catch { }
|
|
return result;
|
|
});
|
|
connection.onInitialized(async () => {
|
|
context.server.configurationHost?.ready();
|
|
context.server.configurationHost?.onDidChangeConfiguration?.(updateHttpSettings);
|
|
updateHttpSettings();
|
|
if (initParams.capabilities.workspace?.workspaceFolders) {
|
|
connection.workspace.onDidChangeWorkspaceFolders(e => {
|
|
for (const folder of e.added) {
|
|
workspaces?.add(vscode_uri_1.URI.parse(folder.uri));
|
|
}
|
|
for (const folder of e.removed) {
|
|
workspaces?.remove(vscode_uri_1.URI.parse(folder.uri));
|
|
}
|
|
});
|
|
}
|
|
if (options.serverMode !== types_js_1.ServerMode.Syntactic
|
|
&& initParams.capabilities.workspace?.didChangeWatchedFiles?.dynamicRegistration) {
|
|
const exts = plugins.map(plugin => plugin.watchFileExtensions).flat();
|
|
if (exts.length) {
|
|
connection.client.register(vscode.DidChangeWatchedFilesNotification.type, {
|
|
watchers: [
|
|
{
|
|
globPattern: `**/*.{${exts.join(',')}}`
|
|
},
|
|
]
|
|
});
|
|
connection.onDidChangeWatchedFiles(e => {
|
|
for (const cb of didChangeWatchedFilesCallbacks) {
|
|
cb(e);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
async function updateHttpSettings() {
|
|
const httpSettings = await context.server.configurationHost?.getConfiguration?.('http');
|
|
(0, request_light_1.configure)(httpSettings?.proxy, httpSettings?.proxyStrictSSL ?? false);
|
|
}
|
|
});
|
|
connection.onShutdown(async () => {
|
|
workspaces?.reloadProjects();
|
|
});
|
|
connection.listen();
|
|
function createFsWithCache(fs) {
|
|
const readFileCache = new Map();
|
|
const statCache = new Map();
|
|
const readDirectoryCache = new Map();
|
|
didChangeWatchedFilesCallbacks.add(({ changes }) => {
|
|
for (const change of changes) {
|
|
if (change.type === vscode.FileChangeType.Deleted) {
|
|
readFileCache.set(change.uri, undefined);
|
|
statCache.set(change.uri, undefined);
|
|
const dir = change.uri.substring(0, change.uri.lastIndexOf('/'));
|
|
readDirectoryCache.delete(dir);
|
|
}
|
|
else if (change.type === vscode.FileChangeType.Changed) {
|
|
readFileCache.delete(change.uri);
|
|
statCache.delete(change.uri);
|
|
}
|
|
else if (change.type === vscode.FileChangeType.Created) {
|
|
readFileCache.delete(change.uri);
|
|
statCache.delete(change.uri);
|
|
const dir = change.uri.substring(0, change.uri.lastIndexOf('/'));
|
|
readDirectoryCache.delete(dir);
|
|
}
|
|
}
|
|
});
|
|
return {
|
|
readFile: uri => {
|
|
if (!readFileCache.has(uri)) {
|
|
readFileCache.set(uri, fs.readFile(uri));
|
|
}
|
|
return readFileCache.get(uri);
|
|
},
|
|
stat: uri => {
|
|
if (!statCache.has(uri)) {
|
|
statCache.set(uri, fs.stat(uri));
|
|
}
|
|
return statCache.get(uri);
|
|
},
|
|
readDirectory: uri => {
|
|
if (!readDirectoryCache.has(uri)) {
|
|
readDirectoryCache.set(uri, fs.readDirectory(uri));
|
|
}
|
|
return readDirectoryCache.get(uri);
|
|
},
|
|
};
|
|
}
|
|
async function createLanguageServiceHost() {
|
|
workspaces = (0, workspaces_js_1.createWorkspaces)({
|
|
...context,
|
|
workspaces: {
|
|
ts,
|
|
tsLocalized,
|
|
initParams,
|
|
initOptions: options,
|
|
documents,
|
|
plugins,
|
|
},
|
|
}, roots);
|
|
(await import('./features/customFeatures.js')).register(connection, workspaces, context.server.runtimeEnv);
|
|
(await import('./features/languageFeatures.js')).register(connection, workspaces, initParams, options, getSemanticTokensLegend(), context.server.runtimeEnv, documents);
|
|
for (const plugin of plugins) {
|
|
plugin.onInitialized?.(getLanguageService, context.server.runtimeEnv);
|
|
}
|
|
async function getLanguageService(uri) {
|
|
const project = (await workspaces.getProject(uri))?.project;
|
|
return project?.getLanguageService();
|
|
}
|
|
}
|
|
function getSemanticTokensLegend() {
|
|
if (!options.semanticTokensLegend) {
|
|
return index_js_1.standardSemanticTokensLegend;
|
|
}
|
|
return {
|
|
tokenTypes: [...index_js_1.standardSemanticTokensLegend.tokenTypes, ...options.semanticTokensLegend.tokenTypes],
|
|
tokenModifiers: [...index_js_1.standardSemanticTokensLegend.tokenModifiers, ...options.semanticTokensLegend.tokenModifiers],
|
|
};
|
|
}
|
|
}
|
|
exports.startCommonLanguageServer = startCommonLanguageServer;
|
|
//# sourceMappingURL=server.js.map |