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