提交 76856e19 编写于 作者: N Nick Cameron

Add an early lint pass for lints that operate on the AST

There is a minor [breaking-change] for lint authors - some functions which were previously defined on `lint::Context` have moved to a trait - `LintContext`, you may need to import that trait to avoid name resolution errors.
上级 f18c2aaf
此差异已折叠。
......@@ -35,10 +35,12 @@
use std::ascii::AsciiExt;
use syntax::codemap::Span;
use rustc_front::visit::FnKind;
use syntax::visit as ast_visit;
use syntax::ast;
use rustc_front::hir;
pub use lint::context::{Context, LintStore, raw_emit_lint, check_crate, gather_attrs,
pub use lint::context::{LateContext, EarlyContext, Context, LintContext, LintStore,
raw_emit_lint, check_crate, check_ast_crate, gather_attrs,
GatherNodeLevels};
/// Specification of a single lint.
......@@ -126,46 +128,92 @@ pub trait LintPass {
/// `Lint`, make it a private `static` item in its own module.
fn get_lints(&self) -> LintArray;
fn check_crate(&mut self, _: &Context, _: &hir::Crate) { }
fn check_ident(&mut self, _: &Context, _: Span, _: ast::Ident) { }
fn check_mod(&mut self, _: &Context, _: &hir::Mod, _: Span, _: ast::NodeId) { }
fn check_foreign_item(&mut self, _: &Context, _: &hir::ForeignItem) { }
fn check_item(&mut self, _: &Context, _: &hir::Item) { }
fn check_local(&mut self, _: &Context, _: &hir::Local) { }
fn check_block(&mut self, _: &Context, _: &hir::Block) { }
fn check_stmt(&mut self, _: &Context, _: &hir::Stmt) { }
fn check_arm(&mut self, _: &Context, _: &hir::Arm) { }
fn check_pat(&mut self, _: &Context, _: &hir::Pat) { }
fn check_decl(&mut self, _: &Context, _: &hir::Decl) { }
fn check_expr(&mut self, _: &Context, _: &hir::Expr) { }
fn check_expr_post(&mut self, _: &Context, _: &hir::Expr) { }
fn check_ty(&mut self, _: &Context, _: &hir::Ty) { }
fn check_generics(&mut self, _: &Context, _: &hir::Generics) { }
fn check_fn(&mut self, _: &Context,
fn check_ident(&mut self, _: &LateContext, _: Span, _: ast::Ident) { }
fn check_crate(&mut self, _: &LateContext, _: &hir::Crate) { }
fn check_mod(&mut self, _: &LateContext, _: &hir::Mod, _: Span, _: ast::NodeId) { }
fn check_foreign_item(&mut self, _: &LateContext, _: &hir::ForeignItem) { }
fn check_item(&mut self, _: &LateContext, _: &hir::Item) { }
fn check_local(&mut self, _: &LateContext, _: &hir::Local) { }
fn check_block(&mut self, _: &LateContext, _: &hir::Block) { }
fn check_stmt(&mut self, _: &LateContext, _: &hir::Stmt) { }
fn check_arm(&mut self, _: &LateContext, _: &hir::Arm) { }
fn check_pat(&mut self, _: &LateContext, _: &hir::Pat) { }
fn check_decl(&mut self, _: &LateContext, _: &hir::Decl) { }
fn check_expr(&mut self, _: &LateContext, _: &hir::Expr) { }
fn check_expr_post(&mut self, _: &LateContext, _: &hir::Expr) { }
fn check_ty(&mut self, _: &LateContext, _: &hir::Ty) { }
fn check_generics(&mut self, _: &LateContext, _: &hir::Generics) { }
fn check_fn(&mut self, _: &LateContext,
_: FnKind, _: &hir::FnDecl, _: &hir::Block, _: Span, _: ast::NodeId) { }
fn check_trait_item(&mut self, _: &Context, _: &hir::TraitItem) { }
fn check_impl_item(&mut self, _: &Context, _: &hir::ImplItem) { }
fn check_struct_def(&mut self, _: &Context,
fn check_trait_item(&mut self, _: &LateContext, _: &hir::TraitItem) { }
fn check_impl_item(&mut self, _: &LateContext, _: &hir::ImplItem) { }
fn check_struct_def(&mut self, _: &LateContext,
_: &hir::StructDef, _: ast::Ident, _: &hir::Generics, _: ast::NodeId) { }
fn check_struct_def_post(&mut self, _: &Context,
fn check_struct_def_post(&mut self, _: &LateContext,
_: &hir::StructDef, _: ast::Ident, _: &hir::Generics, _: ast::NodeId) { }
fn check_struct_field(&mut self, _: &Context, _: &hir::StructField) { }
fn check_variant(&mut self, _: &Context, _: &hir::Variant, _: &hir::Generics) { }
fn check_variant_post(&mut self, _: &Context, _: &hir::Variant, _: &hir::Generics) { }
fn check_opt_lifetime_ref(&mut self, _: &Context, _: Span, _: &Option<hir::Lifetime>) { }
fn check_lifetime_ref(&mut self, _: &Context, _: &hir::Lifetime) { }
fn check_lifetime_def(&mut self, _: &Context, _: &hir::LifetimeDef) { }
fn check_explicit_self(&mut self, _: &Context, _: &hir::ExplicitSelf) { }
fn check_mac(&mut self, _: &Context, _: &ast::Mac) { }
fn check_path(&mut self, _: &Context, _: &hir::Path, _: ast::NodeId) { }
fn check_attribute(&mut self, _: &Context, _: &ast::Attribute) { }
fn check_struct_field(&mut self, _: &LateContext, _: &hir::StructField) { }
fn check_variant(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
fn check_variant_post(&mut self, _: &LateContext, _: &hir::Variant, _: &hir::Generics) { }
fn check_opt_lifetime_ref(&mut self, _: &LateContext, _: Span, _: &Option<hir::Lifetime>) { }
fn check_lifetime_ref(&mut self, _: &LateContext, _: &hir::Lifetime) { }
fn check_lifetime_def(&mut self, _: &LateContext, _: &hir::LifetimeDef) { }
fn check_explicit_self(&mut self, _: &LateContext, _: &hir::ExplicitSelf) { }
// Note that you shouldn't implement both check_mac and check_ast_mac,
// because then your lint will be called twice. Prefer check_ast_mac.
fn check_mac(&mut self, _: &LateContext, _: &ast::Mac) { }
fn check_path(&mut self, _: &LateContext, _: &hir::Path, _: ast::NodeId) { }
fn check_attribute(&mut self, _: &LateContext, _: &ast::Attribute) { }
fn check_ast_ident(&mut self, _: &EarlyContext, _: Span, _: ast::Ident) { }
fn check_ast_crate(&mut self, _: &EarlyContext, _: &ast::Crate) { }
fn check_ast_mod(&mut self, _: &EarlyContext, _: &ast::Mod, _: Span, _: ast::NodeId) { }
fn check_ast_foreign_item(&mut self, _: &EarlyContext, _: &ast::ForeignItem) { }
fn check_ast_item(&mut self, _: &EarlyContext, _: &ast::Item) { }
fn check_ast_local(&mut self, _: &EarlyContext, _: &ast::Local) { }
fn check_ast_block(&mut self, _: &EarlyContext, _: &ast::Block) { }
fn check_ast_stmt(&mut self, _: &EarlyContext, _: &ast::Stmt) { }
fn check_ast_arm(&mut self, _: &EarlyContext, _: &ast::Arm) { }
fn check_ast_pat(&mut self, _: &EarlyContext, _: &ast::Pat) { }
fn check_ast_decl(&mut self, _: &EarlyContext, _: &ast::Decl) { }
fn check_ast_expr(&mut self, _: &EarlyContext, _: &ast::Expr) { }
fn check_ast_expr_post(&mut self, _: &EarlyContext, _: &ast::Expr) { }
fn check_ast_ty(&mut self, _: &EarlyContext, _: &ast::Ty) { }
fn check_ast_generics(&mut self, _: &EarlyContext, _: &ast::Generics) { }
fn check_ast_fn(&mut self, _: &EarlyContext,
_: ast_visit::FnKind, _: &ast::FnDecl, _: &ast::Block, _: Span, _: ast::NodeId) { }
fn check_ast_trait_item(&mut self, _: &EarlyContext, _: &ast::TraitItem) { }
fn check_ast_impl_item(&mut self, _: &EarlyContext, _: &ast::ImplItem) { }
fn check_ast_struct_def(&mut self, _: &EarlyContext,
_: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
fn check_ast_struct_def_post(&mut self, _: &EarlyContext,
_: &ast::StructDef, _: ast::Ident, _: &ast::Generics, _: ast::NodeId) { }
fn check_ast_struct_field(&mut self, _: &EarlyContext, _: &ast::StructField) { }
fn check_ast_variant(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
fn check_ast_variant_post(&mut self, _: &EarlyContext, _: &ast::Variant, _: &ast::Generics) { }
fn check_ast_opt_lifetime_ref(&mut self,
_: &EarlyContext,
_: Span,
_: &Option<ast::Lifetime>) { }
fn check_ast_lifetime_ref(&mut self, _: &EarlyContext, _: &ast::Lifetime) { }
fn check_ast_lifetime_def(&mut self, _: &EarlyContext, _: &ast::LifetimeDef) { }
fn check_ast_explicit_self(&mut self, _: &EarlyContext, _: &ast::ExplicitSelf) { }
fn check_ast_mac(&mut self, _: &EarlyContext, _: &ast::Mac) { }
fn check_ast_path(&mut self, _: &EarlyContext, _: &ast::Path, _: ast::NodeId) { }
fn check_ast_attribute(&mut self, _: &EarlyContext, _: &ast::Attribute) { }
/// Called when entering a syntax node that can have lint attributes such
/// as `#[allow(...)]`. Called with *all* the attributes of that node.
fn enter_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) { }
fn enter_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) { }
/// Counterpart to `enter_lint_attrs`.
fn exit_lint_attrs(&mut self, _: &Context, _: &[ast::Attribute]) { }
fn exit_lint_attrs(&mut self, _: &LateContext, _: &[ast::Attribute]) { }
/// Called when entering a syntax node that can have lint attributes such
/// as `#[allow(...)]`. Called with *all* the attributes of that node.
fn ast_enter_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }
/// Counterpart to `ast_enter_lint_attrs`.
fn ast_exit_lint_attrs(&mut self, _: &EarlyContext, _: &[ast::Attribute]) { }
}
/// A lint pass boxed up as a trait object.
......
......@@ -89,7 +89,6 @@ pub fn args<'b>(&'b self) -> &'b Vec<P<ast::MetaItem>> {
/// Register a syntax extension of any kind.
///
/// This is the most general hook into `libsyntax`'s expansion behavior.
#[allow(deprecated)]
pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
self.syntax_exts.push((name, match extension {
NormalTT(ext, _, allow_internal_unstable) => {
......
......@@ -132,7 +132,6 @@ pub fn compile_input(sess: Session,
phase_3_run_analysis_passes(sess,
ast_map,
&expanded_crate,
&arenas,
id,
control.make_glob_map,
......@@ -598,6 +597,10 @@ pub fn phase_2_configure_and_expand(sess: &Session,
sess.abort_if_errors();
});
time(time_passes, "early lint checks", || {
lint::check_ast_crate(sess, &krate)
});
Some(krate)
}
......@@ -641,7 +644,6 @@ pub fn make_map<'ast>(sess: &Session,
/// structures carrying the results of the analysis.
pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
ast_map: front::map::Map<'tcx>,
ast_crate: &ast::Crate,
arenas: &'tcx ty::CtxtArenas<'tcx>,
name: String,
make_glob_map: resolve::MakeGlobMap,
......@@ -765,7 +767,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: Session,
&tcx.sess, lib_features_used));
time(time_passes, "lint checking", ||
lint::check_crate(tcx, &lower_crate(ast_crate), &exported_items));
lint::check_crate(tcx, krate, &exported_items));
// The above three passes generate errors w/o aborting
tcx.sess.abort_if_errors();
......
......@@ -157,7 +157,6 @@ fn call_with_pp_support<'tcx, A, B, F>(&self,
fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
sess: Session,
ast_map: &hir_map::Map<'tcx>,
ast_crate: &ast::Crate,
arenas: &'tcx ty::CtxtArenas<'tcx>,
id: String,
payload: B,
......@@ -180,7 +179,6 @@ fn call_with_pp_support_hir<'tcx, A, B, F>(&self,
PpmTyped => {
driver::phase_3_run_analysis_passes(sess,
ast_map.clone(),
ast_crate,
arenas,
id,
resolve::MakeGlobMap::No,
......@@ -715,7 +713,7 @@ pub fn pretty_print_input(sess: Session,
(PpmHir(s), None) => {
let out: &mut Write = &mut out;
s.call_with_pp_support_hir(
sess, &ast_map.unwrap(), &krate, &arenas, id, box out, |annotation, out, krate| {
sess, &ast_map.unwrap(), &arenas, id, box out, |annotation, out, krate| {
debug!("pretty printing source code {:?}", s);
let sess = annotation.sess();
pprust_hir::print_crate(sess.codemap(),
......@@ -733,7 +731,6 @@ pub fn pretty_print_input(sess: Session,
let out: &mut Write = &mut out;
s.call_with_pp_support_hir(sess,
&ast_map.unwrap(),
&krate,
&arenas,
id,
(out,uii),
......@@ -782,7 +779,6 @@ pub fn pretty_print_input(sess: Session,
let variants = gather_flowgraph_variants(&sess);
driver::phase_3_run_analysis_passes(sess,
ast_map,
&krate,
&arenas,
id,
resolve::MakeGlobMap::No,
......
此差异已折叠。
......@@ -141,7 +141,6 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
driver::phase_3_run_analysis_passes(sess,
hir_map,
&krate,
&arenas,
name,
resolve::MakeGlobMap::No,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册