Skip to content

Commit a1372eb

Browse files
committed
Implement lint logic.
1 parent cd0ba7c commit a1372eb

File tree

1 file changed

+104
-4
lines changed

1 file changed

+104
-4
lines changed

clippy_lints/src/utils/internal_lints.rs

+104-4
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,
3+
walk_ptrs_ty, snippet_opt
44
};
55
use if_chain::if_chain;
66
use rustc::hir::map::Map;
@@ -404,8 +404,108 @@ fn is_trigger_fn(fn_kind: FnKind<'_>) -> bool {
404404

405405
declare_lint_pass!(CollapsibleCalls => [COLLAPSIBLE_SPAN_LINT_CALLS]);
406406

407-
impl EarlyLintPass for CollapsibleCalls {
407+
impl EarlyLintPass for CollapsibleCalls {
408408
fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &ast::Expr) {
409-
span_lint_and_help(cx, COLLAPSIBLE_SPAN_LINT_CALLS, expr.span, "lint_message", "help_message");
409+
use ast::ExprKind;
410+
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+
}
410506
}
411-
}
507+
}
508+
509+
fn snippet(cx: &EarlyContext<'_>, span: Span) -> String {
510+
snippet_opt(cx, span).expect("should be able to retrive span.")
511+
}

0 commit comments

Comments
 (0)