diff options
| author | 2026-10-14 10:42:28 +0000 | |
|---|---|---|
| committer | 2026-10-14 10:42:28 +0000 | |
| commit | ea052eab91b304459ddf64281fc93fc152597412 (patch) | |
| tree | 8dcd378d6634626dd2529c2aef684890999de963 /src/lsp | |
| parent | todo: the spec verifier restarted from the first agent's partial work (diff) | |
| parent | fix std hover, full capture terminator, bare static calls, void main in run-o... (diff) | |
Merge four small fixes: std hovers, capture terminator, bare static calls, void main; todo updated
Diffstat (limited to 'src/lsp')
| -rw-r--r-- | src/lsp/server.zc | 40 |
1 files changed, 34 insertions, 6 deletions
diff --git a/src/lsp/server.zc b/src/lsp/server.zc index afa8de4..a43f910 100644 --- a/src/lsp/server.zc +++ b/src/lsp/server.zc @@ -1761,6 +1761,12 @@ int hover_method(int i) { if (!found) ls = le + 1; } if (!found) return 0; + return hover_method_at(i, sg); +} +// the markdown of the method whose signature starts at byte sg of document i: the +// signature up to the body, a ; or the end of the line, then the docs above it +int hover_method_at(int i, int sg) { + int base = doff[i], size = dsize[i], k, se; // the signature: up to the body, a ; or the end of the line se = sg; while (se < size && dc(base, se) != 10 && dc(base, se) != '{' && dc(base, se) != ';') se++; @@ -1919,17 +1925,24 @@ int hover_global(int i, int kind) { r = rs_find(hoff); if (r >= 0 && run.rsrec[r * run.RS_W + 1] == run.RS_SYM && run.rsrec[r * run.RS_W + 3] >= 0 && kind != 2) { s = run.rsrec[r * run.RS_W + 3]; - if (run.skind[s] != run.K_KW && bs_find(run.sname[s])) { hover_fill(bs_load(bs_k)); return hn; } + if (run.skind[s] != run.K_KW && bs_find(run.sname[s])) { bs_hover(); return hn; } } if (kind != 2) { kt = kwtext(); if (kt) return kw_put(kt); } - if (kind == 1) { if (bs_find(hname)) { hover_fill(bs_load(bs_k)); return hn; } hover_blob(i); return hn; } + if (kind == 1) { if (bs_find(hname)) { bs_hover(); return hn; } hover_blob(i); return hn; } if (hover_scan(i)) { hover_fill(i); return hn; } if (hover_method(i)) return hn; if (kind == 0 && hover_local(i)) return hn; - if (kind != 2 && bs_find(hname)) { hover_fill(bs_load(bs_k)); return hn; } + if (kind != 2 && bs_find(hname)) { bs_hover(); return hn; } hover_blob(i); return hn; } +// is symbol s declared in an embedded library source (the text of std or icon, included +// from tinyvm:std.zc and tinyvm:icon.zc)? such a symbol is a user symbol to the compiler +// (rs_sym sets 16 for it) but its text is not in the document, so hover looks it up by +// its qualified name in the library source, as it does for the runtime. +int hover_embedded_sym(int s) { + return s >= 0 && run.sdsrc && run.sdsrc[s] && bs_name(run.sdsrc[s]) && bs_source(run.sdsrc[s]) >= 0; +} // the hover at the cursor. the compiler's record of the name decides what it // is: a local is its declaration, a parameter the header that names it, and a // symbol is looked up as that kind of symbol. a name with no record is found by @@ -1950,7 +1963,9 @@ int do_hover(int i) { else if (k == run.RS_FIELD && v >= 0) hover_named(i, v, 4); else if (k == run.RS_LOCAL) hover_local(i); else if (k == run.RS_SYM) { - if ((v & 15) == run.K_GVAR || (v & 15) == run.K_GARR) { + // a symbol from an embedded library source (std, icon) is above the user's symbols but is not in the document: its declaration is found in that source by its qualified name + if ((v & 16) && hover_embedded_sym(run.rsrec[r * run.RS_W + 3])) hover_global(i, 1); + else if ((v & 15) == run.K_GVAR || (v & 15) == run.K_GARR) { s = run.rsrec[r * run.RS_W + 3]; q = 0; o = 0 - 1; while (q < run.rsn) { if (run.rsrec[q * run.RS_W + 3] == s && lt_find(run.rsrec[q * run.RS_W]) >= 0) { o = run.rsrec[q * run.RS_W]; break; } q++; } if (o >= 0) hover_named(i, o, 3); else if (v & 16) hover_global(i, 2); else hover_global(i, 1); @@ -2261,16 +2276,29 @@ int bs_method(int dd, char* name, int dot) { } return 0 - 1; } +// did the last bs_find_in hit find a method of a struct (bs_off is its name), not a top-level declaration +int bs_meth; +// the hover of the declaration the last successful bs_find found: a method by its line, anything else +// by the scan that found it +int bs_hover() { + int dd = bs_load(bs_k), q; + if (!bs_meth) return hover_fill(dd); + q = bs_off; + while (q > 0 && dc(doff[dd], q - 1) != 10) q--; + while (q < bs_off && (dc(doff[dd], q) == 32 || dc(doff[dd], q) == 9)) q++; + hn = 0; hover_method_at(dd, q); + return hn; +} // locate a declaration inside one source, after removing its module prefix. int bs_find_in(int k, char* name) { int n = 0, dot = -1, o, dd = bs_load(k); while (name[n]) { if (name[n] == '.' && dot < 0) dot = n; n++; } if (dot > 0 && name[dot + 1]) { o = bs_method(dd, name, dot); - if (o >= 0) { bs_k = k; bs_off = o; return 1; } + if (o >= 0) { bs_k = k; bs_off = o; bs_meth = 1; return 1; } } else if (dot < 0) { set_hname(name); - if (hover_scan(dd)) { bs_k = k; bs_off = decl_off(doff[dd], hdl, hdle); return 1; } + if (hover_scan(dd)) { bs_k = k; bs_off = decl_off(doff[dd], hdl, hdle); bs_meth = 0; return 1; } } return 0; } |
