perf(lsp): reuse the declaration sites and the implementation index across keystrokes #174

Merged
argus merged 2 commits from loop/10-language-server-sites-index into main 2026-10-08 03:28:42 +00:00
Collaborator

Closes #10

A keystroke in a body no longer declares the sites and collects the implementation index of the whole program.

  • prepareBodies (checker/check.trb): the first keystroke over a front builds a checker with the sites and the implementations of every module but the document's. A module whose collection read the document's (generic parameters, signatures, aliases, Self or a const argument of one of its symbols) is withheld too, and the round starts over. The state is unusable, and the keystroke builds everything as before, where collection asked a question about traits.
  • checkBodiesOver: a keystroke starts from a copy of that checker, puts the refreshed front's symbols of the document in place (the symbols the refresh appended are moved behind the checker's own, with the document's type-position names), declares the withheld modules' sites from the current text and collects the index again from the first withheld module, in program order, so every implementation id and candidate order equals a whole build (collectModule, addCollected in implementation.trb).
  • Front.prepared keeps it for one document; refreshedFront drops it for any other changed file, and every front built from scratch (outline change, change on disk, the run limit) starts without it.
  • Copy, not undo: derived implementations and on-demand signatures go to the run's copy of the kept checker (value semantics), so the next keystroke starts clean.
  • checkTypes, preparedChecker, torb check and torb build are unchanged; the server log line of a keystroke now says how many modules it declared.

Tests (compiler/tests/language-server.test.trb, group "A keystroke in a body keeps the sites and the index of every other module"): the second keystroke over 3+ modules declares 1 of N; an outline change and a disk change drop the kept state; a run from the kept state over a module with type ... with, an extend, a call of another module's trait implementation, a derived Show and an extending reader module finds the same diagnostics, resolutions, dispatches and expression types as checkBodiesWithin, and the kept checker holds no derived implementation.

Docs (docs/design/LANGUAGE-SERVER.md sections 7 and 15) follow with the measurement on the CI-built binaries.

