Build a Smaller rust-analyzer
Build a language service with lossless parsing, revisioned inputs, dependency-tracked queries, snapshot workers, and cancellation of stale work.
1. Parse incomplete expressions
Create tokens and a tiny immutable syntax tree. Return (tree, errors) and add
error nodes rather than failing. Make every typed child accessor optional.
2. Add ground inputs
Store FileId → Arc<str> and a small crate graph. Keep paths in a separate VFS
map. All semantic functions accept IDs, never read files.
3. Build a memoized query engine
Implement parse, definitions, name resolution, and type-of-expression queries. Record query dependencies and input revisions. Reuse a result only if its transitive inputs remain unchanged.
4. Separate host and snapshot
AnalysisHost owns mutable inputs. analysis() returns a cloneable read
snapshot. Applying a change advances the revision and invalidates outstanding
snapshots.
5. Add main-loop dispatch
Use channels for client, VFS, and worker events. Apply all mutations in one loop. Route typed read requests with a snapshot to a fixed thread pool and send responses back as tasks.
6. Make stale work cancel
Have long queries periodically compare their captured revision with the host’s
current revision and unwind or return Cancelled. Map cancellation to retry for
idempotent requests and content-modified otherwise.
7. Add latency classes
Keep trivial typing operations synchronous, semantic work on a worker pool, and one blocking formatter on a separate lane. Saturate the semantic pool and prove the typing and formatting paths still respond.
8. Isolate an extension
Run a fake macro expander as a subprocess over framed messages. Crash it on one request; preserve syntax features, report degradation, and restart it.
9. Compare with production
Map your design to VFS, GlobalState, AnalysisHost, Analysis, Salsa inputs
and tracked functions, RequestDispatcher, TaskPool, HIR/IDE façades, Cargo,
flycheck, and proc-macro server. The real repository adds the Rust language,
macro hygiene, rich inference, project models, thousands of features, and
careful memory tuning. Preserve its center: immutable derived worlds that can
be abandoned the moment ground truth changes.