@@ -67,16 +67,20 @@ mod handlers {
67
67
#[ cfg( test) ]
68
68
mod tests;
69
69
70
+ use std:: collections:: HashMap ;
71
+
70
72
use hir:: { diagnostics:: AnyDiagnostic , InFile , Semantics } ;
71
73
use ide_db:: {
72
74
assists:: { Assist , AssistId , AssistKind , AssistResolveStrategy } ,
73
75
base_db:: { FileId , FileRange , SourceDatabase } ,
76
+ generated:: lints:: { LintGroup , CLIPPY_LINT_GROUPS , DEFAULT_LINT_GROUPS } ,
74
77
imports:: insert_use:: InsertUseConfig ,
75
78
label:: Label ,
76
79
source_change:: SourceChange ,
77
80
syntax_helpers:: node_ext:: parse_tt_as_comma_sep_paths,
78
81
FxHashMap , FxHashSet , RootDatabase ,
79
82
} ;
83
+ use once_cell:: sync:: Lazy ;
80
84
use stdx:: never;
81
85
use syntax:: {
82
86
algo:: find_node_at_range,
@@ -370,7 +374,7 @@ pub fn diagnostics(
370
374
let mut rustc_stack: FxHashMap < String , Vec < Severity > > = FxHashMap :: default ( ) ;
371
375
let mut clippy_stack: FxHashMap < String , Vec < Severity > > = FxHashMap :: default ( ) ;
372
376
373
- fun_name (
377
+ handle_lint_attributes (
374
378
& ctx. sema ,
375
379
parse. syntax ( ) ,
376
380
& mut rustc_stack,
@@ -387,7 +391,30 @@ pub fn diagnostics(
387
391
res
388
392
}
389
393
390
- fn fun_name (
394
+ static RUSTC_LINT_GROUPS_DICT : Lazy < HashMap < & str , Vec < & str > > > =
395
+ Lazy :: new ( || build_group_dict ( DEFAULT_LINT_GROUPS , & [ "warnings" ] ) ) ;
396
+
397
+ static CLIPPY_LINT_GROUPS_DICT : Lazy < HashMap < & str , Vec < & str > > > =
398
+ Lazy :: new ( || build_group_dict ( CLIPPY_LINT_GROUPS , & [ ] ) ) ;
399
+
400
+ fn build_group_dict (
401
+ lint_group : & ' static [ LintGroup ] ,
402
+ all_groups : & ' static [ & ' static str ] ,
403
+ ) -> HashMap < & ' static str , Vec < & ' static str > > {
404
+ let mut r: HashMap < & str , Vec < & str > > = HashMap :: new ( ) ;
405
+ for g in lint_group {
406
+ for child in g. children {
407
+ r. entry ( child) . or_default ( ) . push ( g. lint . label ) ;
408
+ }
409
+ }
410
+ for ( lint, groups) in r. iter_mut ( ) {
411
+ groups. push ( lint) ;
412
+ groups. extend_from_slice ( all_groups) ;
413
+ }
414
+ r
415
+ }
416
+
417
+ fn handle_lint_attributes (
391
418
sema : & Semantics < ' _ , RootDatabase > ,
392
419
root : & SyntaxNode ,
393
420
rustc_stack : & mut FxHashMap < String , Vec < Severity > > ,
@@ -406,18 +433,33 @@ fn fun_name(
406
433
if let Some ( x) =
407
434
diagnostics_of_range. get_mut ( & InFile { file_id, value : node. clone ( ) } )
408
435
{
409
- let ( name, stack) = match x. code {
410
- DiagnosticOrigin :: RustcLint ( name) => ( name, & mut * rustc_stack) ,
411
- DiagnosticOrigin :: Clippy ( name) => ( name, & mut * clippy_stack) ,
436
+ const EMPTY_LINTS : & [ & str ] = & [ ] ;
437
+ let ( names, stack) = match x. code {
438
+ DiagnosticOrigin :: RustcLint ( name) => (
439
+ RUSTC_LINT_GROUPS_DICT . get ( name) . map_or ( EMPTY_LINTS , |x| & * * x) ,
440
+ & mut * rustc_stack,
441
+ ) ,
442
+ DiagnosticOrigin :: Clippy ( name) => (
443
+ CLIPPY_LINT_GROUPS_DICT . get ( name) . map_or ( EMPTY_LINTS , |x| & * * x) ,
444
+ & mut * clippy_stack,
445
+ ) ,
412
446
_ => continue ,
413
447
} ;
414
- if let Some ( s) = stack. get ( name) . and_then ( |x| x. last ( ) ) {
415
- x. severity = * s;
448
+ for & name in names {
449
+ if let Some ( s) = stack. get ( name) . and_then ( |x| x. last ( ) ) {
450
+ x. severity = * s;
451
+ }
416
452
}
417
453
}
418
454
if let Some ( mc) = ast:: MacroCall :: cast ( node) {
419
455
if let Some ( me) = sema. expand ( & mc) {
420
- fun_name ( sema, & me, rustc_stack, clippy_stack, diagnostics_of_range) ;
456
+ handle_lint_attributes (
457
+ sema,
458
+ & me,
459
+ rustc_stack,
460
+ clippy_stack,
461
+ diagnostics_of_range,
462
+ ) ;
421
463
}
422
464
}
423
465
}
0 commit comments