1
Fork 0

Refactor away module.resolve_name().

This commit is contained in:
Jeffrey Seyfried 2016-08-01 20:43:48 +00:00
parent 89de52eff0
commit bfc98f59a4
2 changed files with 75 additions and 77 deletions

View file

@ -1250,12 +1250,13 @@ impl<'a> Resolver<'a> {
index: usize,
span: Span)
-> ResolveResult<Module<'a>> {
fn search_parent_externals(needle: Name, module: Module) -> Option<Module> {
match module.resolve_name(needle, TypeNS, false) {
fn search_parent_externals<'a>(this: &mut Resolver<'a>, needle: Name, module: Module<'a>)
-> Option<Module<'a>> {
match this.resolve_name_in_module(module, needle, TypeNS, false, false) {
Success(binding) if binding.is_extern_crate() => Some(module),
_ => match module.parent_link {
ModuleParentLink(ref parent, _) => {
search_parent_externals(needle, parent)
search_parent_externals(this, needle, parent)
}
_ => None,
},
@ -1275,11 +1276,12 @@ impl<'a> Resolver<'a> {
let segment_name = name.as_str();
let module_name = module_to_string(search_module);
let msg = if "???" == &module_name {
match search_parent_externals(name, &self.current_module) {
let current_module = self.current_module;
match search_parent_externals(self, name, current_module) {
Some(module) => {
let path_str = names_to_string(module_path);
let target_mod_str = module_to_string(&module);
let current_mod_str = module_to_string(&self.current_module);
let current_mod_str = module_to_string(current_module);
let prefix = if target_mod_str == current_mod_str {
"self::".to_string()
@ -1436,8 +1438,8 @@ impl<'a> Resolver<'a> {
if module.def.is_some() {
return match self.prelude {
Some(prelude) if !module.no_implicit_prelude.get() => {
prelude.resolve_name(name, ns, false).success()
.map(LexicalScopeBinding::Item)
self.resolve_name_in_module(prelude, name, ns, false, false).success()
.map(LexicalScopeBinding::Item)
}
_ => None,
};
@ -1523,27 +1525,6 @@ impl<'a> Resolver<'a> {
return Success(PrefixFound(containing_module, i));
}
/// Attempts to resolve the supplied name in the given module for the
/// given namespace. If successful, returns the binding corresponding to
/// the name.
fn resolve_name_in_module(&mut self,
module: Module<'a>,
name: Name,
namespace: Namespace,
use_lexical_scope: bool,
record_used: bool)
-> ResolveResult<&'a NameBinding<'a>> {
debug!("(resolving name in module) resolving `{}` in `{}`", name, module_to_string(module));
self.populate_module_if_necessary(module);
module.resolve_name(name, namespace, use_lexical_scope).and_then(|binding| {
if record_used {
self.record_use(name, namespace, binding);
}
Success(binding)
})
}
// AST resolution
//
// We maintain a list of value ribs and type ribs.

View file

@ -133,19 +133,77 @@ impl<'a> NameResolution<'a> {
_ => None, // The binding could be shadowed by a single import, so it is not known.
})
}
}
impl<'a> ::ModuleS<'a> {
fn resolution(&self, name: Name, ns: Namespace) -> &'a RefCell<NameResolution<'a>> {
*self.resolutions.borrow_mut().entry((name, ns))
.or_insert_with(|| self.arenas.alloc_name_resolution())
}
}
impl<'a> Resolver<'a> {
/// Attempts to resolve the supplied name in the given module for the given namespace.
/// If successful, returns the binding corresponding to the name.
pub fn resolve_name_in_module(&mut self,
module: Module<'a>,
name: Name,
ns: Namespace,
allow_private_imports: bool,
record_used: bool)
-> ResolveResult<&'a NameBinding<'a>> {
self.populate_module_if_necessary(module);
let resolution = module.resolution(name, ns);
let resolution = match resolution.borrow_state() {
::std::cell::BorrowState::Unused => resolution.borrow_mut(),
_ => return Failed(None), // This happens when there is a cycle of imports
};
if let Some(result) = self.try_result(&resolution, ns, allow_private_imports) {
// If the resolution doesn't depend on glob definability, check privacy and return.
return result.and_then(|binding| {
if !allow_private_imports && binding.is_import() && !binding.is_pseudo_public() {
return Failed(None);
}
if record_used {
self.record_use(name, ns, binding);
}
Success(binding)
});
}
// Check if the globs are determined
for directive in module.globs.borrow().iter() {
if !allow_private_imports && directive.vis != ty::Visibility::Public { continue }
if let Some(target_module) = directive.target_module.get() {
let result = self.resolve_name_in_module(target_module, name, ns, false, false);
if let Indeterminate = result {
return Indeterminate;
}
} else {
return Indeterminate;
}
}
Failed(None)
}
// Returns Some(the resolution of the name), or None if the resolution depends
// on whether more globs can define the name.
fn try_result(&self, ns: Namespace, allow_private_imports: bool)
fn try_result(&mut self,
resolution: &NameResolution<'a>,
ns: Namespace,
allow_private_imports: bool)
-> Option<ResolveResult<&'a NameBinding<'a>>> {
match self.binding {
match resolution.binding {
Some(binding) if !binding.is_glob_import() =>
return Some(Success(binding)),
_ => {} // Items and single imports are not shadowable
return Some(Success(binding)), // Items and single imports are not shadowable.
_ => {}
};
// Check if a single import can still define the name.
match self.single_imports {
match resolution.single_imports {
SingleImports::None => {},
SingleImports::AtLeastOne => return Some(Indeterminate),
SingleImports::MaybeOne(directive) => {
@ -153,7 +211,7 @@ impl<'a> NameResolution<'a> {
// the name, and (3) no public glob has defined the name, the resolution depends
// on whether more globs can define the name.
if !allow_private_imports && directive.vis != ty::Visibility::Public &&
!self.binding.map(NameBinding::is_pseudo_public).unwrap_or(false) {
!resolution.binding.map(NameBinding::is_pseudo_public).unwrap_or(false) {
return None;
}
@ -165,57 +223,16 @@ impl<'a> NameResolution<'a> {
SingleImport { source, .. } => source,
GlobImport { .. } => unreachable!(),
};
match target_module.resolve_name(name, ns, false) {
match self.resolve_name_in_module(target_module, name, ns, false, false) {
Failed(_) => {}
_ => return Some(Indeterminate),
}
}
}
self.binding.map(Success)
}
}
impl<'a> ::ModuleS<'a> {
fn resolution(&self, name: Name, ns: Namespace) -> &'a RefCell<NameResolution<'a>> {
*self.resolutions.borrow_mut().entry((name, ns))
.or_insert_with(|| self.arenas.alloc_name_resolution())
resolution.binding.map(Success)
}
pub fn resolve_name(&self, name: Name, ns: Namespace, allow_private_imports: bool)
-> ResolveResult<&'a NameBinding<'a>> {
let resolution = self.resolution(name, ns);
let resolution = match resolution.borrow_state() {
::std::cell::BorrowState::Unused => resolution.borrow_mut(),
_ => return Failed(None), // This happens when there is a cycle of imports
};
if let Some(result) = resolution.try_result(ns, allow_private_imports) {
// If the resolution doesn't depend on glob definability, check privacy and return.
return result.and_then(|binding| {
let allowed = allow_private_imports || !binding.is_import() ||
binding.is_pseudo_public();
if allowed { Success(binding) } else { Failed(None) }
});
}
// Check if the globs are determined
for directive in self.globs.borrow().iter() {
if !allow_private_imports && directive.vis != ty::Visibility::Public { continue }
match directive.target_module.get() {
None => return Indeterminate,
Some(target_module) => match target_module.resolve_name(name, ns, false) {
Indeterminate => return Indeterminate,
_ => {}
}
}
}
Failed(None)
}
}
impl<'a> Resolver<'a> {
// Add an import directive to the current module.
pub fn add_import_directive(&mut self,
module_path: Vec<Name>,