11use crate :: utils:: {
22 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
44} ;
55use if_chain:: if_chain;
66use rustc:: hir:: map:: Map ;
@@ -16,7 +16,8 @@ use rustc_session::{declare_lint_pass, impl_lint_pass};
1616use rustc_span:: source_map:: { Span , Spanned } ;
1717use rustc_span:: symbol:: SymbolStr ;
1818use 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 ;
2021use syntax:: visit:: FnKind ;
2122
2223declare_clippy_lint ! {
@@ -405,104 +406,174 @@ fn is_trigger_fn(fn_kind: FnKind<'_>) -> bool {
405406declare_lint_pass ! ( CollapsibleCalls => [ COLLAPSIBLE_SPAN_LINT_CALLS ] ) ;
406407
407408impl 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+ }
410441
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+ ) ;
506577 }
507578}
508579
0 commit comments