Skip to content

Commit c9375e2

Browse files
committed
Revise lint logic.
1 parent a1372eb commit c9375e2

File tree

2 files changed

+176
-105
lines changed

2 files changed

+176
-105
lines changed

clippy_lints/src/utils/internal_lints.rs

Lines changed: 170 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use 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
};
55
use if_chain::if_chain;
66
use rustc::hir::map::Map;
@@ -16,7 +16,8 @@ use rustc_session::{declare_lint_pass, impl_lint_pass};
1616
use rustc_span::source_map::{Span, Spanned};
1717
use rustc_span::symbol::SymbolStr;
1818
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;
2021
use syntax::visit::FnKind;
2122

2223
declare_clippy_lint! {
@@ -405,104 +406,174 @@ fn is_trigger_fn(fn_kind: FnKind<'_>) -> bool {
405406
declare_lint_pass!(CollapsibleCalls => [COLLAPSIBLE_SPAN_LINT_CALLS]);
406407

407408
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+
}
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

tests/ui/collapsible_span_lint_calls.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
// run-rustfix
22
#![deny(clippy::internal)]
3-
#![feature(rustc_private)]
3+
#![feature(rustc_private)]
44

5-
extern crate rustc_session;
6-
extern crate rustc_errors;
7-
extern crate rustc_lint;
8-
extern crate syntax;
9-
extern crate rustc_span;
5+
extern crate rustc_session;
6+
extern crate rustc_errors;
7+
extern crate rustc_lint;
8+
extern crate syntax;
9+
extern crate rustc_span;
1010

1111
use rustc_session::{declare_tool_lint, declare_lint_pass};
1212
use rustc_errors::{DiagnosticBuilder, Applicability};

0 commit comments

Comments
 (0)