pub struct IncrementalGraph { /* private fields */ }Expand description
Incremental Tier-B resolution store. Holds one isolated subgraph per file
plus a global definition index, so re-extracting a single changed file
rebuilds only that file’s subgraph — never the whole graph — while
graph stitches the current cross-file edges on
demand.
Output is identical (up to ordering) to running ScopeGraphResolver over
the same file set: both share the same per-file build and stitch passes.
use code2graph::{extract_path, resolve::IncrementalGraph};
// `app` imports `Config` from `conf`.
let conf = extract_path("src/conf.rs", "pub struct Config {}").unwrap();
let app = extract_path("src/app.rs", "use conf::Config;\npub fn run() {}").unwrap();
// Keep a resolved graph current as files change: each file is resolved in
// isolation and cross-file edges are stitched on demand.
let mut graph = IncrementalGraph::from_files(&[conf, app]);
let resolves_import = |g: code2graph::graph::CodeGraph| {
g.edges.iter().any(|e| e.to.to_scip_string().ends_with("conf/Config#"))
};
assert!(resolves_import(graph.graph()));
// Re-extract only the changed file; `conf` is never reprocessed.
let app = extract_path("src/app.rs", "use conf::Config;\npub fn helper() {}").unwrap();
graph.upsert(&app);
assert!(resolves_import(graph.graph()));Implementations§
Source§impl IncrementalGraph
impl IncrementalGraph
Sourcepub fn from_files(files: &[FileFacts]) -> Self
pub fn from_files(files: &[FileFacts]) -> Self
Build a store from a file set by upserting each in turn. Ergonomic
constructor equivalent to new() followed by an upsert per file.
Sourcepub fn upsert(&mut self, facts: &FileFacts)
pub fn upsert(&mut self, facts: &FileFacts)
Insert or replace the subgraph for facts.file.
Re-extracting a file rebuilds ONLY that file’s subgraph — structurally guaranteed, because the per-file build reads no file but the one passed. If a subgraph already existed for this key, its definitions are removed from the global index first, so the index reflects only the current set.
Sourcepub fn subgraph(&self, file: &str) -> Option<&FileSubgraph>
pub fn subgraph(&self, file: &str) -> Option<&FileSubgraph>
Return the stored FileSubgraph for a file key, or None if the file
is not present in the store.
This is the persistence read path: a consumer serializes the returned
subgraph (e.g. with serde_json::to_string) and writes it to a cache
store keyed by file path. On the next startup, the consumer deserializes
each cached blob and restores it via upsert_subgraph — bypassing
build_subgraph entirely for files that have not changed.
Sourcepub fn upsert_subgraph(&mut self, file: String, sub: FileSubgraph)
pub fn upsert_subgraph(&mut self, file: String, sub: FileSubgraph)
Insert or replace a PRE-BUILT (e.g. deserialized) FileSubgraph for
file, updating the global definition index to reflect the new contents.
This is the persistence write path (the restore leg): after deserializing
a cached subgraph on startup, call this method to re-populate the store
without re-running build_subgraph. The global index is rebuilt from the
restored symbols, so the index is never itself persisted — the
subgraphs are the single source of truth, and the index is always derived
from them.
If a subgraph already exists for file (e.g. a hot-reload of a changed
file), its symbols are removed from the index first, exactly as upsert
does, so the index never accumulates stale entries.
All of upsert’s index-bookkeeping lives here; upsert itself delegates
to this method (after calling build_subgraph) so the two paths can never
drift.
Sourcepub fn remove(&mut self, file: &str)
pub fn remove(&mut self, file: &str)
Drop the file file from the store, removing its definitions from the
global index. A no-op if the file is not present.
Sourcepub fn graph(&self) -> CodeGraph
pub fn graph(&self) -> CodeGraph
Stitch the current cross-file edges and return the full CodeGraph.
Deterministic: file keys are processed in sorted order, so symbols, intra-file edges, and pending refs always accumulate in the same order regardless of upsert history. Cross-file edges are stitched last against the current global index.