From e1e0a265e931637f452ac05bb7d912e07bcee574 Mon Sep 17 00:00:00 2001 From: zinc Date: Thu, 15 Oct 2026 10:11:56 +0330 Subject: lsp: borrow errors ranged on the use, with related information for where the owner ended and was declared; vscode client passes relatedInformation through --- src/lsp/server.zc | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'src/lsp') diff --git a/src/lsp/server.zc b/src/lsp/server.zc index 6f4ce67..65881a9 100644 --- a/src/lsp/server.zc +++ b/src/lsp/server.zc @@ -258,6 +258,35 @@ int wpos(int off) { wc('}'); return 0; } +// a packed compiler place (tpack) as an lsp location in document gd. +int wplace(int p) { + int o = ((p >> 40) & 0x1FFFFF) - 1, n = (p >> 24) & 0xFFFF; + if (o < 0) o = 0; if (o > plen) o = plen; + if (n < 1) n = 1; if (o + n > plen) n = plen - o; + ws("{\"uri\":"); wjs(duri[gd], dulen[gd]); ws(",\"range\":{\"start\":"); wpos(o); ws(",\"end\":"); wpos(o + n); ws("}}"); + return 0; +} +// the related places the compiler recorded for the record at offset at (run.dg_related): +// where the owner ended and where it was declared, as relatedInformation. +int diag_related(int at) { + int k = 0, why; word e; char* what; + while (k < run.dgreln) { + e = run.dgrel + k * run.DGREL_W; + if (e[0] == at) { + why = e[3]; what = " ended here"; + if (why == 1) what = " was freed here"; else if (why == 2) what = " was given to a .d parameter here"; + else if (why == 3) what = " was moved here"; else if (why == 4) what = " was stored into a container here"; + else if (why == 5) what = " was returned here"; else if (why == 6) what = " was stored in a global here"; + else if (why == 7) what = " was freed by this reassignment"; else if (why == 8) what = " was pushed into an array here"; + ws(",\"relatedInformation\":[{\"location\":"); wplace(e[1]); ws(",\"message\":\"owner "); ws(e[4]); ws(what); ws("\"}"); + if (e[2]) { ws(",{\"location\":"); wplace(e[2]); ws(",\"message\":\"owner "); ws(e[4]); ws(" is declared here\"}"); } + wc(']'); + return 0; + } + k++; + } + return 0; +} // writes the publishDiagnostics message for document gd from dgb. each record // becomes a range (the whole line when the compiler only knew the line), a // severity and its message. @@ -295,6 +324,7 @@ int gen_diag() { ws("{\"range\":{\"start\":"); wpos(o); ws(",\"end\":"); wpos(e); ws("},\"severity\":"); wn(sev); ws(",\"source\":\"zc\",\"message\":"); wjs(dgb + at + 5, n); + diag_related(at); wc('}'); at = at + 5 + n; } -- cgit v1.2.3