#![feature(rustc_private)]
extern crate rustc_ast;
extern crate rustc_hir;
extern crate rustc_lint;
extern crate rustc_session;
extern crate rustc_span;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::intravisit::FnKind;
use rustc_hir::{Body, FnDecl};
use rustc_lint::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext, LintStore};
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::Span;
use rustc_tools::with_lints;
declare_tool_lint! {
pub lint::WARN_GENERICS,
Warn,
"warns if any item has generics",
report_in_external_macro: false
}
declare_lint_pass!(WarnGenerics => [WARN_GENERICS]);
impl EarlyLintPass for WarnGenerics {
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
if let Some(generics) = item.kind.generics() {
if generics.params.is_empty() {
return;
}
cx.struct_span_lint(WARN_GENERICS, generics.span, "generics are ugly", |diag| {
diag
});
}
}
}
declare_tool_lint! {
pub lint::ODD_FUNCTION_LINE_COUNT,
Deny,
"errors if a function has an odd number of lines",
report_in_external_macro: false
}
declare_lint_pass!(OddFunctionLineCount => [ODD_FUNCTION_LINE_COUNT]);
impl LateLintPass<'_> for OddFunctionLineCount {
fn check_fn(
&mut self,
cx: &LateContext<'_>,
_: FnKind<'_>,
_: &FnDecl<'_>,
body: &Body<'_>,
span: Span,
_: LocalDefId,
) {
if span.from_expansion() {
return;
}
if let Ok(code) = cx.sess().source_map().span_to_snippet(body.value.span) {
let code = &code[1..code.len() - 1];
if !code.is_empty() && code.split('\n').count() % 2 != 0 {
cx.struct_span_lint(
ODD_FUNCTION_LINE_COUNT,
span,
"functions with odd number of lines should not exist",
|diag| diag,
);
}
}
}
}
fn main() -> Result<(), ()> {
let args: Vec<String> = std::env::args().collect();
if args.is_empty() {
eprintln!("Missing file operand");
return Err(());
}
println!("Running lint example with arguments `{:?}`", args);
with_lints(&args, vec![], |store: &mut LintStore| {
store.register_early_pass(|| Box::new(WarnGenerics));
store.register_late_pass(|_| Box::new(OddFunctionLineCount));
})
.map(|_| ())
.map_err(|_| ())
}