aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/visibility.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/visibility.rs')
-rw-r--r--crates/ra_hir_def/src/visibility.rs40
1 files changed, 39 insertions, 1 deletions
diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs
index 7d881911d..901bc7191 100644
--- a/crates/ra_hir_def/src/visibility.rs
+++ b/crates/ra_hir_def/src/visibility.rs
@@ -9,7 +9,7 @@ use crate::{
9 db::DefDatabase, 9 db::DefDatabase,
10 path::{ModPath, PathKind}, 10 path::{ModPath, PathKind},
11 src::{HasChildSource, HasSource}, 11 src::{HasChildSource, HasSource},
12 AdtId, Lookup, VisibilityDefId, 12 AdtId, Lookup, ModuleId, VisibilityDefId,
13}; 13};
14 14
15/// Visibility of an item, not yet resolved. 15/// Visibility of an item, not yet resolved.
@@ -89,6 +89,44 @@ impl Visibility {
89 ast::VisibilityKind::Pub => Visibility::Public, 89 ast::VisibilityKind::Pub => Visibility::Public,
90 } 90 }
91 } 91 }
92
93 pub fn resolve(
94 &self,
95 db: &impl DefDatabase,
96 resolver: &crate::resolver::Resolver,
97 ) -> ResolvedVisibility {
98 // we fall back to public visibility (i.e. fail open) if the path can't be resolved
99 resolver.resolve_visibility(db, self).unwrap_or(ResolvedVisibility::Public)
100 }
101}
102
103/// Visibility of an item, with the path resolved.
104#[derive(Debug, Copy, Clone, PartialEq, Eq)]
105pub enum ResolvedVisibility {
106 /// Visibility is restricted to a certain module.
107 Module(ModuleId),
108 /// Visibility is unrestricted.
109 Public,
110}
111
112impl ResolvedVisibility {
113 pub fn visible_from(self, db: &impl DefDatabase, from_module: ModuleId) -> bool {
114 let to_module = match self {
115 ResolvedVisibility::Module(m) => m,
116 ResolvedVisibility::Public => return true,
117 };
118 // if they're not in the same crate, it can't be visible
119 if from_module.krate != to_module.krate {
120 return false;
121 }
122 // from_module needs to be a descendant of to_module
123 let def_map = db.crate_def_map(from_module.krate);
124 let mut ancestors = std::iter::successors(Some(from_module), |m| {
125 let parent_id = def_map[m.local_id].parent?;
126 Some(ModuleId { local_id: parent_id, ..*m })
127 });
128 ancestors.any(|m| m == to_module)
129 }
92} 130}
93 131
94fn visibility_from_loc<T>(node: T, db: &impl DefDatabase) -> Visibility 132fn visibility_from_loc<T>(node: T, db: &impl DefDatabase) -> Visibility