Introduce callback to resolver
Sets a flag to pass through the rest of the walker.
This commit is contained in:
parent
ea5cc76aac
commit
f4ea3928ac
1 changed files with 92 additions and 16 deletions
|
|
@ -397,7 +397,7 @@ enum PatternBindingMode {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
|
||||
enum Namespace {
|
||||
pub enum Namespace {
|
||||
TypeNS,
|
||||
ValueNS
|
||||
}
|
||||
|
|
@ -445,18 +445,38 @@ enum NameDefinition {
|
|||
|
||||
impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
||||
fn visit_item(&mut self, item: &Item) {
|
||||
if let Some(ref callback) = self.callback {
|
||||
if callback(ast_map::Node::NodeItem(item), &mut self.resolved) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.resolve_item(item);
|
||||
}
|
||||
fn visit_arm(&mut self, arm: &Arm) {
|
||||
self.resolve_arm(arm);
|
||||
}
|
||||
fn visit_block(&mut self, block: &Block) {
|
||||
if let Some(ref callback) = self.callback {
|
||||
if callback(ast_map::Node::NodeBlock(block), &mut self.resolved) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.resolve_block(block);
|
||||
}
|
||||
fn visit_expr(&mut self, expr: &Expr) {
|
||||
if let Some(ref callback) = self.callback {
|
||||
if callback(ast_map::Node::NodeExpr(expr), &mut self.resolved) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.resolve_expr(expr);
|
||||
}
|
||||
fn visit_local(&mut self, local: &Local) {
|
||||
if let Some(ref callback) = self.callback {
|
||||
if callback(ast_map::Node::NodeLocal(&*local.pat), &mut self.resolved) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
self.resolve_local(local);
|
||||
}
|
||||
fn visit_ty(&mut self, ty: &Ty) {
|
||||
|
|
@ -475,6 +495,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
|||
visit::walk_poly_trait_ref(self, tref, m);
|
||||
}
|
||||
fn visit_variant(&mut self, variant: &ast::Variant, generics: &Generics) {
|
||||
if let Some(ref callback) = self.callback {
|
||||
if callback(ast_map::Node::NodeVariant(variant), &mut self.resolved) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if let Some(ref dis_expr) = variant.node.disr_expr {
|
||||
// resolve the discriminator expr as a constant
|
||||
self.with_constant_rib(|this| {
|
||||
|
|
@ -498,6 +523,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
fn visit_foreign_item(&mut self, foreign_item: &ast::ForeignItem) {
|
||||
if let Some(ref callback) = self.callback {
|
||||
if callback(ast_map::Node::NodeForeignItem(foreign_item), &mut self.resolved) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
let type_parameters = match foreign_item.node {
|
||||
ForeignItemFn(_, ref generics) => {
|
||||
HasTypeParameters(generics, FnSpace, ItemRibKind)
|
||||
|
|
@ -1110,6 +1140,13 @@ pub struct Resolver<'a, 'tcx:'a> {
|
|||
|
||||
used_imports: HashSet<(NodeId, Namespace)>,
|
||||
used_crates: HashSet<CrateNum>,
|
||||
|
||||
// Callback function for intercepting walks
|
||||
callback: Option<Box<Fn(ast_map::Node, &mut bool) -> bool>>,
|
||||
// The intention is that the callback modifies this flag.
|
||||
// Once set, the resolver falls out of the walk, preserving the ribs.
|
||||
resolved: bool,
|
||||
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
|
|
@ -1171,6 +1208,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
emit_errors: true,
|
||||
make_glob_map: make_glob_map == MakeGlobMap::Yes,
|
||||
glob_map: HashMap::new(),
|
||||
|
||||
callback: None,
|
||||
resolved: false,
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2207,7 +2248,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
f(self);
|
||||
|
||||
match type_parameters {
|
||||
HasTypeParameters(..) => { self.type_ribs.pop(); }
|
||||
HasTypeParameters(..) => { if !self.resolved { self.type_ribs.pop(); } }
|
||||
NoTypeParameters => { }
|
||||
}
|
||||
}
|
||||
|
|
@ -2217,7 +2258,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
{
|
||||
self.label_ribs.push(Rib::new(NormalRibKind));
|
||||
f(self);
|
||||
self.label_ribs.pop();
|
||||
if !self.resolved {
|
||||
self.label_ribs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fn with_constant_rib<F>(&mut self, f: F) where
|
||||
|
|
@ -2226,8 +2269,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
self.value_ribs.push(Rib::new(ConstantItemRibKind));
|
||||
self.type_ribs.push(Rib::new(ConstantItemRibKind));
|
||||
f(self);
|
||||
self.type_ribs.pop();
|
||||
self.value_ribs.pop();
|
||||
if !self.resolved {
|
||||
self.type_ribs.pop();
|
||||
self.value_ribs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_function(&mut self,
|
||||
|
|
@ -2258,8 +2303,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
|
||||
debug!("(resolving function) leaving function");
|
||||
|
||||
self.label_ribs.pop();
|
||||
self.value_ribs.pop();
|
||||
if !self.resolved {
|
||||
self.label_ribs.pop();
|
||||
self.value_ribs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_trait_reference(&mut self,
|
||||
|
|
@ -2362,7 +2409,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
self_type_rib.bindings.insert(name, DlDef(self_def));
|
||||
self.type_ribs.push(self_type_rib);
|
||||
f(self);
|
||||
self.type_ribs.pop();
|
||||
if !self.resolved {
|
||||
self.type_ribs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_implementation(&mut self,
|
||||
|
|
@ -2531,7 +2580,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
visit::walk_expr_opt(self, &arm.guard);
|
||||
self.visit_expr(&*arm.body);
|
||||
|
||||
self.value_ribs.pop();
|
||||
if !self.resolved {
|
||||
self.value_ribs.pop();
|
||||
}
|
||||
}
|
||||
|
||||
fn resolve_block(&mut self, block: &Block) {
|
||||
|
|
@ -2575,7 +2626,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
// Move back up.
|
||||
self.current_module = orig_module;
|
||||
|
||||
self.value_ribs.pop();
|
||||
if !self.resolved {
|
||||
self.value_ribs.pop();
|
||||
}
|
||||
debug!("(resolving block) leaving block");
|
||||
}
|
||||
|
||||
|
|
@ -3017,12 +3070,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
/// doesn't skip straight to the containing module.
|
||||
/// Skips `path_depth` trailing segments, which is also reflected in the
|
||||
/// returned value. See `middle::def::PathResolution` for more info.
|
||||
fn resolve_path(&mut self,
|
||||
id: NodeId,
|
||||
path: &Path,
|
||||
path_depth: usize,
|
||||
namespace: Namespace,
|
||||
check_ribs: bool) -> Option<PathResolution> {
|
||||
pub fn resolve_path(&mut self,
|
||||
id: NodeId,
|
||||
path: &Path,
|
||||
path_depth: usize,
|
||||
namespace: Namespace,
|
||||
check_ribs: bool) -> Option<PathResolution> {
|
||||
let span = path.span;
|
||||
let segments = &path.segments[..path.segments.len()-path_depth];
|
||||
|
||||
|
|
@ -3991,4 +4044,27 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
|
|||
}
|
||||
}
|
||||
|
||||
pub fn create_resolver<'a, 'tcx>(session: &'a Session,
|
||||
ast_map: &'a ast_map::Map<'tcx>,
|
||||
_: &LanguageItems,
|
||||
krate: &'a Crate,
|
||||
make_glob_map: MakeGlobMap,
|
||||
callback: Option<Box<Fn(ast_map::Node, &mut bool) -> bool>>)
|
||||
-> Resolver<'a, 'tcx> {
|
||||
let mut resolver = Resolver::new(session, ast_map, krate.span, make_glob_map);
|
||||
|
||||
resolver.callback = callback;
|
||||
|
||||
build_reduced_graph::build_reduced_graph(&mut resolver, krate);
|
||||
session.abort_if_errors();
|
||||
|
||||
resolve_imports::resolve_imports(&mut resolver);
|
||||
session.abort_if_errors();
|
||||
|
||||
record_exports::record(&mut resolver);
|
||||
session.abort_if_errors();
|
||||
|
||||
resolver
|
||||
}
|
||||
|
||||
__build_diagnostic_array! { librustc_resolve, DIAGNOSTICS }
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue