blob: fd51bca9e5be521f9382f9ce4b93f27bd9cd0e6d [file] [log] [blame]
use clippy_utils::diagnostics::span_lint;
use rustc_ast::ast::{Crate, ItemKind, ModKind};
use rustc_lint::{EarlyContext, EarlyLintPass};
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
/// ### What it does
/// Checks that [`clippy_utils::paths`] is sorted lexically
///
/// ### Why is this bad?
/// We like to pretend we're an example of tidy code.
///
/// ### Example
/// Wrong ordering of the util::paths constants.
pub UNSORTED_CLIPPY_UTILS_PATHS,
internal,
"various things that will negatively affect your clippy experience"
}
declare_lint_pass!(UnsortedClippyUtilsPaths => [UNSORTED_CLIPPY_UTILS_PATHS]);
impl EarlyLintPass for UnsortedClippyUtilsPaths {
fn check_crate(&mut self, cx: &EarlyContext<'_>, krate: &Crate) {
if let Some(utils) = krate.items.iter().find(|item| item.ident.name.as_str() == "utils") {
if let ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) = utils.kind {
if let Some(paths) = items.iter().find(|item| item.ident.name.as_str() == "paths") {
if let ItemKind::Mod(_, ModKind::Loaded(ref items, ..)) = paths.kind {
let mut last_name: Option<&str> = None;
for item in items {
let name = item.ident.as_str();
if let Some(last_name) = last_name {
if *last_name > *name {
span_lint(
cx,
UNSORTED_CLIPPY_UTILS_PATHS,
item.span,
"this constant should be before the previous constant due to lexical \
ordering",
);
}
}
last_name = Some(name);
}
}
}
}
}
}
}