Split language server into two modules

This commit is contained in:
Christopher Schleiden
2022-12-07 18:56:57 -08:00
parent e7ac43a4b6
commit d34fe648d4
2 changed files with 119 additions and 110 deletions
+115
View File
@@ -0,0 +1,115 @@
import { hover } from "@github/actions-languageservice/hover";
import { registerLogger, setLogLevel } from "@github/actions-languageservice/log";
import { validate } from "@github/actions-languageservice/validate";
import {
CompletionItem,
Connection,
Hover,
HoverParams,
InitializeParams,
InitializeResult,
TextDocumentPositionParams,
TextDocuments,
TextDocumentSyncKind
} from "vscode-languageserver";
import { TextDocument } from "vscode-languageserver-textdocument";
import { contextProviders } from "./context-providers";
import { InitializationOptions, RepositoryContext } from "./initializationOptions";
import { onCompletion } from "./on-completion";
import { TTLCache } from "./utils/cache";
import { valueProviders } from "./value-providers";
export function initConnection(connection: Connection) {
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
let sessionToken: string | undefined;
let repos: RepositoryContext[] = [];
const cache = new TTLCache();
let hasWorkspaceFolderCapability = false;
let hasDiagnosticRelatedInformationCapability = false;
// Register remote console logger with language service
registerLogger(connection.console);
connection.onInitialize((params: InitializeParams) => {
const capabilities = params.capabilities;
hasWorkspaceFolderCapability = !!(capabilities.workspace && !!capabilities.workspace.workspaceFolders);
hasDiagnosticRelatedInformationCapability = !!(
capabilities.textDocument &&
capabilities.textDocument.publishDiagnostics &&
capabilities.textDocument.publishDiagnostics.relatedInformation
);
const options: InitializationOptions = params.initializationOptions;
sessionToken = options.sessionToken;
if (options.repos) {
repos = options.repos;
}
if (options.logLevel !== undefined) {
setLogLevel(options.logLevel);
}
const result: InitializeResult = {
capabilities: {
textDocumentSync: TextDocumentSyncKind.Full,
completionProvider: {
resolveProvider: false,
triggerCharacters: [":", "."]
},
hoverProvider: true
}
};
if (hasWorkspaceFolderCapability) {
result.capabilities.workspace = {
workspaceFolders: {
supported: true
}
};
}
return result;
});
// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
documents.onDidChangeContent(change => {
validateTextDocument(change.document);
});
async function validateTextDocument(textDocument: TextDocument): Promise<void> {
const repoContext = repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri));
const result = await validate(
textDocument,
valueProviders(sessionToken, repoContext, cache),
contextProviders(sessionToken, repoContext, cache)
);
connection.sendDiagnostics({uri: textDocument.uri, diagnostics: result});
}
// This handler provides the initial list of the completion items.
connection.onCompletion(async ({position, textDocument}: TextDocumentPositionParams): Promise<CompletionItem[]> => {
return await onCompletion(
position,
documents.get(textDocument.uri)!,
sessionToken,
repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri)),
cache
);
});
connection.onHover(async ({position, textDocument}: HoverParams): Promise<Hover | null> => {
return hover(documents.get(textDocument.uri)!, position);
});
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
// Listen on the connection
connection.listen();
}
+4 -110
View File
@@ -1,113 +1,7 @@
import {
CompletionItem,
createConnection,
Hover,
HoverParams,
InitializeParams,
InitializeResult,
TextDocumentPositionParams,
TextDocuments,
TextDocumentSyncKind
} from "vscode-languageserver/node";
import {createConnection} from "vscode-languageserver/node";
import {hover, registerLogger, setLogLevel, validate} from "@github/actions-languageservice";
import {TextDocument} from "vscode-languageserver-textdocument";
import {contextProviders} from "./context-providers";
import {InitializationOptions, RepositoryContext} from "./initializationOptions";
import {onCompletion} from "./on-completion";
import {TTLCache} from "./utils/cache";
import {valueProviders} from "./value-providers";
import {initConnection} from "./connection";
// By default create node connection
const connection = createConnection();
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
let sessionToken: string | undefined;
let repos: RepositoryContext[] = [];
const cache = new TTLCache();
let hasWorkspaceFolderCapability = false;
let hasDiagnosticRelatedInformationCapability = false;
// Register remote console logger with language service
registerLogger(connection.console);
connection.onInitialize((params: InitializeParams) => {
const capabilities = params.capabilities;
hasWorkspaceFolderCapability = !!(capabilities.workspace && !!capabilities.workspace.workspaceFolders);
hasDiagnosticRelatedInformationCapability = !!(
capabilities.textDocument &&
capabilities.textDocument.publishDiagnostics &&
capabilities.textDocument.publishDiagnostics.relatedInformation
);
const options: InitializationOptions = params.initializationOptions;
sessionToken = options.sessionToken;
if (options.repos) {
repos = options.repos;
}
if (options.logLevel !== undefined) {
setLogLevel(options.logLevel);
}
const result: InitializeResult = {
capabilities: {
textDocumentSync: TextDocumentSyncKind.Full,
completionProvider: {
resolveProvider: false,
triggerCharacters: [":", "."]
},
hoverProvider: true
}
};
if (hasWorkspaceFolderCapability) {
result.capabilities.workspace = {
workspaceFolders: {
supported: true
}
};
}
return result;
});
// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
documents.onDidChangeContent(change => {
validateTextDocument(change.document);
});
async function validateTextDocument(textDocument: TextDocument): Promise<void> {
const repoContext = repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri));
const result = await validate(
textDocument,
valueProviders(sessionToken, repoContext, cache),
contextProviders(sessionToken, repoContext, cache)
);
connection.sendDiagnostics({uri: textDocument.uri, diagnostics: result});
}
// This handler provides the initial list of the completion items.
connection.onCompletion(async ({position, textDocument}: TextDocumentPositionParams): Promise<CompletionItem[]> => {
return await onCompletion(
position,
documents.get(textDocument.uri)!,
sessionToken,
repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri)),
cache
);
});
connection.onHover(async ({position, textDocument}: HoverParams): Promise<Hover | null> => {
return hover(documents.get(textDocument.uri)!, position);
});
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
// Listen on the connection
connection.listen();
initConnection(connection);