@@ -14,6 +14,7 @@ use crate::arena::Handle;
1414use crate :: graph:: File ;
1515use crate :: graph:: Node ;
1616use crate :: graph:: StackGraph ;
17+ use crate :: graph:: Symbol ;
1718use crate :: paths:: Path ;
1819use crate :: paths:: Paths ;
1920use crate :: CancellationError ;
@@ -26,6 +27,14 @@ pub enum Assertion {
2627 source : AssertionSource ,
2728 targets : Vec < AssertionTarget > ,
2829 } ,
30+ Defines {
31+ source : AssertionSource ,
32+ symbols : Vec < Handle < Symbol > > ,
33+ } ,
34+ Refers {
35+ source : AssertionSource ,
36+ symbols : Vec < Handle < Symbol > > ,
37+ } ,
2938}
3039
3140/// Source position of an assertion
@@ -36,7 +45,20 @@ pub struct AssertionSource {
3645}
3746
3847impl AssertionSource {
39- fn reference_iter < ' a > (
48+ fn definitions_iter < ' a > (
49+ & ' a self ,
50+ graph : & ' a StackGraph ,
51+ ) -> impl Iterator < Item = Handle < Node > > + ' a {
52+ graph. nodes_for_file ( self . file ) . filter ( move |n| {
53+ graph[ * n] . is_definition ( )
54+ && graph
55+ . source_info ( * n)
56+ . map ( |s| s. span . contains ( & self . position ) )
57+ . unwrap_or ( false )
58+ } )
59+ }
60+
61+ fn references_iter < ' a > (
4062 & ' a self ,
4163 graph : & ' a StackGraph ,
4264 ) -> impl Iterator < Item = Handle < Node > > + ' a {
@@ -74,12 +96,22 @@ pub enum AssertionError {
7496 NoReferences {
7597 source : AssertionSource ,
7698 } ,
77- IncorrectDefinitions {
99+ IncorrectlyDefined {
78100 source : AssertionSource ,
79101 references : Vec < Handle < Node > > ,
80102 missing_targets : Vec < AssertionTarget > ,
81103 unexpected_paths : Vec < Path > ,
82104 } ,
105+ IncorrectDefinitions {
106+ source : AssertionSource ,
107+ missing_symbols : Vec < Handle < Symbol > > ,
108+ unexpected_symbols : Vec < Handle < Symbol > > ,
109+ } ,
110+ IncorrectReferences {
111+ source : AssertionSource ,
112+ missing_symbols : Vec < Handle < Symbol > > ,
113+ unexpected_symbols : Vec < Handle < Symbol > > ,
114+ } ,
83115 Cancelled ( CancellationError ) ,
84116}
85117
@@ -98,9 +130,11 @@ impl Assertion {
98130 cancellation_flag : & dyn CancellationFlag ,
99131 ) -> Result < ( ) , AssertionError > {
100132 match self {
101- Assertion :: Defined { source, targets } => {
133+ Self :: Defined { source, targets } => {
102134 self . run_defined ( graph, paths, source, targets, cancellation_flag)
103135 }
136+ Self :: Defines { source, symbols } => self . run_defines ( graph, source, symbols) ,
137+ Self :: Refers { source, symbols } => self . run_refers ( graph, source, symbols) ,
104138 }
105139 }
106140
@@ -112,7 +146,7 @@ impl Assertion {
112146 expected_targets : & Vec < AssertionTarget > ,
113147 cancellation_flag : & dyn CancellationFlag ,
114148 ) -> Result < ( ) , AssertionError > {
115- let references = source. reference_iter ( graph) . collect :: < Vec < _ > > ( ) ;
149+ let references = source. references_iter ( graph) . collect :: < Vec < _ > > ( ) ;
116150 if references. is_empty ( ) {
117151 return Err ( AssertionError :: NoReferences {
118152 source : source. clone ( ) ,
@@ -146,7 +180,7 @@ impl Assertion {
146180 . cloned ( )
147181 . collect :: < Vec < _ > > ( ) ;
148182 if !missing_targets. is_empty ( ) || !unexpected_paths. is_empty ( ) {
149- return Err ( AssertionError :: IncorrectDefinitions {
183+ return Err ( AssertionError :: IncorrectlyDefined {
150184 source : source. clone ( ) ,
151185 references,
152186 missing_targets,
@@ -156,4 +190,68 @@ impl Assertion {
156190
157191 Ok ( ( ) )
158192 }
193+
194+ fn run_defines (
195+ & self ,
196+ graph : & StackGraph ,
197+ source : & AssertionSource ,
198+ expected_symbols : & Vec < Handle < Symbol > > ,
199+ ) -> Result < ( ) , AssertionError > {
200+ let actual_symbols = source
201+ . definitions_iter ( graph)
202+ . filter_map ( |d| graph[ d] . symbol ( ) )
203+ . collect :: < Vec < _ > > ( ) ;
204+ let missing_symbols = expected_symbols
205+ . iter ( )
206+ . filter ( |x| !actual_symbols. contains ( * x) )
207+ . cloned ( )
208+ . unique ( )
209+ . collect :: < Vec < _ > > ( ) ;
210+ let unexpected_symbols = actual_symbols
211+ . iter ( )
212+ . filter ( |x| !expected_symbols. contains ( * x) )
213+ . cloned ( )
214+ . unique ( )
215+ . collect :: < Vec < _ > > ( ) ;
216+ if !missing_symbols. is_empty ( ) || !unexpected_symbols. is_empty ( ) {
217+ return Err ( AssertionError :: IncorrectDefinitions {
218+ source : source. clone ( ) ,
219+ missing_symbols,
220+ unexpected_symbols,
221+ } ) ;
222+ }
223+ Ok ( ( ) )
224+ }
225+
226+ fn run_refers (
227+ & self ,
228+ graph : & StackGraph ,
229+ source : & AssertionSource ,
230+ expected_symbols : & Vec < Handle < Symbol > > ,
231+ ) -> Result < ( ) , AssertionError > {
232+ let actual_symbols = source
233+ . references_iter ( graph)
234+ . filter_map ( |d| graph[ d] . symbol ( ) )
235+ . collect :: < Vec < _ > > ( ) ;
236+ let missing_symbols = expected_symbols
237+ . iter ( )
238+ . filter ( |x| !actual_symbols. contains ( * x) )
239+ . cloned ( )
240+ . unique ( )
241+ . collect :: < Vec < _ > > ( ) ;
242+ let unexpected_symbols = actual_symbols
243+ . iter ( )
244+ . filter ( |x| !expected_symbols. contains ( * x) )
245+ . cloned ( )
246+ . unique ( )
247+ . collect :: < Vec < _ > > ( ) ;
248+ if !missing_symbols. is_empty ( ) || !unexpected_symbols. is_empty ( ) {
249+ return Err ( AssertionError :: IncorrectReferences {
250+ source : source. clone ( ) ,
251+ missing_symbols,
252+ unexpected_symbols,
253+ } ) ;
254+ }
255+ Ok ( ( ) )
256+ }
159257}
0 commit comments