Skip to content
This repository was archived by the owner on Sep 9, 2025. It is now read-only.

Commit 91692b3

Browse files
author
Hendrik van Antwerpen
committed
Add feature flag for new path finding experiment
1 parent d7a1868 commit 91692b3

File tree

4 files changed

+90
-3
lines changed

4 files changed

+90
-3
lines changed

stack-graphs/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ edition = "2018"
1515
[features]
1616
copious-debugging = []
1717
json = ["serde", "serde_json"]
18+
new-partial-paths = []
1819

1920
[lib]
2021
# All of our tests are in the tests/it "integration" test executable.

stack-graphs/src/graph.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,11 @@ impl Node {
579579
matches!(self, Node::Root(_))
580580
}
581581

582+
#[inline(always)]
583+
pub fn is_endpoint(&self) -> bool {
584+
self.is_definition() || self.is_exported_scope() || self.is_reference() || self.is_root()
585+
}
586+
582587
/// Returns this node's symbol, if it has one. (_Pop symbol_, _pop scoped symbol_, _push
583588
/// symbol_, and _push scoped symbol_ nodes have symbols.)
584589
pub fn symbol(&self) -> Option<Handle<Symbol>> {

stack-graphs/src/partial.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2055,9 +2055,25 @@ impl PartialPath {
20552055
self.starts_at_reference(graph) && self.ends_at_definition(graph)
20562056
}
20572057

2058+
pub fn starts_at_endpoint(&self, graph: &StackGraph) -> bool {
2059+
let node = &graph[self.start_node];
2060+
node.is_endpoint()
2061+
}
2062+
2063+
pub fn ends_at_endpoint(&self, graph: &StackGraph) -> bool {
2064+
let node = &graph[self.end_node];
2065+
node.is_endpoint() || node.is_jump_to()
2066+
}
2067+
2068+
#[cfg(feature = "new-partial-paths")]
2069+
pub fn as_complete_as_necessary(&self, graph: &StackGraph) -> bool {
2070+
self.starts_at_endpoint(graph) && self.ends_at_endpoint(graph)
2071+
}
2072+
20582073
/// A partial path is _as complete as possible_ if we cannot extend it any further within the
20592074
/// current file. This represents the maximal amount of work that we can pre-compute at index
20602075
/// time.
2076+
#[cfg(not(feature = "new-partial-paths"))]
20612077
pub fn is_complete_as_possible(&self, graph: &StackGraph) -> bool {
20622078
match &graph[self.start_node] {
20632079
Node::Root(_) => (),
@@ -2489,6 +2505,7 @@ impl Node {
24892505
}
24902506
}
24912507

2508+
#[cfg(not(feature = "new-partial-paths"))]
24922509
impl PartialPaths {
24932510
/// Finds all partial paths in a file, calling the `visit` closure for each one.
24942511
///
@@ -2546,6 +2563,72 @@ impl PartialPaths {
25462563
}
25472564
}
25482565

2566+
#[cfg(feature = "new-partial-paths")]
2567+
impl PartialPaths {
2568+
/// Finds all partial paths in a file, calling the `visit` closure for each one.
2569+
///
2570+
/// This function ensures that the set of visited partial paths covers all complete
2571+
/// paths, from references to definitions, when used for path stitching. Callers are
2572+
/// advised _not_ to filter this set in the visitor using functions like
2573+
/// [`PartialPath::is_complete_as_possible`][] or [`PartialPath::is_productive`][] as
2574+
/// that may interfere with implementation changes of this function.
2575+
///
2576+
/// This function will not return until all reachable partial paths have been processed, so
2577+
/// `graph` must already contain a complete stack graph. If you have a very large stack graph
2578+
/// stored in some other storage system, and want more control over lazily loading only the
2579+
/// necessary pieces, then you should code up your own loop that calls
2580+
/// [`PartialPath::extend`][] manually.
2581+
///
2582+
/// [`PartialPath::extend`]: struct.PartialPath.html#method.extend
2583+
pub fn find_all_partial_paths_in_file<F>(
2584+
&mut self,
2585+
graph: &StackGraph,
2586+
file: Handle<File>,
2587+
cancellation_flag: &dyn CancellationFlag,
2588+
mut visit: F,
2589+
) -> Result<(), CancellationError>
2590+
where
2591+
F: FnMut(&StackGraph, &mut PartialPaths, PartialPath),
2592+
{
2593+
copious_debugging!("Find all partial paths in {}", graph[file]);
2594+
let mut cycle_detector = CycleDetector::new();
2595+
let mut queue = VecDeque::new();
2596+
queue.push_back(PartialPath::from_node(graph, self, StackGraph::root_node()));
2597+
queue.extend(
2598+
graph
2599+
.nodes_for_file(file)
2600+
.filter(|node| graph[*node].is_endpoint())
2601+
.map(|node| PartialPath::from_node(graph, self, node)),
2602+
);
2603+
while let Some(path) = queue.pop_front() {
2604+
cancellation_flag.check("finding partial paths in file")?;
2605+
let is_seed = path.start_node == path.end_node && path.edges.len() == 0;
2606+
copious_debugging!(" => {}", path.display(graph, self));
2607+
if !is_seed && path.as_complete_as_necessary(graph) {
2608+
copious_debugging!(" * as complete as necessary");
2609+
if !path.is_productive(self) {
2610+
copious_debugging!(" * not productive");
2611+
} else if !cycle_detector
2612+
.should_process_path(&path, |probe| probe.cmp(graph, self, &path))
2613+
{
2614+
copious_debugging!(" * presumed a cycle");
2615+
} else {
2616+
copious_debugging!(" * visit");
2617+
visit(graph, self, path);
2618+
}
2619+
} else if !is_seed
2620+
&& !cycle_detector.should_process_path(&path, |probe| probe.cmp(graph, self, &path))
2621+
{
2622+
copious_debugging!(" * presumed a cycle");
2623+
} else {
2624+
copious_debugging!(" * extend");
2625+
path.extend_from_file(graph, self, file, &mut queue);
2626+
}
2627+
}
2628+
Ok(())
2629+
}
2630+
}
2631+
25492632
//-------------------------------------------------------------------------------------------------
25502633
// Extending paths with partial paths
25512634

tree-sitter-stack-graphs/src/cli/analyze.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -221,9 +221,7 @@ impl AnalyzeArgs {
221221
file,
222222
&cancellation_flag.as_ref(),
223223
|g, ps, p| {
224-
if p.is_complete_as_possible(g) {
225-
db.add_partial_path(g, ps, p);
226-
}
224+
db.add_partial_path(g, ps, p);
227225
},
228226
) {
229227
Ok(_) => {}

0 commit comments

Comments
 (0)