22
33use  std:: { collections:: HashSet ,  fmt:: Write ,  path:: Path ,  time:: Instant } ; 
44
5+ use  itertools:: Itertools ; 
6+ use  rand:: { seq:: SliceRandom ,  thread_rng} ; 
7+ 
58use  hir:: { 
69    db:: { DefDatabase ,  HirDatabase } , 
710    AssocItem ,  Crate ,  HasSource ,  HirDisplay ,  ModuleDef , 
@@ -19,6 +22,7 @@ pub fn run(
1922    path :  & Path , 
2023    only :  Option < & str > , 
2124    with_deps :  bool , 
25+     randomize :  bool , 
2226)  -> Result < ( ) >  { 
2327    let  db_load_time = Instant :: now ( ) ; 
2428    let  ( mut  host,  roots)  = ra_batch:: load_cargo ( path) ?; 
@@ -41,7 +45,11 @@ pub fn run(
4145            } ) 
4246            . collect :: < HashSet < _ > > ( ) ; 
4347
44-     for  krate in  Crate :: all ( db)  { 
48+     let  mut  krates = Crate :: all ( db) ; 
49+     if  randomize { 
50+         krates. shuffle ( & mut  thread_rng ( ) ) ; 
51+     } 
52+     for  krate in  krates { 
4553        let  module = krate. root_module ( db) . expect ( "crate without root module" ) ; 
4654        let  file_id = module. definition_source ( db) . file_id ; 
4755        if  members. contains ( & db. file_source_root ( file_id. original_file ( db) ) )  { 
@@ -50,6 +58,10 @@ pub fn run(
5058        } 
5159    } 
5260
61+     if  randomize { 
62+         visit_queue. shuffle ( & mut  thread_rng ( ) ) ; 
63+     } 
64+ 
5365    println ! ( "Crates in this dir: {}" ,  num_crates) ; 
5466    let  mut  num_decls = 0 ; 
5567    let  mut  funcs = Vec :: new ( ) ; 
@@ -79,10 +91,14 @@ pub fn run(
7991    println ! ( "Total functions: {}" ,  funcs. len( ) ) ; 
8092    println ! ( "Item Collection: {:?}, {}" ,  analysis_time. elapsed( ) ,  ra_prof:: memory_usage( ) ) ; 
8193
94+     if  randomize { 
95+         funcs. shuffle ( & mut  thread_rng ( ) ) ; 
96+     } 
97+ 
8298    let  inference_time = Instant :: now ( ) ; 
8399    let  mut  bar = match  verbosity { 
84-         Verbosity :: Verbose  | Verbosity :: Normal  => ProgressReport :: new ( funcs . len ( )   as   u64 ) , 
85-         Verbosity :: Quiet  => ProgressReport :: hidden ( ) , 
100+         Verbosity :: Quiet  | Verbosity :: Spammy  => ProgressReport :: hidden ( ) , 
101+         _  => ProgressReport :: new ( funcs . len ( )   as   u64 ) , 
86102    } ; 
87103
88104    bar. tick ( ) ; 
@@ -92,23 +108,36 @@ pub fn run(
92108    let  mut  num_type_mismatches = 0 ; 
93109    for  f in  funcs { 
94110        let  name = f. name ( db) ; 
95-         let  mut  msg = format ! ( "processing: {}" ,  name) ; 
111+         let  full_name = f
112+             . module ( db) 
113+             . path_to_root ( db) 
114+             . into_iter ( ) 
115+             . rev ( ) 
116+             . filter_map ( |it| it. name ( db) ) 
117+             . chain ( Some ( f. name ( db) ) ) 
118+             . join ( "::" ) ; 
119+         if  let  Some ( only_name)  = only { 
120+             if  name. to_string ( )  != only_name && full_name != only_name { 
121+                 continue ; 
122+             } 
123+         } 
124+         let  mut  msg = format ! ( "processing: {}" ,  full_name) ; 
96125        if  verbosity. is_verbose ( )  { 
97126            let  src = f. source ( db) ; 
98127            let  original_file = src. file_id . original_file ( db) ; 
99128            let  path = db. file_relative_path ( original_file) ; 
100129            let  syntax_range = src. value . syntax ( ) . text_range ( ) ; 
101130            write ! ( msg,  " ({:?} {})" ,  path,  syntax_range) . unwrap ( ) ; 
102131        } 
103-         bar. set_message ( & msg) ; 
104-         if  let  Some ( only_name)  = only { 
105-             if  name. to_string ( )  != only_name { 
106-                 continue ; 
107-             } 
132+         if  verbosity. is_spammy ( )  { 
133+             bar. println ( format ! ( "{}" ,  msg) ) ; 
108134        } 
135+         bar. set_message ( & msg) ; 
109136        let  f_id = FunctionId :: from ( f) ; 
110137        let  body = db. body ( f_id. into ( ) ) ; 
111138        let  inference_result = db. infer ( f_id. into ( ) ) ; 
139+         let  ( previous_exprs,  previous_unknown,  previous_partially_unknown)  =
140+             ( num_exprs,  num_exprs_unknown,  num_exprs_partially_unknown) ; 
112141        for  ( expr_id,  _)  in  body. exprs . iter ( )  { 
113142            let  ty = & inference_result[ expr_id] ; 
114143            num_exprs += 1 ; 
@@ -125,6 +154,33 @@ pub fn run(
125154                    num_exprs_partially_unknown += 1 ; 
126155                } 
127156            } 
157+             if  only. is_some ( )  && verbosity. is_spammy ( )  { 
158+                 // in super-verbose mode for just one function, we print every single expression 
159+                 let  ( _,  sm)  = db. body_with_source_map ( f_id. into ( ) ) ; 
160+                 let  src = sm. expr_syntax ( expr_id) ; 
161+                 if  let  Some ( src)  = src { 
162+                     let  original_file = src. file_id . original_file ( db) ; 
163+                     let  line_index = host. analysis ( ) . file_line_index ( original_file) . unwrap ( ) ; 
164+                     let  text_range = src. value . either ( 
165+                         |it| it. syntax_node_ptr ( ) . range ( ) , 
166+                         |it| it. syntax_node_ptr ( ) . range ( ) , 
167+                     ) ; 
168+                     let  ( start,  end)  = ( 
169+                         line_index. line_col ( text_range. start ( ) ) , 
170+                         line_index. line_col ( text_range. end ( ) ) , 
171+                     ) ; 
172+                     bar. println ( format ! ( 
173+                         "{}:{}-{}:{}: {}" , 
174+                         start. line + 1 , 
175+                         start. col_utf16, 
176+                         end. line + 1 , 
177+                         end. col_utf16, 
178+                         ty. display( db) 
179+                     ) ) ; 
180+                 }  else  { 
181+                     bar. println ( format ! ( "unknown location: {}" ,  ty. display( db) ) ) ; 
182+                 } 
183+             } 
128184            if  let  Some ( mismatch)  = inference_result. type_mismatch_for_expr ( expr_id)  { 
129185                num_type_mismatches += 1 ; 
130186                if  verbosity. is_verbose ( )  { 
@@ -164,6 +220,15 @@ pub fn run(
164220                } 
165221            } 
166222        } 
223+         if  verbosity. is_spammy ( )  { 
224+             bar. println ( format ! ( 
225+                 "In {}: {} exprs, {} unknown, {} partial" , 
226+                 full_name, 
227+                 num_exprs - previous_exprs, 
228+                 num_exprs_unknown - previous_unknown, 
229+                 num_exprs_partially_unknown - previous_partially_unknown
230+             ) ) ; 
231+         } 
167232        bar. inc ( 1 ) ; 
168233    } 
169234    bar. finish_and_clear ( ) ; 
0 commit comments