language server: reuse the declaration sites and the implementation index across keystrokes #10
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Context
LANGUAGE-SERVER.md section 15 lists what the language server still pays on every keystroke. This issue took the whole list; refinement split it into four pieces, each one PR with its own measurement:
Each PR removes its own bullet from section 15 and writes what it built into the section that owns the topic.
Goal
A keystroke inside a function body no longer rebuilds the declaration sites and the implementation index of the whole program. Today
checkBodiesWithin(compiler/src/semantics/checker/check.trb) callsdeclareSitesfor every module andbuildImplementationsover every module on each overlay run, which is 40 to 70 ms of a 90 to 240 ms keystroke on the files of section 7. The sites and the index of every module whose text did not change come from state kept with the front; only the changed module's part is redone.Design record points (pinned)
refreshedFrontkeeps the symbols' ids and rewrites only the changed file's spans; a front is built from scratch when the outline changed, a document closed, a watched file changed on disk, and after 200 runs. The kept state has the lifetime of the front it was built over: dropped exactly where the front is built from scratch, redone for the changed module where the front is refreshed.Requirements
declareSitesorbuildImplementationsover unchanged modules. The changed module's sites (they hold its syntax nodes, in the coordinates of the current text) and its implementations (theiratspans, thebySpankeys) are built again from the refreshed front.Equals,Showand so on) and counts those added after the run started. It must not leak that into the kept state: the kept state is copied, or the additions are undone, whichever the worker measures to be cheaper. The choice and its cost go into the record.checkTypes,preparedCheckerandtorb check/torb buildbehave exactly as before; only the language server's overlay path changes.Acceptance criteria
compiler/tests/language-server.test.trbobserves it (the run'sTimingentries, or a counter the checker keeps for the test) over a workspace of at least three modules.typewith awithlist, anextend, and calls a trait implementation of another module, the overlay's diagnostics and the resolutions inside the changed body equal those of a checker that builds everything (checkBodiesWithinas it is today), including a body that needs a derived implementation.compiler/tests/language-server.test.trb,tests/lsp/*.expected) pass unchanged.compiler/src/semantics/checker/expression.trb(the largest file of the compiler) the way section 7 measures a keystroke (median of ten keystrokes typing a word into a local of a function in the middle of the file, the workspace check off, the pass timingsdeclaration sitesandthe implementation indexread before and after). The numbers and the method are written into section 7 ("What a keystroke costs") and the first bullet of section 15 is removed. The measurement is taken from a binary the forge CI built, not from a local bootstrap, and it is not a gate (no threshold in a test).skills/, it is regenerated (torb docs skill docs skills, checked by tier A).Seed
No. Compiler code in existing syntax; no new native, no driver flag, no std name looked up by string.
Size and commits
One PR, one or two Conventional Commits:
perf(lsp): reuse the declaration sites and the implementation index across keystrokes, and optionallydocs(lsp): measure a keystroke after the reuse. Tier A (sh tools/gates.sh a) in the forge CI; tier B is not needed (nocompiler/src/ir,backendorruntimechange).Implementer
opus / high:
compiler/src/semantics/checker/and the language server core.Collisions
Touches
compiler/src/semantics/checker/check.trb,compiler/src/semantics/check.trb,compiler/src/language-server/analysis.trbandview.trb. #171 touchesanalysis.trbandserver.trbas well: whichever lands second rebases. #9 (running) adds a checker table undercompiler/src/semantics/checker/; the overlap is at most a neighbouring hunk. #6 and #7 (running) touch runtime, VM and benchmarks, not the language server.[loop:torbscript] intake: in scope (author orion, label loop). Implements LANGUAGE-SERVER.md section 15; design record is the specification, no collision with CONCEPT "Open Questions", no seed impact expected. Five criteria, likely split into several issues in refine. Release freeze for 0.1.0 (2026-10-06) holds new PRs, next: refine (queued, buffer >= 2 ready)
[loop:torbscript] claim refine by session:loop-torbscript-20261008 until 2026-10-08T03:17:22Z
language server: the whole-program work left per keystroketo language server: reuse the declaration sites and the implementation index across keystrokes[loop:torbscript] refine: the five criteria cover four independent pieces, so the issue is split by section 15 bullet: this issue keeps the declaration sites and the implementation index (rewritten with goal, requirements, testable criteria, pinned record points, seed impact: no, one PR with one or two Conventional Commits, implementer opus/high), and #170 (semantic tokens), #171 (first check of a document in slices) and #172 (rename checks once, depends on #171) carry the rest, each ready with its own measurement on the largest compiler file. No owner question: all four stay inside the design record (no protocol addition, no breaking change, no seed change). Collisions: #10 and #171 share analysis.trb and view.trb (second to land rebases); #9 may touch a neighbouring hunk under compiler/src/semantics/checker/; no overlap with #6 and #7. Worker usage ~120000 tokens, next: implement
[loop:torbscript] claim implement by session:loop-torbscript-20261008 until 2026-10-08T07:28:41Z