@@ -10,7 +10,11 @@ use hir::{
10
10
db:: { AstDatabase , DefDatabase , HirDatabase } ,
11
11
AssocItem , Crate , Function , HasSource , HirDisplay , ModuleDef ,
12
12
} ;
13
- use hir_def:: { body:: BodySourceMap , expr:: ExprId , FunctionId } ;
13
+ use hir_def:: {
14
+ body:: { BodySourceMap , SyntheticSyntax } ,
15
+ expr:: ExprId ,
16
+ FunctionId ,
17
+ } ;
14
18
use hir_ty:: { TyExt , TypeWalk } ;
15
19
use ide:: { Analysis , AnalysisHost , LineCol , RootDatabase } ;
16
20
use ide_db:: base_db:: {
@@ -28,7 +32,7 @@ use syntax::{AstNode, SyntaxNode};
28
32
use vfs:: { AbsPathBuf , Vfs , VfsPath } ;
29
33
30
34
use crate :: cli:: {
31
- flags,
35
+ flags:: { self , OutputFormat } ,
32
36
load_cargo:: { load_workspace, LoadCargoConfig } ,
33
37
print_memory_usage,
34
38
progress_report:: ProgressReport ,
@@ -191,7 +195,7 @@ impl flags::AnalysisStats {
191
195
) {
192
196
let mut bar = match verbosity {
193
197
Verbosity :: Quiet | Verbosity :: Spammy => ProgressReport :: hidden ( ) ,
194
- _ if self . parallel => ProgressReport :: hidden ( ) ,
198
+ _ if self . parallel || self . output . is_some ( ) => ProgressReport :: hidden ( ) ,
195
199
_ => ProgressReport :: new ( funcs. len ( ) as u64 ) ,
196
200
} ;
197
201
@@ -252,7 +256,7 @@ impl flags::AnalysisStats {
252
256
for ( expr_id, _) in body. exprs . iter ( ) {
253
257
let ty = & inference_result[ expr_id] ;
254
258
num_exprs += 1 ;
255
- if ty. is_unknown ( ) {
259
+ let unknown_or_partial = if ty. is_unknown ( ) {
256
260
num_exprs_unknown += 1 ;
257
261
if verbosity. is_spammy ( ) {
258
262
if let Some ( ( path, start, end) ) =
@@ -270,6 +274,7 @@ impl flags::AnalysisStats {
270
274
bar. println ( format ! ( "{}: Unknown type" , name, ) ) ;
271
275
}
272
276
}
277
+ true
273
278
} else {
274
279
let mut is_partially_unknown = false ;
275
280
ty. walk ( & mut |ty| {
@@ -280,7 +285,8 @@ impl flags::AnalysisStats {
280
285
if is_partially_unknown {
281
286
num_exprs_partially_unknown += 1 ;
282
287
}
283
- }
288
+ is_partially_unknown
289
+ } ;
284
290
if self . only . is_some ( ) && verbosity. is_spammy ( ) {
285
291
// in super-verbose mode for just one function, we print every single expression
286
292
if let Some ( ( _, start, end) ) =
@@ -298,6 +304,13 @@ impl flags::AnalysisStats {
298
304
bar. println ( format ! ( "unknown location: {}" , ty. display( db) ) ) ;
299
305
}
300
306
}
307
+ if unknown_or_partial && self . output == Some ( OutputFormat :: Csv ) {
308
+ println ! (
309
+ r#"{},type,"{}""# ,
310
+ location_csv( db, & analysis, vfs, & sm, expr_id) ,
311
+ ty. display( db)
312
+ ) ;
313
+ }
301
314
if let Some ( mismatch) = inference_result. type_mismatch_for_expr ( expr_id) {
302
315
num_type_mismatches += 1 ;
303
316
if verbosity. is_verbose ( ) {
@@ -323,6 +336,14 @@ impl flags::AnalysisStats {
323
336
) ) ;
324
337
}
325
338
}
339
+ if self . output == Some ( OutputFormat :: Csv ) {
340
+ println ! (
341
+ r#"{},mismatch,"{}","{}""# ,
342
+ location_csv( db, & analysis, vfs, & sm, expr_id) ,
343
+ mismatch. expected. display( db) ,
344
+ mismatch. actual. display( db)
345
+ ) ;
346
+ }
326
347
}
327
348
}
328
349
if verbosity. is_spammy ( ) {
@@ -358,6 +379,28 @@ impl flags::AnalysisStats {
358
379
}
359
380
}
360
381
382
+ fn location_csv (
383
+ db : & RootDatabase ,
384
+ analysis : & Analysis ,
385
+ vfs : & Vfs ,
386
+ sm : & BodySourceMap ,
387
+ expr_id : ExprId ,
388
+ ) -> String {
389
+ let src = match sm. expr_syntax ( expr_id) {
390
+ Ok ( s) => s,
391
+ Err ( SyntheticSyntax ) => return "synthetic,," . to_string ( ) ,
392
+ } ;
393
+ let root = db. parse_or_expand ( src. file_id ) . unwrap ( ) ;
394
+ let node = src. map ( |e| e. to_node ( & root) . syntax ( ) . clone ( ) ) ;
395
+ let original_range = node. as_ref ( ) . original_file_range ( db) ;
396
+ let path = vfs. file_path ( original_range. file_id ) ;
397
+ let line_index = analysis. file_line_index ( original_range. file_id ) . unwrap ( ) ;
398
+ let text_range = original_range. range ;
399
+ let ( start, end) =
400
+ ( line_index. line_col ( text_range. start ( ) ) , line_index. line_col ( text_range. end ( ) ) ) ;
401
+ format ! ( "{},{}:{},{}:{}" , path, start. line + 1 , start. col, end. line + 1 , end. col)
402
+ }
403
+
361
404
fn expr_syntax_range (
362
405
db : & RootDatabase ,
363
406
analysis : & Analysis ,
0 commit comments