55// Please see the LICENSE-APACHE or LICENSE-MIT files in this distribution for license details.
66// ------------------------------------------------------------------------------------------------
77
8+ use itertools:: Itertools ;
89use lsp_positions:: Offset ;
910use lsp_positions:: Position ;
1011use lsp_positions:: Span ;
@@ -37,58 +38,147 @@ use crate::paths::SymbolStack;
3738#[ error( transparent) ]
3839pub struct JsonError ( #[ from] serde_json:: error:: Error ) ;
3940
41+ //-----------------------------------------------------------------------------
42+ // Filter
43+
44+ pub trait Filter {
45+ /// Return whether elements for the given file must be included.
46+ fn include_file ( & self , graph : & StackGraph , file : & Handle < File > ) -> bool ;
47+
48+ /// Return whether the given node must be included.
49+ /// Nodes of excluded files are always excluded.
50+ fn include_node ( & self , graph : & StackGraph , node : & Handle < Node > ) -> bool ;
51+
52+ /// Return whether the given edge must be included.
53+ /// Edges via excluded nodes are always excluded.
54+ fn include_edge ( & self , graph : & StackGraph , source : & Handle < Node > , sink : & Handle < Node > ) -> bool ;
55+
56+ /// Return whether the given path must be included.
57+ /// Paths via excluded nodes or edges are always excluded.
58+ fn include_path ( & self , graph : & StackGraph , paths : & Paths , path : & Path ) -> bool ;
59+ }
60+
61+ impl < F > Filter for F
62+ where
63+ F : Fn ( & StackGraph , & Handle < File > ) -> bool ,
64+ {
65+ fn include_file ( & self , graph : & StackGraph , file : & Handle < File > ) -> bool {
66+ self ( graph, file)
67+ }
68+
69+ fn include_node ( & self , _graph : & StackGraph , _node : & Handle < Node > ) -> bool {
70+ true
71+ }
72+
73+ fn include_edge (
74+ & self ,
75+ _graph : & StackGraph ,
76+ _source : & Handle < Node > ,
77+ _sink : & Handle < Node > ,
78+ ) -> bool {
79+ true
80+ }
81+
82+ fn include_path ( & self , _graph : & StackGraph , _paths : & Paths , _path : & Path ) -> bool {
83+ true
84+ }
85+ }
86+
87+ /// Struct that ensures the implications of exclusions.
88+ /// For example, that nodes frome excluded files are not included, etc.
89+ struct ImplicationFilter < ' a > ( & ' a dyn Filter ) ;
90+
91+ impl Filter for ImplicationFilter < ' _ > {
92+ fn include_file ( & self , graph : & StackGraph , file : & Handle < File > ) -> bool {
93+ self . 0 . include_file ( graph, file)
94+ }
95+
96+ fn include_node ( & self , graph : & StackGraph , node : & Handle < Node > ) -> bool {
97+ graph[ * node]
98+ . id ( )
99+ . file ( )
100+ . map_or ( true , |f| self . include_file ( graph, & f) )
101+ && self . 0 . include_node ( graph, node)
102+ }
103+
104+ fn include_edge ( & self , graph : & StackGraph , source : & Handle < Node > , sink : & Handle < Node > ) -> bool {
105+ self . include_node ( graph, source)
106+ && self . include_node ( graph, sink)
107+ && self . 0 . include_edge ( graph, source, sink)
108+ }
109+
110+ fn include_path ( & self , graph : & StackGraph , paths : & Paths , path : & Path ) -> bool {
111+ path. edges
112+ . iter_unordered ( paths)
113+ . map ( |e| graph. node_for_id ( e. source_node_id ) . unwrap ( ) )
114+ . chain ( std:: iter:: once ( path. end_node ) )
115+ . tuple_windows ( )
116+ . all ( |( source, sink) | self . include_edge ( graph, & source, & sink) )
117+ && self . 0 . include_path ( graph, paths, path)
118+ }
119+ }
120+
40121//-----------------------------------------------------------------------------
41122// InStackGraph
42123
43- struct InStackGraph < ' a , T > ( T , & ' a StackGraph ) ;
124+ struct InStackGraph < ' a , T > ( T , & ' a StackGraph , & ' a dyn Filter ) ;
44125
45126impl < ' a , T > InStackGraph < ' a , T > {
46127 fn with < U > ( & ' a self , u : U ) -> InStackGraph < ' a , U > {
47- InStackGraph ( u, self . 1 )
128+ InStackGraph ( u, self . 1 , self . 2 )
48129 }
49130
50131 fn with_idx < Idx : Copy , U : ?Sized > ( & ' a self , idx : Idx ) -> InStackGraph < ' a , ( Idx , & U ) >
51132 where
52133 StackGraph : Index < Idx , Output = U > ,
53134 {
54- InStackGraph ( ( idx, & self . 1 [ idx] ) , self . 1 )
135+ InStackGraph ( ( idx, & self . 1 [ idx] ) , self . 1 , self . 2 )
55136 }
56137}
57138
58139//-----------------------------------------------------------------------------
59140// StackGraph
60141
61- impl StackGraph {
62- pub fn to_json ( & self ) -> JsonStackGraph {
63- JsonStackGraph ( self )
142+ impl < ' a > StackGraph {
143+ pub fn to_json ( & ' a self , f : & ' a dyn Filter ) -> JsonStackGraph {
144+ JsonStackGraph ( self , f )
64145 }
65146}
66147
67- pub struct JsonStackGraph < ' a > ( & ' a StackGraph ) ;
148+ pub struct JsonStackGraph < ' a > ( & ' a StackGraph , & ' a dyn Filter ) ;
68149
69150impl < ' a > JsonStackGraph < ' a > {
70151 pub fn to_value ( & self ) -> Result < Value , JsonError > {
71- Ok ( serde_json:: to_value ( self . 0 ) ?)
152+ Ok ( serde_json:: to_value ( self ) ?)
72153 }
73154
74155 pub fn to_string ( & self ) -> Result < String , JsonError > {
75- Ok ( serde_json:: to_string ( self . 0 ) ?)
156+ Ok ( serde_json:: to_string ( self ) ?)
76157 }
77158
78159 pub fn to_string_pretty ( & self ) -> Result < String , JsonError > {
79- Ok ( serde_json:: to_string_pretty ( self . 0 ) ?)
160+ Ok ( serde_json:: to_string_pretty ( self ) ?)
80161 }
81162}
82163
83- impl Serialize for StackGraph {
164+ impl Serialize for JsonStackGraph < ' _ > {
84165 fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
85166 where
86167 S : Serializer ,
87168 {
88169 let mut ser = serializer. serialize_struct ( "stack_graph" , 2 ) ?;
89- ser. serialize_field ( "files" , & InStackGraph ( & Files , self ) ) ?;
90- ser. serialize_field ( "nodes" , & InStackGraph ( & Nodes , self ) ) ?;
91- ser. serialize_field ( "edges" , & InStackGraph ( & Edges , self ) ) ?;
170+ ser. serialize_field (
171+ "files" ,
172+ & InStackGraph ( & Files , self . 0 , & ImplicationFilter ( self . 1 ) ) ,
173+ ) ?;
174+ ser. serialize_field (
175+ "nodes" ,
176+ & InStackGraph ( & Nodes , self . 0 , & ImplicationFilter ( self . 1 ) ) ,
177+ ) ?;
178+ ser. serialize_field (
179+ "edges" ,
180+ & InStackGraph ( & Edges , self . 0 , & ImplicationFilter ( self . 1 ) ) ,
181+ ) ?;
92182 ser. end ( )
93183 }
94184}
@@ -98,15 +188,16 @@ impl Serialize for StackGraph {
98188
99189struct Files ;
100190
101- impl Serialize for InStackGraph < ' _ , & Files > {
191+ impl < ' a > Serialize for InStackGraph < ' a , & Files > {
102192 fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
103193 where
104194 S : Serializer ,
105195 {
106196 let graph = self . 1 ;
197+ let filter = self . 2 ;
107198
108199 let mut ser = serializer. serialize_seq ( None ) ?;
109- for file in graph. iter_files ( ) {
200+ for file in graph. iter_files ( ) . filter ( |f| filter . include_file ( graph , f ) ) {
110201 ser. serialize_element ( & self . with_idx ( file) ) ?;
111202 }
112203 ser. end ( )
@@ -133,8 +224,15 @@ impl Serialize for InStackGraph<'_, &Nodes> {
133224 where
134225 S : Serializer ,
135226 {
227+ let graph = self . 1 ;
228+ let filter = self . 2 ;
229+
136230 let mut nodes = serializer. serialize_seq ( None ) ?;
137- for node in self . 1 . iter_nodes ( ) {
231+ for node in self
232+ . 1
233+ . iter_nodes ( )
234+ . filter ( |n| filter. include_node ( graph, & n) )
235+ {
138236 nodes. serialize_element ( & self . with_idx ( node) ) ?;
139237 }
140238 nodes. end ( )
@@ -304,9 +402,16 @@ impl Serialize for InStackGraph<'_, &Edges> {
304402 where
305403 S : Serializer ,
306404 {
405+ let graph = self . 1 ;
406+ let filter = self . 2 ;
407+
307408 let mut ser = serializer. serialize_seq ( None ) ?;
308409 for source in self . 1 . iter_nodes ( ) {
309- for edge in self . 1 . outgoing_edges ( source) {
410+ for edge in self
411+ . 1
412+ . outgoing_edges ( source)
413+ . filter ( |e| filter. include_edge ( graph, & e. source , & e. sink ) )
414+ {
310415 ser. serialize_element ( & self . with ( & edge) ) ?;
311416 }
312417 }
@@ -377,70 +482,67 @@ impl Serialize for InStackGraph<'_, &Offset> {
377482//-----------------------------------------------------------------------------
378483// InPaths
379484
380- struct InPaths < ' a , T > ( T , & ' a Paths , & ' a StackGraph ) ;
485+ struct InPaths < ' a , T > ( T , & ' a Paths , & ' a StackGraph , & ' a dyn Filter ) ;
381486
382487impl < ' a , T > InPaths < ' a , T > {
383488 fn with < U > ( & ' a self , u : U ) -> InPaths < ' a , U > {
384- InPaths ( u, self . 1 , self . 2 )
489+ InPaths ( u, self . 1 , self . 2 , self . 3 )
385490 }
386491
387492 fn in_stack_graph ( & ' a self ) -> InStackGraph < ' a , T >
388493 where
389494 T : Copy ,
390495 {
391- InStackGraph ( self . 0 , self . 2 )
496+ InStackGraph ( self . 0 , self . 2 , self . 3 )
392497 }
393498}
394499
395500//-----------------------------------------------------------------------------
396501// Paths
397502
398503impl < ' a > Paths {
399- pub fn to_json < F > ( & ' a mut self , graph : & ' a StackGraph , f : F ) -> JsonPaths < ' _ , F >
400- where
401- F : FnMut ( & StackGraph , & Paths , & Path ) -> bool ,
402- {
504+ pub fn to_json ( & ' a mut self , graph : & ' a StackGraph , f : & ' a dyn Filter ) -> JsonPaths < ' _ > {
403505 JsonPaths ( self , graph, f)
404506 }
405507}
406508
407- pub struct JsonPaths < ' a , F > ( & ' a mut Paths , & ' a StackGraph , F )
408- where
409- F : FnMut ( & StackGraph , & Paths , & Path ) -> bool ;
509+ pub struct JsonPaths < ' a > ( & ' a mut Paths , & ' a StackGraph , & ' a dyn Filter ) ;
410510
411- impl < ' a , F > JsonPaths < ' a , F >
412- where
413- F : FnMut ( & StackGraph , & Paths , & Path ) -> bool ,
414- {
511+ impl < ' a > JsonPaths < ' a > {
415512 pub fn to_value ( & mut self ) -> Result < Value , JsonError > {
416- let paths = self . to_path_vec ( ) ;
417- Ok ( serde_json:: to_value ( & InPaths ( & paths, self . 0 , self . 1 ) ) ?)
513+ let filter = ImplicationFilter ( self . 2 ) ;
514+ let paths = Self :: to_path_vec ( self . 1 , self . 0 , & filter) ;
515+ Ok ( serde_json:: to_value ( & InPaths (
516+ & paths, self . 0 , self . 1 , & filter,
517+ ) ) ?)
418518 }
419519
420520 pub fn to_string ( & mut self ) -> Result < String , JsonError > {
421- let paths = self . to_path_vec ( ) ;
422- Ok ( serde_json:: to_string ( & InPaths ( & paths, self . 0 , self . 1 ) ) ?)
521+ let filter = ImplicationFilter ( self . 2 ) ;
522+ let paths = Self :: to_path_vec ( self . 1 , self . 0 , & filter) ;
523+ Ok ( serde_json:: to_string ( & InPaths (
524+ & paths, self . 0 , self . 1 , & filter,
525+ ) ) ?)
423526 }
424527
425528 pub fn to_string_pretty ( & mut self ) -> Result < String , JsonError > {
426- let paths = self . to_path_vec ( ) ;
529+ let filter = ImplicationFilter ( self . 2 ) ;
530+ let paths = Self :: to_path_vec ( self . 1 , self . 0 , & filter) ;
427531 Ok ( serde_json:: to_string_pretty ( & InPaths (
428- & paths, self . 0 , self . 1 ,
532+ & paths, self . 0 , self . 1 , & filter ,
429533 ) ) ?)
430534 }
431535
432- fn to_path_vec ( & mut self ) -> Vec < Path > {
433- let mut paths = Vec :: new ( ) ;
434- let f = & mut self . 2 ;
435- self . 0
436- . find_all_paths ( self . 1 , self . 1 . iter_nodes ( ) , |g, ps, p| {
437- if f ( g, ps, & p) {
438- let mut p = p;
439- p. edges . ensure_forwards ( ps) ;
440- paths. push ( p) ;
441- }
442- } ) ;
443- paths
536+ fn to_path_vec ( graph : & StackGraph , paths : & mut Paths , filter : & dyn Filter ) -> Vec < Path > {
537+ let mut path_vec = Vec :: new ( ) ;
538+ paths. find_all_paths ( graph, graph. iter_nodes ( ) , |g, ps, p| {
539+ if filter. include_path ( g, ps, & p) {
540+ let mut p = p;
541+ p. edges . ensure_forwards ( ps) ;
542+ path_vec. push ( p) ;
543+ }
544+ } ) ;
545+ path_vec
444546 }
445547}
446548
0 commit comments