diff --git a/stack-graphs/CHANGELOG.md b/stack-graphs/CHANGELOG.md index ee5b6404f..c61221e8e 100644 --- a/stack-graphs/CHANGELOG.md +++ b/stack-graphs/CHANGELOG.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - The `Appendable` trait has been simplified. Its `Ctx` type parameter is gone, in favor of a separate trait `ToAppendable` that is used to find appendables for a handle. The type itself moved from the `cycles` to the `stitching` module. -- The `ForwardPartialPathStitcher` has been generalized so that it can be used to build paths from a database or from graph edges. It now takes a type parameter indicating the type of candidates it uses. Instead of a `Database` instance, it expects a value that implements the `Candidates` and `ToAppendable` traits. The `ForwardPartialPathStitcher::process_next_phase` expects an additional `extend_until` closure that controls whether the extended paths are considered for further extension or not (using `|_,_,_| true` retains old behavior). +- The `ForwardPartialPathStitcher` has been generalized so that it can be used to build paths from a database, graph edges, or a SQL reader. It now takes a type parameter indicating the type of candidates it uses. Instead `StackGraph`, `PartialPaths` and `Database` instances, it expects a value that implements the `ForwardCandidates` trait. The `ForwardPartialPathStitcher::process_next_phase` expects an additional `extend_until` closure that controls whether the extended paths are considered for further extension or not (using `|_,_,_| true` retains old behavior). - The SQLite database implementation is using a new schema which stores binary instead of JSON values, resulting in faster write times and smaller databases. - Renamed method `SQLiteReader::load_graph_for_file_or_directory` to `SQLiteReader::load_graphs_for_file_or_directory`. @@ -30,7 +30,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - The `ForwardPartialPathStitcher::from_nodes` function has been removed. Callers are responsible for creating the right initial paths, which can be done using `PartialPath::from_node`. - The `PartialPaths::find_minimal_partial_path_set_in_file` method has been removed in favor of `ForwardPartialPathStitcher::find_minimal_partial_path_set_in_file`. -- The `PartialPaths::find_all_complete_paths` method has been removed in favor of `ForwardPartialPathStitcher::find_all_complete_partial_paths` using `GraphEdges(None)` for the `db` argument. +- The `PartialPaths::find_all_complete_paths` method has been removed in favor of `ForwardPartialPathStitcher::find_all_complete_partial_paths` using a `GraphEdgeCandidates` instance for the `candidates` argument. +- The `Database::find_all_complete_paths` method has been removed in favor of `ForwardPartialPathStitcher::find_all_complete_partial_paths` using a `DatabaseCandidates` instance for the `candidates` argument. +- The `SQLiteReader::find_all_complete_partial_paths` method has been removed in favor of `ForwardPartialPathStitcher::find_all_complete_partial_paths` using a `SQLiteReader` instance for the `candidates` argument. - The `OwnedOrDatabasePath` has been removed because it was obsolete with the changes to `Appendable`. ## v0.11.0 -- 2023-06-08 diff --git a/stack-graphs/src/assert.rs b/stack-graphs/src/assert.rs index c00087eae..70237614c 100644 --- a/stack-graphs/src/assert.rs +++ b/stack-graphs/src/assert.rs @@ -18,6 +18,7 @@ use crate::graph::Symbol; use crate::partial::PartialPath; use crate::partial::PartialPaths; use crate::stitching::Database; +use crate::stitching::DatabaseCandidates; use crate::stitching::ForwardPartialPathStitcher; use crate::CancellationError; use crate::CancellationFlag; @@ -179,9 +180,7 @@ impl Assertion { for reference in &references { let mut reference_paths = Vec::new(); ForwardPartialPathStitcher::find_all_complete_partial_paths( - graph, - partials, - db, + &mut DatabaseCandidates::new(graph, partials, db), vec![*reference], cancellation_flag, |_, _, p| { diff --git a/stack-graphs/src/c.rs b/stack-graphs/src/c.rs index 1b4c95a34..f4857c791 100644 --- a/stack-graphs/src/c.rs +++ b/stack-graphs/src/c.rs @@ -29,8 +29,9 @@ use crate::partial::PartialScopeStack; use crate::partial::PartialScopedSymbol; use crate::partial::PartialSymbolStack; use crate::stitching::Database; +use crate::stitching::DatabaseCandidates; use crate::stitching::ForwardPartialPathStitcher; -use crate::stitching::GraphEdges; +use crate::stitching::GraphEdgeCandidates; use crate::CancellationError; use crate::CancellationFlag; @@ -1218,9 +1219,7 @@ pub extern "C" fn sg_partial_path_arena_find_all_complete_paths( let cancellation_flag: Option<&AtomicUsize> = unsafe { std::mem::transmute(cancellation_flag.as_ref()) }; ForwardPartialPathStitcher::find_all_complete_partial_paths( - graph, - partials, - &mut GraphEdges(None), + &mut GraphEdgeCandidates::new(graph, partials, None), starting_nodes.iter().copied().map(sg_node_handle::into), &AtomicUsizeCancellationFlag(cancellation_flag), |graph, _partials, path| { @@ -1535,9 +1534,10 @@ pub extern "C" fn sg_forward_partial_path_stitcher_process_next_phase( let partials = unsafe { &mut (*partials).inner }; let db = unsafe { &mut (*db).inner }; let stitcher = unsafe { &mut *(stitcher as *mut InternalForwardPartialPathStitcher) }; - stitcher - .stitcher - .process_next_phase(graph, partials, db, |_, _, _| true); + stitcher.stitcher.process_next_phase( + &mut DatabaseCandidates::new(graph, partials, db), + |_, _, _| true, + ); stitcher.update_previous_phase_partial_paths(partials); } diff --git a/stack-graphs/src/stitching.rs b/stack-graphs/src/stitching.rs index cf1ecbdd7..b332389c1 100644 --- a/stack-graphs/src/stitching.rs +++ b/stack-graphs/src/stitching.rs @@ -172,46 +172,84 @@ where //------------------------------------------------------------------------------------------------- // Candidates -/// A trait to support finding candidates for partial path extension. Requires an accompanying -/// [`ToAppendable`] implementation to convert the candidate handles into [`Appendable`]s. -pub trait Candidates { - fn find_candidates( +/// A trait to support finding candidates for partial path extension. The candidates are represented +/// by handles `H`, which are mapped to appendables `A` using the database `Db`. Loading errors are +/// reported as values of the `Err` type. +pub trait ForwardCandidates +where + A: Appendable, + Db: ToAppendable, +{ + /// Load possible forward candidates for the given partial path into this candidates instance. + /// Must be called before [`get_forward_candidates`] to allow lazy-loading implementations. + fn load_forward_candidates( &mut self, - graph: &StackGraph, - partials: &mut PartialPaths, - path: &PartialPath, - result: &mut R, - ) where + _path: &PartialPath, + _cancellation_flag: &dyn CancellationFlag, + ) -> Result<(), Err> { + Ok(()) + } + + /// Get forward candidates for extending the given partial path and add them to the provided + /// result instance. If this instance loads data lazily, this only considers previously loaded + /// data. + fn get_forward_candidates(&mut self, path: &PartialPath, result: &mut R) + where R: std::iter::Extend; + + /// Get the graph, partial path arena, and database backing this candidates instance. + fn get_graph_partials_and_db(&mut self) -> (&StackGraph, &mut PartialPaths, &Db); } //------------------------------------------------------------------------------------------------- // FileEdges /// Acts as a database of the edges in the graph. -pub struct GraphEdges(pub Option>); +pub struct GraphEdgeCandidates<'a> { + graph: &'a StackGraph, + partials: &'a mut PartialPaths, + file: Option>, + edges: GraphEdges, +} -impl ToAppendable for GraphEdges { - fn get_appendable<'a>(&'a self, value: &'a Edge) -> &'a Edge { - value +impl<'a> GraphEdgeCandidates<'a> { + pub fn new( + graph: &'a StackGraph, + partials: &'a mut PartialPaths, + file: Option>, + ) -> Self { + Self { + graph, + partials, + file, + edges: GraphEdges, + } } } -impl Candidates for GraphEdges { - fn find_candidates( - &mut self, - graph: &StackGraph, - _partials: &mut PartialPaths, - path: &PartialPath, - result: &mut R, - ) where +impl ForwardCandidates for GraphEdgeCandidates<'_> { + fn get_forward_candidates(&mut self, path: &PartialPath, result: &mut R) + where R: std::iter::Extend, { - result.extend( - graph - .outgoing_edges(path.end_node) - .filter(|e| self.0.map_or(true, |file| graph[e.sink].is_in_file(file))), - ); + result.extend(self.graph.outgoing_edges(path.end_node).filter(|e| { + self.file + .map_or(true, |file| self.graph[e.sink].is_in_file(file)) + })); + } + + fn get_graph_partials_and_db(&mut self) -> (&StackGraph, &mut PartialPaths, &GraphEdges) { + (self.graph, self.partials, &self.edges) + } +} + +/// A dummy type to act as the "database" for graph edges. Its [`ToAppendable`] implementation +/// is the identity on edges. +pub struct GraphEdges; + +impl ToAppendable for GraphEdges { + fn get_appendable<'a>(&'a self, edge: &'a Edge) -> &'a Edge { + edge } } @@ -303,6 +341,32 @@ impl Database { handle } + /// Find all partial paths in this database that start at the given path's end node. + /// If the end node is the root node, returns paths with a symbol stack precondition + /// that are compatible with the path's symbol stack post condition. + pub fn find_candidate_partial_paths( + &mut self, + graph: &StackGraph, + partials: &mut PartialPaths, + path: &PartialPath, + result: &mut R, + ) where + R: std::iter::Extend>, + { + if graph[path.end_node].is_root() { + // The join node is root, so there's no need to use half-open symbol stacks here, as we + // do for [`PartialPath::concatenate`][]. + let key = SymbolStackKey::from_partial_symbol_stack( + partials, + self, + path.symbol_stack_postcondition, + ); + self.find_candidate_partial_paths_from_root(graph, partials, Some(key), result); + } else { + self.find_candidate_partial_paths_from_node(graph, partials, path.end_node, result); + } + } + /// Find all partial paths in this database that start at the root node, and have a symbol /// stack precondition that is compatible with a given symbol stack. #[cfg_attr(not(feature = "copious-debugging"), allow(unused_variables))] @@ -500,28 +564,39 @@ impl ToAppendable, PartialPath> for Database { } } -impl Candidates> for Database { - fn find_candidates( - &mut self, - graph: &StackGraph, - partials: &mut PartialPaths, - path: &PartialPath, - result: &mut R, - ) where +pub struct DatabaseCandidates<'a> { + graph: &'a StackGraph, + partials: &'a mut PartialPaths, + database: &'a mut Database, +} + +impl<'a> DatabaseCandidates<'a> { + pub fn new( + graph: &'a StackGraph, + partials: &'a mut PartialPaths, + database: &'a mut Database, + ) -> Self { + Self { + graph, + partials, + database, + } + } +} + +impl ForwardCandidates, PartialPath, Database, CancellationError> + for DatabaseCandidates<'_> +{ + fn get_forward_candidates(&mut self, path: &PartialPath, result: &mut R) + where R: std::iter::Extend>, { - if graph[path.end_node].is_root() { - // The join node is root, so there's no need to use half-open symbol stacks here, as we - // do for [`PartialPath::concatenate`][]. - let key = SymbolStackKey::from_partial_symbol_stack( - partials, - self, - path.symbol_stack_postcondition, - ); - self.find_candidate_partial_paths_from_root(graph, partials, Some(key), result); - } else { - self.find_candidate_partial_paths_from_node(graph, partials, path.end_node, result); - } + self.database + .find_candidate_partial_paths(self.graph, self.partials, path, result); + } + + fn get_graph_partials_and_db(&mut self) -> (&StackGraph, &mut PartialPaths, &Database) { + (self.graph, self.partials, self.database) } } @@ -754,18 +829,18 @@ impl ForwardPartialPathStitcher { /// Attempts to extend one partial path as part of the algorithm. When calling this function, /// you are responsible for ensuring that `db` already contains all of the possible appendables /// that we might want to extend `partial_path` with. - fn extend( + fn extend( &mut self, - graph: &StackGraph, - partials: &mut PartialPaths, - db: &mut Db, + candidates: &mut C, partial_path: &PartialPath, cycle_detector: AppendingCycleDetector, ) -> usize where A: Appendable, - Db: Candidates + ToAppendable, + Db: ToAppendable, + C: ForwardCandidates, { + let (graph, partials, db) = candidates.get_graph_partials_and_db(); copious_debugging!(" Extend {}", partial_path.display(graph, partials)); // check is path is cyclic, in which case we do not extend it @@ -794,13 +869,14 @@ impl ForwardPartialPathStitcher { // find candidates to append self.candidates.clear(); - db.find_candidates(graph, partials, partial_path, &mut self.candidates); + candidates.get_forward_candidates(partial_path, &mut self.candidates); // try to extend path with candidates let extension_count = self.candidates.len(); self.next_iteration.0.reserve(extension_count); self.next_iteration.1.reserve(extension_count); for extension in &self.candidates { + let (graph, partials, db) = candidates.get_graph_partials_and_db(); let extension_path = db.get_appendable(extension); copious_debugging!(" with {}", extension_path.display(graph, partials)); @@ -852,15 +928,11 @@ impl ForwardPartialPathStitcher { /// or not. It is not called on the initial paths. /// /// [`previous_phase_partial_paths`]: #method.previous_phase_partial_paths - pub fn process_next_phase( - &mut self, - graph: &StackGraph, - partials: &mut PartialPaths, - db: &mut Db, - extend_while: E, - ) where + pub fn process_next_phase(&mut self, candidates: &mut C, extend_while: E) + where A: Appendable, - Db: Candidates + ToAppendable, + Db: ToAppendable, + C: ForwardCandidates, E: Fn(&StackGraph, &mut PartialPaths, &PartialPath) -> bool, { copious_debugging!("==> Start phase {}", self.phase_number); @@ -872,6 +944,7 @@ impl ForwardPartialPathStitcher { ); let mut work_performed = 0; while let Some((partial_path, cycle_detector)) = self.queue.pop_front() { + let (graph, partials, _) = candidates.get_graph_partials_and_db(); copious_debugging!( "--> Candidate partial path {}", partial_path.display(graph, partials) @@ -885,7 +958,7 @@ impl ForwardPartialPathStitcher { ); continue; } - work_performed += self.extend(graph, partials, db, &partial_path, cycle_detector); + work_performed += self.extend(candidates, &partial_path, cycle_detector); if work_performed >= self.max_work_per_phase { break; } @@ -948,9 +1021,7 @@ impl ForwardPartialPathStitcher { while !stitcher.is_complete() { cancellation_flag.check("finding complete partial paths")?; stitcher.process_next_phase( - graph, - partials, - &mut GraphEdges(Some(file)), + &mut GraphEdgeCandidates::new(graph, partials, Some(file)), |g, _ps, p| !as_complete_as_necessary(g, p), ); for path in stitcher.previous_phase_partial_paths() { @@ -975,34 +1046,40 @@ impl ForwardPartialPathStitcher { /// [`process_next_phase`][] manually. /// /// [`process_next_phase`]: #method.process_next_phase - pub fn find_all_complete_partial_paths( - graph: &StackGraph, - partials: &mut PartialPaths, - db: &mut Db, + pub fn find_all_complete_partial_paths( + candidates: &mut C, starting_nodes: I, cancellation_flag: &dyn CancellationFlag, mut visit: F, - ) -> Result<(), CancellationError> + ) -> Result<(), Err> where I: IntoIterator>, A: Appendable, - Db: Candidates + ToAppendable, + Db: ToAppendable, + C: ForwardCandidates, F: FnMut(&StackGraph, &mut PartialPaths, &PartialPath), + Err: std::convert::From, { - let initial_paths = starting_nodes - .into_iter() - .filter(|n| graph[*n].is_reference()) - .map(|n| { - let mut p = PartialPath::from_node(graph, partials, n); - p.eliminate_precondition_stack_variables(partials); - p - }) - .collect::>(); - let mut stitcher = - ForwardPartialPathStitcher::from_partial_paths(graph, partials, initial_paths); + let mut stitcher = { + let (graph, partials, _) = candidates.get_graph_partials_and_db(); + let initial_paths = starting_nodes + .into_iter() + .filter(|n| graph[*n].is_reference()) + .map(|n| { + let mut p = PartialPath::from_node(graph, partials, n); + p.eliminate_precondition_stack_variables(partials); + p + }) + .collect::>(); + ForwardPartialPathStitcher::from_partial_paths(graph, partials, initial_paths) + }; while !stitcher.is_complete() { cancellation_flag.check("finding complete partial paths")?; - stitcher.process_next_phase(graph, partials, db, |_, _, _| true); + for path in stitcher.previous_phase_partial_paths() { + candidates.load_forward_candidates(path, cancellation_flag)?; + } + stitcher.process_next_phase(candidates, |_, _, _| true); + let (graph, partials, _) = candidates.get_graph_partials_and_db(); for path in stitcher.previous_phase_partial_paths() { if path.is_complete(graph) { visit(graph, partials, path); diff --git a/stack-graphs/src/storage.rs b/stack-graphs/src/storage.rs index 808697a4a..3cd89d797 100644 --- a/stack-graphs/src/storage.rs +++ b/stack-graphs/src/storage.rs @@ -28,7 +28,7 @@ use crate::partial::PartialSymbolStack; use crate::serde; use crate::serde::FileFilter; use crate::stitching::Database; -use crate::stitching::ForwardPartialPathStitcher; +use crate::stitching::ForwardCandidates; use crate::CancellationError; use crate::CancellationFlag; @@ -684,51 +684,6 @@ impl SQLiteReader { pub fn get(&mut self) -> (&StackGraph, &mut PartialPaths, &mut Database) { (&self.graph, &mut self.partials, &mut self.db) } - - /// Find all paths using the given path stitcher. Data is lazily loaded if necessary. - pub fn find_all_complete_partial_paths( - &mut self, - starting_nodes: I, - cancellation_flag: &dyn CancellationFlag, - mut visit: F, - ) -> Result<()> - where - I: IntoIterator>, - F: FnMut(&StackGraph, &mut PartialPaths, &PartialPath), - { - let initial_paths = starting_nodes - .into_iter() - .map(|n| { - let mut p = PartialPath::from_node(&self.graph, &mut self.partials, n); - p.eliminate_precondition_stack_variables(&mut self.partials); - p - }) - .collect::>(); - let mut stitcher = ForwardPartialPathStitcher::from_partial_paths( - &self.graph, - &mut self.partials, - initial_paths, - ); - stitcher.set_max_work_per_phase(128); - while !stitcher.is_complete() { - cancellation_flag.check("find_all_complete_partial_paths")?; - for path in stitcher.previous_phase_partial_paths() { - self.load_partial_path_extensions(path, cancellation_flag)?; - } - stitcher.process_next_phase( - &self.graph, - &mut self.partials, - &mut self.db, - |_, _, _| true, - ); - for path in stitcher.previous_phase_partial_paths() { - if path.is_complete(&self.graph) { - visit(&self.graph, &mut self.partials, path); - } - } - } - Ok(()) - } } impl PartialSymbolStack { @@ -764,6 +719,28 @@ impl PartialSymbolStack { } } +impl ForwardCandidates, PartialPath, Database, StorageError> for SQLiteReader { + fn load_forward_candidates( + &mut self, + path: &PartialPath, + cancellation_flag: &dyn CancellationFlag, + ) -> std::result::Result<(), StorageError> { + self.load_partial_path_extensions(path, cancellation_flag) + } + + fn get_forward_candidates(&mut self, path: &PartialPath, result: &mut R) + where + R: std::iter::Extend>, + { + self.db + .find_candidate_partial_paths(&self.graph, &mut self.partials, path, result); + } + + fn get_graph_partials_and_db(&mut self) -> (&StackGraph, &mut PartialPaths, &Database) { + (&self.graph, &mut self.partials, &self.db) + } +} + /// Check if the database has the version supported by this library version. fn check_version(conn: &Connection) -> Result<()> { let version = conn.query_row("SELECT version FROM metadata", [], |r| r.get::<_, usize>(0))?; diff --git a/stack-graphs/tests/it/can_jump_to_definition.rs b/stack-graphs/tests/it/can_jump_to_definition.rs index 7fde42161..965207f4c 100644 --- a/stack-graphs/tests/it/can_jump_to_definition.rs +++ b/stack-graphs/tests/it/can_jump_to_definition.rs @@ -10,7 +10,8 @@ use std::collections::BTreeSet; use pretty_assertions::assert_eq; use stack_graphs::graph::StackGraph; use stack_graphs::partial::PartialPaths; -use stack_graphs::stitching::{ForwardPartialPathStitcher, GraphEdges}; +use stack_graphs::stitching::ForwardPartialPathStitcher; +use stack_graphs::stitching::GraphEdgeCandidates; use stack_graphs::NoCancellation; use crate::test_graphs; @@ -22,9 +23,7 @@ fn check_jump_to_definition(graph: &StackGraph, expected_paths: &[&str]) { .iter_nodes() .filter(|handle| graph[*handle].is_reference()); ForwardPartialPathStitcher::find_all_complete_partial_paths( - graph, - &mut paths, - &mut GraphEdges(None), + &mut GraphEdgeCandidates::new(graph, &mut paths, None), references, &NoCancellation, |graph, paths, path| { diff --git a/stack-graphs/tests/it/can_jump_to_definition_with_forward_partial_path_stitching.rs b/stack-graphs/tests/it/can_jump_to_definition_with_forward_partial_path_stitching.rs index 85984e814..d45e96afc 100644 --- a/stack-graphs/tests/it/can_jump_to_definition_with_forward_partial_path_stitching.rs +++ b/stack-graphs/tests/it/can_jump_to_definition_with_forward_partial_path_stitching.rs @@ -11,6 +11,7 @@ use pretty_assertions::assert_eq; use stack_graphs::graph::StackGraph; use stack_graphs::partial::PartialPaths; use stack_graphs::stitching::Database; +use stack_graphs::stitching::DatabaseCandidates; use stack_graphs::stitching::ForwardPartialPathStitcher; use stack_graphs::NoCancellation; @@ -39,9 +40,7 @@ fn check_jump_to_definition(graph: &StackGraph, expected_partial_paths: &[&str]) .filter(|handle| graph[*handle].is_reference()); let mut complete_partial_paths = Vec::new(); ForwardPartialPathStitcher::find_all_complete_partial_paths( - graph, - &mut partials, - &mut db, + &mut DatabaseCandidates::new(graph, &mut partials, &mut db), references, &NoCancellation, |_, _, p| { diff --git a/stack-graphs/tests/it/cycles.rs b/stack-graphs/tests/it/cycles.rs index e9584dd2f..12c8b5672 100644 --- a/stack-graphs/tests/it/cycles.rs +++ b/stack-graphs/tests/it/cycles.rs @@ -171,7 +171,7 @@ fn finding_simple_identity_cycle_is_detected() { { let mut edges = Appendables::new(); let mut cd = AppendingCycleDetector::new(); - let db = &GraphEdges(None); + let db = &GraphEdges; for edge in &[ edge(r, foo_ref, 0), @@ -261,7 +261,7 @@ fn finding_composite_identity_cycle_is_detected() { { let mut edges = Appendables::new(); let mut cd = AppendingCycleDetector::new(); - let db = &GraphEdges(None); + let db = &GraphEdges; for edge in &[ edge(r, s, 0), edge(r, s, 0), diff --git a/tree-sitter-stack-graphs/src/cli/query.rs b/tree-sitter-stack-graphs/src/cli/query.rs index 583aee85b..08ede0b93 100644 --- a/tree-sitter-stack-graphs/src/cli/query.rs +++ b/tree-sitter-stack-graphs/src/cli/query.rs @@ -9,6 +9,7 @@ use clap::Args; use clap::Parser; use clap::Subcommand; use clap::ValueHint; +use stack_graphs::stitching::ForwardPartialPathStitcher; use stack_graphs::storage::FileStatus; use stack_graphs::storage::SQLiteReader; use std::path::Path; @@ -184,7 +185,8 @@ impl<'a> Querier<'a> { }; let mut reference_paths = Vec::new(); - if let Err(err) = self.db.find_all_complete_partial_paths( + if let Err(err) = ForwardPartialPathStitcher::find_all_complete_partial_paths( + self.db, std::iter::once(node), &cancellation_flag, |_g, _ps, p| { @@ -256,6 +258,12 @@ pub enum QueryError { StorageError(#[from] stack_graphs::storage::StorageError), } +impl From for QueryError { + fn from(value: stack_graphs::CancellationError) -> Self { + Self::Cancelled(value.0) + } +} + impl From for QueryError { fn from(value: crate::CancellationError) -> Self { Self::Cancelled(value.0) diff --git a/tree-sitter-stack-graphs/src/cli/test.rs b/tree-sitter-stack-graphs/src/cli/test.rs index 9566687f1..4bcb47171 100644 --- a/tree-sitter-stack-graphs/src/cli/test.rs +++ b/tree-sitter-stack-graphs/src/cli/test.rs @@ -16,6 +16,7 @@ use stack_graphs::graph::StackGraph; use stack_graphs::partial::PartialPaths; use stack_graphs::serde::Filter; use stack_graphs::stitching::Database; +use stack_graphs::stitching::DatabaseCandidates; use stack_graphs::stitching::ForwardPartialPathStitcher; use std::path::Path; use std::path::PathBuf; @@ -481,9 +482,7 @@ impl TestArgs { .collect::>(); let mut paths = Vec::new(); ForwardPartialPathStitcher::find_all_complete_partial_paths( - graph, - partials, - db, + &mut DatabaseCandidates::new(graph, partials, db), references.clone(), &cancellation_flag, |_, _, p| { diff --git a/tree-sitter-stack-graphs/src/cli/visualize.rs b/tree-sitter-stack-graphs/src/cli/visualize.rs index fd947c1d9..e0665c353 100644 --- a/tree-sitter-stack-graphs/src/cli/visualize.rs +++ b/tree-sitter-stack-graphs/src/cli/visualize.rs @@ -9,6 +9,7 @@ use clap::Args; use clap::ValueHint; use stack_graphs::serde::NoFilter; use stack_graphs::stitching::Database; +use stack_graphs::stitching::ForwardPartialPathStitcher; use stack_graphs::storage::SQLiteReader; use stack_graphs::NoCancellation; use std::path::Path; @@ -53,9 +54,14 @@ impl VisualizeArgs { .filter(|n| graph[*n].is_reference()) .collect::>(); let mut complete_paths_db = Database::new(); - db.find_all_complete_partial_paths(starting_nodes, cancellation_flag, |g, ps, p| { - complete_paths_db.add_partial_path(g, ps, p.clone()); - })?; + ForwardPartialPathStitcher::find_all_complete_partial_paths( + &mut db, + starting_nodes, + cancellation_flag, + |g, ps, p| { + complete_paths_db.add_partial_path(g, ps, p.clone()); + }, + )?; let (graph, partials, _) = db.get(); let html = graph.to_html_string("stack-graph", partials, &mut complete_paths_db, &NoFilter)?;