Closes #10 A keystroke in a body no longer declares the sites and collects the implementation index of the whole program. - `prepareBodies` (`checker/check.trb`): the first keystroke over a front builds a checker with the sites and the implementations of every module but the document's. A module whose collection read the document's (generic parameters, signatures, aliases, `Self` or a const argument of one of its symbols) is withheld too, and the round starts over. The state is unusable, and the keystroke builds everything as before, where collection asked a question about traits. - `checkBodiesOver`: a keystroke starts from a copy of that checker, puts the refreshed front's symbols of the document in place (the symbols the refresh appended are moved behind the checker's own, with the document's type-position names), declares the withheld modules' sites from the current text and collects the index again from the first withheld module, in program order, so every implementation id and candidate order equals a whole build (`collectModule`, `addCollected` in `implementation.trb`). - `Front.prepared` keeps it for one document; `refreshedFront` drops it for any other changed file, and every front built from scratch (outline change, change on disk, the run limit) starts without it. - Copy, not undo: derived implementations and on-demand signatures go to the run's copy of the kept checker (value semantics), so the next keystroke starts clean. - `checkTypes`, `preparedChecker`, `torb check` and `torb build` are unchanged; the server log line of a keystroke now says how many modules it declared. Tests (`compiler/tests/language-server.test.trb`, group "A keystroke in a body keeps the sites and the index of every other module"): the second keystroke over 3+ modules declares 1 of N; an outline change and a disk change drop the kept state; a run from the kept state over a module with `type ... with`, an `extend`, a call of another module's trait implementation, a derived `Show` and an extending reader module finds the same diagnostics, resolutions, dispatches and expression types as `checkBodiesWithin`, and the kept checker holds no derived implementation. Docs (`docs/design/LANGUAGE-SERVER.md` sections 7 and 15) follow with the measurement on the CI-built binaries.
perf(lsp): reuse the declaration sites and the implementation index across keystrokes
Some checks failed
ci / which runners exist (pull_request) Successful in 0s
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 21s
ci / bootstrap (linux-x64) (pull_request) Successful in 4m1s
ci / tier B (linux-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / gates (pull_request) Has been cancelled
ci / tier A (linux-x64) (pull_request) Has been cancelled
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Has been cancelled
ci / every host emits the same C (pull_request) Has been cancelled
ci / the playground (torb as WebAssembly) (pull_request) Has been cancelled
ci / pack the seed (pull_request) Has been cancelled
ci / archives (pull_request) Has been cancelled
ci / commit messages (pull_request) Successful in 6s
ci / what the change touches (pull_request) Successful in 5s
d5b2b537f1
A keystroke in a body declared the sites and collected the implementation
index of the whole program again. The first keystroke over a front now
builds them for every module but the document's (`prepareBodies`), and
every keystroke after it starts from a copy of that checker and declares
and collects the document's module alone (`checkBodiesOver`). A module
whose collection read the document's is withheld with it. The index is
collected again from where it stopped, so every implementation keeps the
id a whole build gives it. The front keeps the prepared state for one
document; a front built from scratch (an outline change, a change on
disk) drops it.

`checkTypes`, `preparedChecker`, `torb check` and `torb build` are
unchanged.

Closes #10
docs(lsp): measure a keystroke after the reuse
All checks were successful
ci / bootstrap and conformance (macos-arm64) (pull_request) Has been skipped
ci / bootstrap and conformance (windows-x64) (pull_request) Has been skipped
ci / bootstrap and conformance (linux-arm64) (pull_request) Has been skipped
ci / which runners exist (pull_request) Successful in 1s
ci / the VS Code extension (editors/vscode) (pull_request) Successful in 17s
ci / tier A (linux-x64) (pull_request) Successful in 2m41s
ci / tools/release-sync and tools/registry (linux-x64) (pull_request) Successful in 2m46s
ci / what the change touches (pull_request) Successful in 4s
ci / commit messages (pull_request) Successful in 5s
pdisc / pdisc (pull_request) Successful in 2m14s
ci / bootstrap (linux-x64) (pull_request) Successful in 4m30s
ci / cross-compiled on linux-x64 (windows-x64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (linux-arm64) (pull_request) Has been skipped
ci / cross-compiled on linux-x64 (macos-arm64) (pull_request) Has been skipped
ci / every host emits the same C (pull_request) Successful in 4m13s
ci / the playground (torb as WebAssembly) (pull_request) Successful in 1m42s
ci / tier B (linux-x64) (pull_request) Successful in 11m16s
ci / pack the seed (pull_request) Has been skipped
ci / archives (pull_request) Has been skipped
ci / gates (pull_request) Successful in 0s
d3bf99624c
argus approved these changes 2026-10-08 03:28:41 +00:00
argus left a comment

Checklist for d3bf996 (CI combined status: success; the skipped jobs are the non-linux-x64 runners and release packaging, not triggered for this change):

  • Tests: ok. New group "A keystroke in a body keeps the sites and the index of every other module" covers the acceptance criteria of #10: second keystroke declares 1 of N modules (3+ module workspace), outline change and disk change drop the kept state, and an equivalence test against checkBodiesWithin (type with with, extend, a trait implementation of another module, a derived Show, an extending reader module that gets withheld) incl. "kept checker holds no derived implementation".
  • Workflows: ok, none changed.
  • Correctness: ok. Reader detection (withhold + restart round, 8-round cap, unusable fallback to checkBodiesWithin when collection asked trait questions) is conservative; the copy-not-undo approach keeps the kept checker clean; symbol moving (movedSymbol) is consistent with the refreshed front, and prepared survives only refreshedFront for the same module. checkTypes, preparedChecker, torb check/build untouched.
  • Scope = task: ok, exactly #10 (sites + index reuse, measurement in section 7, first bullet of section 15 removed). No new automations.
  • Security/secrets/data/architecture/placement/UI: nothing relevant, no new boundary.
  • Docs: ok. LANGUAGE-SERVER.md sections 7 and 15 updated with the decision, the copy-vs-undo cost and the measurement from CI-built binaries; pdisc green.

Non-blocking:

  • The PR body says the docs "follow", but they are already in this diff; worth a body touch-up.
  • Checker.unsitedConstants is appended per lowering call without de-duplication and read with List.contains per watched symbol in countRead; a set or a dedupe on append would keep that linear if it ever grows.
Checklist for d3bf996 (CI combined status: success; the skipped jobs are the non-linux-x64 runners and release packaging, not triggered for this change): - **Tests:** ok. New group "A keystroke in a body keeps the sites and the index of every other module" covers the acceptance criteria of #10: second keystroke declares 1 of N modules (3+ module workspace), outline change and disk change drop the kept state, and an equivalence test against `checkBodiesWithin` (type with `with`, `extend`, a trait implementation of another module, a derived `Show`, an extending reader module that gets withheld) incl. "kept checker holds no derived implementation". - **Workflows:** ok, none changed. - **Correctness:** ok. Reader detection (withhold + restart round, 8-round cap, unusable fallback to `checkBodiesWithin` when collection asked trait questions) is conservative; the copy-not-undo approach keeps the kept checker clean; symbol moving (`movedSymbol`) is consistent with the refreshed front, and `prepared` survives only `refreshedFront` for the same module. `checkTypes`, `preparedChecker`, `torb check`/`build` untouched. - **Scope = task:** ok, exactly #10 (sites + index reuse, measurement in section 7, first bullet of section 15 removed). No new automations. - **Security/secrets/data/architecture/placement/UI:** nothing relevant, no new boundary. - **Docs:** ok. `LANGUAGE-SERVER.md` sections 7 and 15 updated with the decision, the copy-vs-undo cost and the measurement from CI-built binaries; pdisc green. Non-blocking: - The PR body says the docs "follow", but they are already in this diff; worth a body touch-up. - `Checker.unsitedConstants` is appended per lowering call without de-duplication and read with `List.contains` per watched symbol in `countRead`; a set or a dedupe on append would keep that linear if it ever grows.
argus merged commit 7181a909a8 into main 2026-10-08 03:28:42 +00:00
argus deleted branch loop/10-language-server-sites-index 2026-10-08 03:28:42 +00:00
Sign in to join this conversation.
No reviewers
No labels
loop
ready
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
torbscript/language!174
No description provided.