Skip to content

Commit b9050d4

Browse files
committed
Revise lint logic.
1 parent f6c5232 commit b9050d4

File tree

2 files changed

+178
-104
lines changed

2 files changed

+178
-104
lines changed

clippy_lints/src/utils/internal_lints.rs

Lines changed: 172 additions & 98 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,6 +16,10 @@ use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass};
1616
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
1717
use rustc_span::source_map::{Span, Spanned};
1818
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;
1923

2024
declare_clippy_lint! {
2125
/// **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 {
401405
declare_lint_pass!(CollapsibleCalls => [COLLAPSIBLE_SPAN_LINT_CALLS]);
402406

403407
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+
}
406440

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+
);
502576
}
503577
}
504578

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)