From 11e7c303e3c07562e3b3136ee8621fdfb810b08f Mon Sep 17 00:00:00 2001 From: Andre Henriques Date: Tue, 26 Dec 2023 20:01:14 +0000 Subject: [PATCH] More work on the lsp --- index.ts | 4 ++-- lsp.ts | 41 ++++++++++++++++++++++++++++++-- parser.ts | 71 ++++++++++++++++++++++++++++++------------------------- 3 files changed, 80 insertions(+), 36 deletions(-) diff --git a/index.ts b/index.ts index 816b1ef..1b5060b 100644 --- a/index.ts +++ b/index.ts @@ -1,6 +1,6 @@ import fs from 'fs'; import process from 'process'; -import { getDiagnostics, parseLsp } from './parser'; +import { diagnosticsRequests, getDiagnostics, parseLsp } from './parser'; if (process.argv.length !== 3) { console.log("Please provide only one pass"); @@ -13,4 +13,4 @@ const res = parseLsp(file); fs.writeFileSync('./res', res.text); -console.log(await getDiagnostics(file)); +console.log((await diagnosticsRequests(res)).map(a => a.replacements)); diff --git a/lsp.ts b/lsp.ts index 980f666..4dcd39d 100644 --- a/lsp.ts +++ b/lsp.ts @@ -81,6 +81,16 @@ type TextDocumentDidOpen = RPCRequest & { } } +type TextDocumentCodeAction = RPCRequest & { + method: 'textDocument/codeAction', + params: { + range: Range, + textDocument: { + uri: string, + } + }, +}; + type Position = { line: number, character: number @@ -104,6 +114,8 @@ export enum Severity { Hint = 4, } +const saveRes: Record = { }; + async function handleJSON(req: RPCRequest) { log(`New Message entered: method: ${req.method}`); @@ -119,15 +131,37 @@ async function handleJSON(req: RPCRequest) { return; } + const diags = await getDiagnostics(reqO.params.textDocument.text); + + saveRes[reqO.params.textDocument.uri] = diags; + const params = { uri: reqO.params.textDocument.uri, - diagnostics: (await getDiagnostics(reqO.params.textDocument.text)), + diagnostics: diags.map(a => ({ + message: a.message, + range: a.range, + severity: a.severity, + }) as Dialog), } notifyRPC('textDocument/publishDiagnostics', params); - //error(`TODO ${req.method}`); + } else if (req.method === 'textDocument/codeAction') { + const reqO: TextDocumentCodeAction = req as any; + + const diagRecord = saveRes[reqO.params.textDocument.uri]; + + if (!diagRecord) { + sendRPCMessage(req, [{ + title: "No diagnostics found in this file" + }]); + return; + } + + log(JSON.stringify(req.params)); + + error("TODO handle " + req.method); } else { error(`Handle: ${req.method} after init`); } @@ -145,6 +179,9 @@ async function handleJSON(req: RPCRequest) { // TODO change in the future when the server also checks the ib file as well interFileDependencies: false, workspaceDiagnostics: false, + }, + codeActionProvider: { + codeActionKinds: [ "quickfix" ] } }, serverInfo: { diff --git a/parser.ts b/parser.ts index 1682911..46d0ad7 100644 --- a/parser.ts +++ b/parser.ts @@ -388,11 +388,37 @@ function buildLineIndex(file: string) { } return lineIndex; } +type Match = { + message: string, + shortMessage: string, + offset: number, + length: number, + replacements: { + value: string + }[], + context: { + text: string, + offset: number, + length: number + }, + sentence: string, + rule: { + id: string, + subId: string, + description: string, + urls: { + value: string + }[], + issueType: string, + category: { + id: string, + name: string + } + } +} -export async function getDiagnostics(file: string): Promise { - - const res = parseLsp(file); +export async function diagnosticsRequests(res: ParseResult): Promise < Match[] > { const formData = new URLSearchParams(); formData.set('text', res.text); @@ -414,40 +440,20 @@ export async function getDiagnostics(file: string): Promise { } const body = await rawRes.json(); - type Match = { - message: string, - shortMessage: string, - offset: number, - length: number, - replacements: { - value: string - }[], - context: { - text: string, - offset: number, - length: number - }, - sentence: string, - rule: { - id: string, - subId: string, - description: string, - urls: { - value: string - }[], - issueType: string, - category: { - id: string, - name: string - } - } - } + return body.matches; +} + +export async function getDiagnostics(file: string): Promise<(Dialog & {replacements: string[]})[]> { + + const res = parseLsp(file); + + const matches = await diagnosticsRequests(res); const lineIndex = buildLineIndex(file); const diags = []; - for (const i of body.matches) { + for (const i of matches) { const match: Match = i; const original_position = getOriginalPostion(res, match.offset); if (original_position == -1) { @@ -466,6 +472,7 @@ export async function getDiagnostics(file: string): Promise { range, severity: Severity.Error, message: match.message, + replacements: match.replacements.map(a => a.value), }) }