1
1
use crate :: utils:: {
2
2
is_expn_of, match_def_path, match_type, method_calls, paths, span_lint, span_lint_and_help, span_lint_and_sugg,
3
- walk_ptrs_ty, snippet_opt
3
+ walk_ptrs_ty, snippet_opt, match_path_ast
4
4
} ;
5
5
use if_chain:: if_chain;
6
6
use rustc:: hir:: map:: Map ;
@@ -16,7 +16,8 @@ use rustc_session::{declare_lint_pass, impl_lint_pass};
16
16
use rustc_span:: source_map:: { Span , Spanned } ;
17
17
use rustc_span:: symbol:: SymbolStr ;
18
18
use syntax:: ast;
19
- use syntax:: ast:: { Crate as AstCrate , ItemKind , LitKind , Name } ;
19
+ use syntax:: ast:: { Crate as AstCrate , ItemKind , LitKind , Name , Expr as AstExpr } ;
20
+ use syntax:: ptr:: P ;
20
21
use syntax:: visit:: FnKind ;
21
22
22
23
declare_clippy_lint ! {
@@ -405,104 +406,174 @@ fn is_trigger_fn(fn_kind: FnKind<'_>) -> bool {
405
406
declare_lint_pass ! ( CollapsibleCalls => [ COLLAPSIBLE_SPAN_LINT_CALLS ] ) ;
406
407
407
408
impl EarlyLintPass for CollapsibleCalls {
408
- fn check_expr ( & mut self , cx : & EarlyContext < ' _ > , expr : & ast:: Expr ) {
409
- use ast:: ExprKind ;
409
+ fn check_expr ( & mut self , cx : & EarlyContext < ' _ > , expr : & AstExpr ) {
410
+ use ast:: { StmtKind , ExprKind } ;
411
+
412
+ span_lint_and_help ( cx, COLLAPSIBLE_SPAN_LINT_CALLS , expr. span , "lint message" , "help message" ) ;
413
+
414
+ // if_chain! {
415
+ // if let ExprKind::Call(ref func, ref and_then_args) = expr.kind;
416
+ // if let ExprKind::Path(None, ref path) = func.kind;
417
+ // if match_path_ast(path, &["span_lint_and_then"]);
418
+ // if and_then_args.len() == 5;
419
+ // if let ExprKind::Closure(_, _, _, _, block, _) = &and_then_args[4].kind;
420
+ // if let ExprKind::Block(block, _) = &block.kind;
421
+ // let stmts = &block.stmts;
422
+ // if stmts.len() == 1;
423
+ // if let StmtKind::Expr(only_expr) = &stmts[0].kind;
424
+ // if let ExprKind::MethodCall(ref ps, ref span_call_args) = &only_expr.kind;
425
+ // let and_then_args = get_and_then_args(cx, and_then_args);
426
+ // then {
427
+ // match &*ps.ident.as_str() {
428
+ // "span_suggestion" =>
429
+ // suggest_span_suggestion(cx, expr, and_then_args, suggestion_args(cx, span_call_args)),
430
+ // "span_help" =>
431
+ // suggest_span_help(cx, expr, and_then_args, help_args(cx, span_call_args)),
432
+ // "span_note" =>
433
+ // suggest_span_note(cx, expr, and_then_args, note_args(cx, span_call_args)),
434
+ // _ => (),
435
+ // }
436
+ // span_lint_and_help(cx, COLLAPSIBLE_SPAN_LINT_CALLS, expr.span, "lint message", "help message");
437
+ // }
438
+ // }
439
+ }
440
+ }
410
441
411
- if_chain ! {
412
- if let ExprKind :: Call ( ref func, ref and_then_args) = expr. kind;
413
- if let ExprKind :: Path ( None , ref path) = func. kind;
414
- if let match_path_ast( path, & [ "span_lint_and_then" ] ) ;
415
- if and_then_args. len( ) == 5 ;
416
- if let ExprKind :: Closure ( _, _, _, _, block) = and_then_args[ 4 ] . kind;
417
- if let ExprKind :: Block ( block, _) = block. kind;
418
- let stmts = block. stmts;
419
- if stmts. len( ) == 1 ;
420
- if let StmtKind :: Expr ( only_expr) = stmts[ 0 ] . kind;
421
- if let ExprKind :: MethodCall ( ps, span_call_args) = only_expr. kind;
422
- then {
423
- let cx_snippet = snippet( cx, and_then_args[ 0 ] . span) ;
424
- let lint_snippet= snippet( cx, and_then_args[ 1 ] . span) ;
425
- let span_snippet = snippet( cx, and_then_args[ 2 ] . span) ;
426
- let msg_snippet= snippet( cx, and_then_args[ 3 ] . span) ;
427
-
428
- match ps. ident. name. as_str( ) {
429
- "span_suggestion" => {
430
- let span_snippet_of_span_call = snippet( cx, span_call_args[ 0 ] . span) ;
431
- let help_snippet = snippet( cx, span_call_args[ 1 ] . span) ;
432
- let sugg_snippet = snippet( cx, span_call_args[ 2 ] . span) ;
433
- let applicability_snippet = snippet( cx, span_call_args[ 3 ] . span) ;
434
-
435
- if span_snippet == span_snippet_of_span_call {
436
- span_lint_and_sugg (
437
- cx,
438
- COLLAPSIBLE_SPAN_LINT_CALLS ,
439
- expr. span,
440
- "this call is collapsible" ,
441
- "collapse into" ,
442
- format!(
443
- "span_lint_and_sugg({}, {}, {}, {}, {}, {},{})" ,
444
- cx_snippet,
445
- lint_snippet,
446
- span_snippet,
447
- msg_snippet,
448
- help_snippet,
449
- sugg_snippet,
450
- applicability_snippet
451
- ) ,
452
- Applicability :: MachineApplicable
453
- ) ;
454
- }
455
- } ,
456
- "span_help" => {
457
- let span_snippet_of_span_call = snippet( cx, span_call_args[ 0 ] . span) ;
458
- let help_snippet = snippet( cx, span_call_args[ 1 ] . span) ;
459
-
460
- if span_snippet == span_snippet_of_span_call {
461
- span_lint_and_sugg(
462
- cx,
463
- COLLAPSIBLE_SPAN_LINT_CALLS ,
464
- expr. span,
465
- "this call is collapsible" ,
466
- "collapse into" ,
467
- format!(
468
- "span_lint_and_help({}, {}, {}, {},{})" ,
469
- cx_snippet,
470
- lint_snippet,
471
- span_snippet,
472
- msg_snippet,
473
- help_snippet
474
- ) ,
475
- Applicability :: MachineApplicable
476
- ) ;
477
- }
478
- } ,
479
- "span_note" => {
480
- let span_snippet_of_span_call = snippet( cx, span_call_args[ 0 ] . span) ;
481
- let note_snippet = snippet( cx, span_call_args[ 1 ] . span) ;
482
-
483
- if span_snippet == span_snippet_of_span_call {
484
- span_lint_and_sugg(
485
- cx,
486
- COLLAPSIBLE_SPAN_LINT_CALLS ,
487
- expr. span,
488
- "this call is collspible" ,
489
- "collapse into" ,
490
- format!(
491
- "span_lint_and_note({},{}, {}, {}, {})" ,
492
- cx_snippet,
493
- lint_snippet,
494
- span_snippet,
495
- msg_snippet,
496
- note_snippet
497
- ) ,
498
- Applicability :: MachineApplicable
499
- ) ;
500
- }
501
- } ,
502
- _ => ( ) ,
503
- }
504
- }
505
- }
442
+ struct AndThenArgs {
443
+ cx : String ,
444
+ lint : String ,
445
+ span : String ,
446
+ msg : String ,
447
+ }
448
+
449
+ fn get_and_then_args ( cx : & EarlyContext < ' _ > , and_then_args : & Vec < P < AstExpr > > ) -> AndThenArgs {
450
+ let cx_snippet = snippet ( cx, and_then_args[ 0 ] . span ) ;
451
+ let lint_snippet= snippet ( cx, and_then_args[ 1 ] . span ) ;
452
+ let span_snippet = snippet ( cx, and_then_args[ 2 ] . span ) ;
453
+ let msg_snippet= snippet ( cx, and_then_args[ 3 ] . span ) ;
454
+
455
+ AndThenArgs {
456
+ cx : cx_snippet,
457
+ lint : lint_snippet,
458
+ span : span_snippet,
459
+ msg : msg_snippet,
460
+ }
461
+ }
462
+
463
+ struct SuggestionArgs {
464
+ span : String ,
465
+ help : String ,
466
+ sugg : String ,
467
+ applicability : String ,
468
+ }
469
+
470
+ fn suggestion_args ( cx : & EarlyContext < ' _ > , span_call_args : & Vec < P < AstExpr > > ) -> SuggestionArgs {
471
+ let span_snippet_of_span_call = snippet ( cx, span_call_args[ 0 ] . span ) ;
472
+ let help_snippet = snippet ( cx, span_call_args[ 1 ] . span ) ;
473
+ let sugg_snippet = snippet ( cx, span_call_args[ 2 ] . span ) ;
474
+ let applicability_snippet = snippet ( cx, span_call_args[ 3 ] . span ) ;
475
+
476
+ SuggestionArgs {
477
+ span : span_snippet_of_span_call,
478
+ help : help_snippet,
479
+ sugg : sugg_snippet,
480
+ applicability : applicability_snippet,
481
+ }
482
+ }
483
+
484
+ fn suggest_span_suggestion ( cx : & EarlyContext < ' _ > , expr : & AstExpr , and_then_args : AndThenArgs , suggestion_args : SuggestionArgs ) {
485
+ if and_then_args. span == suggestion_args. span {
486
+ println ! ( "suggestion true" ) ;
487
+ span_lint_and_sugg (
488
+ cx,
489
+ COLLAPSIBLE_SPAN_LINT_CALLS ,
490
+ expr. span ,
491
+ "this call is collapsible" ,
492
+ "collapse into" ,
493
+ format ! (
494
+ "span_lint_and_sugg({}, {}, {}, {}, {}, {},{})" ,
495
+ and_then_args. cx,
496
+ and_then_args. lint,
497
+ and_then_args. span,
498
+ and_then_args. msg,
499
+ suggestion_args. help,
500
+ suggestion_args. sugg,
501
+ suggestion_args. applicability
502
+ ) ,
503
+ Applicability :: MachineApplicable
504
+ ) ;
505
+ }
506
+ }
507
+
508
+ struct HelpArgs {
509
+ span : String ,
510
+ help : String ,
511
+ }
512
+
513
+ fn help_args ( cx : & EarlyContext < ' _ > , span_call_args : & Vec < P < AstExpr > > ) -> HelpArgs {
514
+ let span_snippet_of_span_call = snippet ( cx, span_call_args[ 0 ] . span ) ;
515
+ let help_snippet = snippet ( cx, span_call_args[ 1 ] . span ) ;
516
+
517
+ HelpArgs {
518
+ span : span_snippet_of_span_call,
519
+ help : help_snippet,
520
+ }
521
+ }
522
+
523
+ fn suggest_span_help ( cx : & EarlyContext < ' _ > , expr : & AstExpr , and_then_args : AndThenArgs , help_args : HelpArgs ) {
524
+ if and_then_args. span == help_args. span {
525
+ span_lint_and_sugg (
526
+ cx,
527
+ COLLAPSIBLE_SPAN_LINT_CALLS ,
528
+ expr. span ,
529
+ "this call is collapsible" ,
530
+ "collapse into" ,
531
+ format ! (
532
+ "span_lint_and_help({}, {}, {}, {},{})" ,
533
+ and_then_args. cx,
534
+ and_then_args. lint,
535
+ and_then_args. span,
536
+ and_then_args. msg,
537
+ help_args. help
538
+ ) ,
539
+ Applicability :: MachineApplicable
540
+ ) ;
541
+ }
542
+ }
543
+
544
+ struct NoteArgs {
545
+ span : String ,
546
+ note : String ,
547
+ }
548
+
549
+ fn note_args ( cx : & EarlyContext < ' _ > , span_call_args : & Vec < P < AstExpr > > ) -> NoteArgs {
550
+ let span_snippet_of_span_call = snippet ( cx, span_call_args[ 0 ] . span ) ;
551
+ let note_snippet = snippet ( cx, span_call_args[ 1 ] . span ) ;
552
+
553
+ NoteArgs {
554
+ span : span_snippet_of_span_call,
555
+ note : note_snippet,
556
+ }
557
+ }
558
+
559
+ fn suggest_span_note ( cx : & EarlyContext < ' _ > , expr : & AstExpr , and_then_args : AndThenArgs , note_args : NoteArgs ) {
560
+ if and_then_args. span == note_args. span {
561
+ span_lint_and_sugg (
562
+ cx,
563
+ COLLAPSIBLE_SPAN_LINT_CALLS ,
564
+ expr. span ,
565
+ "this call is collspible" ,
566
+ "collapse into" ,
567
+ format ! (
568
+ "span_lint_and_note({},{}, {}, {}, {})" ,
569
+ and_then_args. cx,
570
+ and_then_args. lint,
571
+ and_then_args. span,
572
+ and_then_args. msg,
573
+ note_args. note
574
+ ) ,
575
+ Applicability :: MachineApplicable
576
+ ) ;
506
577
}
507
578
}
508
579
0 commit comments