Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions crates/codegraph-core/src/build_pipeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,9 @@ pub struct BuildPipelineResult {
pub changed_count: usize,
pub removed_count: usize,
pub is_full_build: bool,
/// Full set of changed files including reverse-dep files. Used by the JS
/// structure fallback path so it can update metrics for files whose edges
/// changed even though their content didn't. `None` for full builds.
#[serde(skip_serializing_if = "Option::is_none")]
pub structure_scope: Option<Vec<String>>,
/// Whether the Rust pipeline handled the structure phase (directory nodes,
/// contains edges, file metrics). True when the small-incremental fast path
/// ran (≤5 changed files, >20 existing files). When false, the JS caller
/// must run its own structure phase as a post-processing step.
/// contains edges, file and directory metrics). Always true — the Rust
/// pipeline handles both the small-incremental fast path and full builds.
pub structure_handled: bool,
/// Whether the Rust pipeline wrote AST/complexity/CFG/dataflow to the DB.
/// When true, the JS caller can skip `runPostNativeAnalysis` entirely.
Expand Down Expand Up @@ -181,7 +175,6 @@ pub fn run_pipeline(
changed_count: 0,
removed_count: 0,
is_full_build: false,
structure_scope: Some(vec![]),
structure_handled: true,
analysis_complete: true,
});
Expand Down Expand Up @@ -373,11 +366,22 @@ pub fn run_pipeline(
&line_count_map,
&file_symbols,
);
} else {
// Full structure: directory nodes, contains edges, file + directory metrics.
let changed_for_structure: Option<Vec<String>> = if change_result.is_full_build {
None
} else {
Some(changed_files.clone())
};
structure::build_full_structure(
conn,
&file_symbols,
&collect_result.directories,
root_dir,
&line_count_map,
changed_for_structure.as_deref(),
);
}
// For full/larger builds, the JS fallback handles full structure via
// `features/structure.ts`. The Rust orchestrator handles the fast path
// for small incremental builds. Full structure computation will be
// ported in a follow-up.
timing.structure_ms = t0.elapsed().as_secs_f64() * 1000.0;
Comment on lines 368 to 385

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 file_symbols is incomplete when build_full_structure runs in large-incremental mode

file_symbols at this point contains only the files parsed this cycle (changed + reverse-deps), not all files in the codebase. When build_full_structure is called with changed_for_structure = Some(...), it cleans up and re-inserts contains edges using only that partial set, orphaning unchanged files in the same directories.

Fix: before calling build_full_structure in the non-fast incremental path, load all existing file paths for the affected directories from the DB and add them to the symbol set passed to the function (only path data needed, not full symbol data). The JS fallback did this via reconstructFileSymbolsFromDb.

Fix in Claude Code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in the same commit (4555d12). Rather than augmenting file_symbols in build_pipeline.rs (which would require constructing FileSymbols stubs), the fix is in structure.rs itself: insert_contains_edges and compute_directory_metrics now load all existing file paths from the DB for affected directories, so they work correctly even when file_symbols only contains the parsed subset. This matches what the JS fallback did via reconstructFileSymbolsFromDb but is more targeted — only file paths are loaded, not full symbol data.


let t0 = Instant::now();
Expand Down Expand Up @@ -489,8 +493,7 @@ pub fn run_pipeline(
changed_count: parse_changes.len(),
removed_count: change_result.removed.len(),
is_full_build: change_result.is_full_build,
structure_scope: changed_file_list.clone(),
structure_handled: use_fast_path,
structure_handled: true,
analysis_complete: do_analysis && analysis_ok,
})
}
Expand Down
Loading
Loading