feat(code-graph-incremental): linking phase
What does this MR do and why?
Fourth slice of code-graph-incremental, stacked on !2629 (merged). A canonical tree is now linked: definitions, calls resolved through local types, and uses of imported names become edges inside the file. Linked files then go on the graph together with a File row for every file that was not parsed, tagged with why (excluded extension, binary, over budget, unreadable). Nothing is wired to the CLI or server yet.
Related Issues
Relates to #1284. Reference implementation: !2454 (closed).
Testing
cargo test -p code-graph-incremental: 35 tests. New in tests/link.rs: linking the Python fixture yields the expected DEFINES, CALLS (g = Greeter(); g.greet() resolves through the local type) and IMPORTS edges, all inside one file; every file gets a tree and unparsed ones carry their reason; a file killed by the rewrite budget keeps a row spanning its size, tagged skip_timeout_walk, with no edges. The SSA engine's own tests came along in ssa.rs.
cargo clippy -p code-graph-incremental --all-targets -- -D warnings: clean.
Performance Analysis
No runtime change: nothing calls this crate yet.
- This merge request does not introduce any performance regression. If a performance regression is expected, explain why.
Agent context: long-form analysis, file-by-file walkthroughs, profiler output, alternatives considered
What lands
src/ssa.rs SSA engine (Braun et al.): reaching definitions over the canonical tree
src/linker.rs link(tree, env, run) -> local edges; drives the SSA engine
src/pipeline/phases.rs Link (ItemPhase, Canonical -> LinkedFile), Insert (Workset -> DirtyGraph), listed_file
src/shared/tags.rs linker.rs joins the "engine-read tag keys live in tags.rs" check
tests/link.rsFiles are copied from !2454 (closed) at their final shape. Listed loses its allow(dead_code): Insert reads it. file_tree.rs is read only by Resolve and moves with it to MR 5.
Base branch is michaelusa/code-graph-incremental-dsl (!2629 (merged)); retarget to main once that merges.
MR stack
| MR | Contents |
|---|---|
| !2620 (merged) | runner, budgets, errors, canonical alphabet, artifact and graph types |
| !2627 (merged) | Tree, Interner, tree-sitter languages, Env, inventory, Prepare + Each + Parse |
| !2629 (merged) | DSL engine, Rewrite + Canonicalize, Env.rules, Python rules |
| 4 (this) | SSA, linker, Link + Insert |
| 5 | resolver, file tree, Resolve |
| 6 | export engine + export.yaml, Display + Export + Emit, index template; YAML suites through the integration-tests-codegraph runner with an engine switch; CI job |
| 7 | State save/load, Remap, reindex template, incremental suites |
| 8 | remaining language rule files |
| 9 | orbit index --engine incremental, full index through the existing DuckDB sink |
| 10 | snapshot next to the DuckDB file, changed paths from git, incremental CLI |
| 11 | default flip per language; old pipeline and its fixtures retire |
%{all_commits}