mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-04 02:54:00 +00:00
Add logic for resolving and checking visibility
This commit is contained in:
parent
069bf55cca
commit
1ce809d0fa
@ -19,6 +19,7 @@ use crate::{
|
|||||||
nameres::CrateDefMap,
|
nameres::CrateDefMap,
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
|
visibility::{ResolvedVisibility, Visibility},
|
||||||
AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
|
AdtId, AssocContainerId, ConstId, ContainerId, DefWithBodyId, EnumId, EnumVariantId,
|
||||||
FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
|
FunctionId, GenericDefId, HasModule, ImplId, LocalModuleId, Lookup, ModuleDefId, ModuleId,
|
||||||
StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
|
StaticId, StructId, TraitId, TypeAliasId, TypeParamId, VariantId,
|
||||||
@ -231,6 +232,26 @@ impl Resolver {
|
|||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolve_visibility(
|
||||||
|
&self,
|
||||||
|
db: &impl DefDatabase,
|
||||||
|
visibility: &Visibility,
|
||||||
|
) -> Option<ResolvedVisibility> {
|
||||||
|
match visibility {
|
||||||
|
Visibility::Module(mod_path) => {
|
||||||
|
let resolved = self.resolve_module_path_in_items(db, &mod_path).take_types()?;
|
||||||
|
match resolved {
|
||||||
|
ModuleDefId::ModuleId(m) => Some(ResolvedVisibility::Module(m)),
|
||||||
|
_ => {
|
||||||
|
// error: visibility needs to refer to module
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Visibility::Public => Some(ResolvedVisibility::Public),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resolve_path_in_value_ns(
|
pub fn resolve_path_in_value_ns(
|
||||||
&self,
|
&self,
|
||||||
db: &impl DefDatabase,
|
db: &impl DefDatabase,
|
||||||
|
@ -9,7 +9,7 @@ use crate::{
|
|||||||
db::DefDatabase,
|
db::DefDatabase,
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
src::{HasChildSource, HasSource},
|
src::{HasChildSource, HasSource},
|
||||||
AdtId, Lookup, VisibilityDefId,
|
AdtId, Lookup, ModuleId, VisibilityDefId,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Visibility of an item, not yet resolved.
|
/// Visibility of an item, not yet resolved.
|
||||||
@ -89,6 +89,44 @@ impl Visibility {
|
|||||||
ast::VisibilityKind::Pub => Visibility::Public,
|
ast::VisibilityKind::Pub => Visibility::Public,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn resolve(
|
||||||
|
&self,
|
||||||
|
db: &impl DefDatabase,
|
||||||
|
resolver: &crate::resolver::Resolver,
|
||||||
|
) -> ResolvedVisibility {
|
||||||
|
// we fall back to public visibility (i.e. fail open) if the path can't be resolved
|
||||||
|
resolver.resolve_visibility(db, self).unwrap_or(ResolvedVisibility::Public)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Visibility of an item, with the path resolved.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
pub enum ResolvedVisibility {
|
||||||
|
/// Visibility is restricted to a certain module.
|
||||||
|
Module(ModuleId),
|
||||||
|
/// Visibility is unrestricted.
|
||||||
|
Public,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ResolvedVisibility {
|
||||||
|
pub fn visible_from(self, db: &impl DefDatabase, from_module: ModuleId) -> bool {
|
||||||
|
let to_module = match self {
|
||||||
|
ResolvedVisibility::Module(m) => m,
|
||||||
|
ResolvedVisibility::Public => return true,
|
||||||
|
};
|
||||||
|
// if they're not in the same crate, it can't be visible
|
||||||
|
if from_module.krate != to_module.krate {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// from_module needs to be a descendant of to_module
|
||||||
|
let def_map = db.crate_def_map(from_module.krate);
|
||||||
|
let mut ancestors = std::iter::successors(Some(from_module), |m| {
|
||||||
|
let parent_id = def_map[m.local_id].parent?;
|
||||||
|
Some(ModuleId { local_id: parent_id, ..*m })
|
||||||
|
});
|
||||||
|
ancestors.any(|m| m == to_module)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visibility_from_loc<T>(node: T, db: &impl DefDatabase) -> Visibility
|
fn visibility_from_loc<T>(node: T, db: &impl DefDatabase) -> Visibility
|
||||||
|
Loading…
Reference in New Issue
Block a user