@@ -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" ) ) ]
24922509impl 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
0 commit comments