Refactor away module.resolve_name()
.
This commit is contained in:
parent
89de52eff0
commit
bfc98f59a4
2 changed files with 75 additions and 77 deletions
|
@ -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,7 +1438,7 @@ 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()
|
||||
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.
|
||||
|
|
|
@ -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>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue