Changed symbols are updated in place. Stable edges survive, stale outgoing call sites are removed, and LSP discovery is limited to the affected ranges. Full-file rebuilds are a fallback, not the normal path.
Match old graph symbols with the LSP outline and classify deleted, added, affected, shifted, unchanged, and invisible definitions.
change_mgr + patcher_baseRemove deleted vertices, create additions, and update shifted or affected vertices in place so incoming edges remain attached.
subgraph_mgrDrop affected outgoing anchors surgically when line counts match; otherwise clear that symbol's outgoing references.
subgraph_mgrDiscover affected/added references, batch edge writes, then rebuild line-range indexes from the final graph.
patcher_baseModule Architecture
Git-based change detection. Returns modified/added/deleted/renamed files and changed line ranges.
detect_changed_files() get_changed_line_ranges()High-level orchestration. Classifies symbols, drives two patch rounds, handles fallback remap logic, and refreshes range indexes.
_classify_symbols(old, new) _remap_severed_edges()Core graph ops: deletion, reconstruction, edge reconnection, location matching.
delete_file_subgraph() rebuild_file_subgraph() match_location_to_vertex()JSON-RPC wrapper for rust-analyzer, basedpyright, gopls, and typescript-language-server. C/C++ uses refreshed clangd .idx data.
document_symbol() references() semantic_tokens_range() definition()Public API router. Creates language-specific patcher instances.
patch_files(changed) detect_changed_files()Language-specific subclasses. Override unified_name construction and token type filtering.
_build_unified_name() _get_crossfile_token_types()Three algorithms underpin the incremental update system.
Every vertex stores a unified_name (file path + dotted symbol path, no line number). This enables matching old vertices to new ones even when lines shift. Vertex names are unified_name + ":" + start_line.
LSP returns file:line:character positions. Match an exact symbol start first, then fall back to the innermost symbol span containing the line.
checker.rs:15:0linter.rs:45:12A full-file rebuild or fallback records one six-field entry per
call-site anchor:
(src_name, tgt_name, src_uname, tgt_uname, anchor_file, anchor_line).
The ordinary affected-symbol path updates the vertex in place and does
not need this remap.
Every successful patch batch ends with
build_range_indexes(). The refresh scans the final vertices
and anchored edges in O(V + E), so
query_range() sees added, moved, and removed spans
immediately. C/C++ upholds the same contract after its .idx refresh.