2
2
3
3
use std:: { collections:: HashSet , fmt:: Write , path:: Path , time:: Instant } ;
4
4
5
+ use itertools:: Itertools ;
6
+ use rand:: { seq:: SliceRandom , thread_rng} ;
7
+
5
8
use hir:: {
6
9
db:: { DefDatabase , HirDatabase } ,
7
10
AssocItem , Crate , HasSource , HirDisplay , ModuleDef ,
@@ -19,6 +22,7 @@ pub fn run(
19
22
path : & Path ,
20
23
only : Option < & str > ,
21
24
with_deps : bool ,
25
+ randomize : bool ,
22
26
) -> Result < ( ) > {
23
27
let db_load_time = Instant :: now ( ) ;
24
28
let ( mut host, roots) = ra_batch:: load_cargo ( path) ?;
@@ -41,7 +45,11 @@ pub fn run(
41
45
} )
42
46
. collect :: < HashSet < _ > > ( ) ;
43
47
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 {
45
53
let module = krate. root_module ( db) . expect ( "crate without root module" ) ;
46
54
let file_id = module. definition_source ( db) . file_id ;
47
55
if members. contains ( & db. file_source_root ( file_id. original_file ( db) ) ) {
@@ -50,6 +58,10 @@ pub fn run(
50
58
}
51
59
}
52
60
61
+ if randomize {
62
+ visit_queue. shuffle ( & mut thread_rng ( ) ) ;
63
+ }
64
+
53
65
println ! ( "Crates in this dir: {}" , num_crates) ;
54
66
let mut num_decls = 0 ;
55
67
let mut funcs = Vec :: new ( ) ;
@@ -79,10 +91,14 @@ pub fn run(
79
91
println ! ( "Total functions: {}" , funcs. len( ) ) ;
80
92
println ! ( "Item Collection: {:?}, {}" , analysis_time. elapsed( ) , ra_prof:: memory_usage( ) ) ;
81
93
94
+ if randomize {
95
+ funcs. shuffle ( & mut thread_rng ( ) ) ;
96
+ }
97
+
82
98
let inference_time = Instant :: now ( ) ;
83
99
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 ) ,
86
102
} ;
87
103
88
104
bar. tick ( ) ;
@@ -92,23 +108,36 @@ pub fn run(
92
108
let mut num_type_mismatches = 0 ;
93
109
for f in funcs {
94
110
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) ;
96
125
if verbosity. is_verbose ( ) {
97
126
let src = f. source ( db) ;
98
127
let original_file = src. file_id . original_file ( db) ;
99
128
let path = db. file_relative_path ( original_file) ;
100
129
let syntax_range = src. value . syntax ( ) . text_range ( ) ;
101
130
write ! ( msg, " ({:?} {})" , path, syntax_range) . unwrap ( ) ;
102
131
}
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) ) ;
108
134
}
135
+ bar. set_message ( & msg) ;
109
136
let f_id = FunctionId :: from ( f) ;
110
137
let body = db. body ( f_id. into ( ) ) ;
111
138
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) ;
112
141
for ( expr_id, _) in body. exprs . iter ( ) {
113
142
let ty = & inference_result[ expr_id] ;
114
143
num_exprs += 1 ;
@@ -125,6 +154,33 @@ pub fn run(
125
154
num_exprs_partially_unknown += 1 ;
126
155
}
127
156
}
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
+ }
128
184
if let Some ( mismatch) = inference_result. type_mismatch_for_expr ( expr_id) {
129
185
num_type_mismatches += 1 ;
130
186
if verbosity. is_verbose ( ) {
@@ -164,6 +220,15 @@ pub fn run(
164
220
}
165
221
}
166
222
}
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
+ }
167
232
bar. inc ( 1 ) ;
168
233
}
169
234
bar. finish_and_clear ( ) ;
0 commit comments