aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-12-24 22:45:14 +0000
committerFlorian Diebold <[email protected]>2019-12-26 15:23:40 +0000
commit79c90b5641d2934864c587380e4f050ab63ac029 (patch)
treeb87f4cdb1f6a2b477e111bf611db797f8360e6de /crates/ra_hir_def
parentc31dae2aca8f0847df23b6976c3475cea57ada27 (diff)
Collect visibility of items during nameres
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/nameres/path_resolution.rs27
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs17
-rw-r--r--crates/ra_hir_def/src/resolver.rs15
-rw-r--r--crates/ra_hir_def/src/visibility.rs14
4 files changed, 57 insertions, 16 deletions
diff --git a/crates/ra_hir_def/src/nameres/path_resolution.rs b/crates/ra_hir_def/src/nameres/path_resolution.rs
index 695014c7b..d88076aa7 100644
--- a/crates/ra_hir_def/src/nameres/path_resolution.rs
+++ b/crates/ra_hir_def/src/nameres/path_resolution.rs
@@ -21,6 +21,7 @@ use crate::{
21 nameres::{BuiltinShadowMode, CrateDefMap}, 21 nameres::{BuiltinShadowMode, CrateDefMap},
22 path::{ModPath, PathKind}, 22 path::{ModPath, PathKind},
23 per_ns::PerNs, 23 per_ns::PerNs,
24 visibility::{ResolvedVisibility, Visibility},
24 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, 25 AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
25}; 26};
26 27
@@ -64,6 +65,32 @@ impl CrateDefMap {
64 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)) 65 self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it))
65 } 66 }
66 67
68 pub(crate) fn resolve_visibility(
69 &self,
70 db: &impl DefDatabase,
71 original_module: LocalModuleId,
72 visibility: &Visibility,
73 ) -> Option<ResolvedVisibility> {
74 match visibility {
75 Visibility::Module(path) => {
76 let (result, remaining) =
77 self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module);
78 if remaining.is_some() {
79 return None;
80 }
81 let types = result.take_types()?;
82 match types {
83 ModuleDefId::ModuleId(m) => Some(ResolvedVisibility::Module(m)),
84 _ => {
85 // error: visibility needs to refer to module
86 None
87 }
88 }
89 }
90 Visibility::Public => Some(ResolvedVisibility::Public),
91 }
92 }
93
67 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change 94 // Returns Yes if we are sure that additions to `ItemMap` wouldn't change
68 // the result. 95 // the result.
69 pub(super) fn resolve_path_fp_with_macro( 96 pub(super) fn resolve_path_fp_with_macro(
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs
index 73dc08745..9dabb5b6d 100644
--- a/crates/ra_hir_def/src/nameres/raw.rs
+++ b/crates/ra_hir_def/src/nameres/raw.rs
@@ -16,12 +16,15 @@ use hir_expand::{
16use ra_arena::{impl_arena_id, Arena, RawId}; 16use ra_arena::{impl_arena_id, Arena, RawId};
17use ra_prof::profile; 17use ra_prof::profile;
18use ra_syntax::{ 18use ra_syntax::{
19 ast::{self, AttrsOwner, NameOwner}, 19 ast::{self, AttrsOwner, NameOwner, VisibilityOwner},
20 AstNode, 20 AstNode,
21}; 21};
22use test_utils::tested_by; 22use test_utils::tested_by;
23 23
24use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; 24use crate::{
25 attr::Attrs, db::DefDatabase, path::ModPath, visibility::Visibility, FileAstId, HirFileId,
26 InFile,
27};
25 28
26/// `RawItems` is a set of top-level items in a file (except for impls). 29/// `RawItems` is a set of top-level items in a file (except for impls).
27/// 30///
@@ -138,6 +141,7 @@ pub struct ImportData {
138 pub(super) is_prelude: bool, 141 pub(super) is_prelude: bool,
139 pub(super) is_extern_crate: bool, 142 pub(super) is_extern_crate: bool,
140 pub(super) is_macro_use: bool, 143 pub(super) is_macro_use: bool,
144 pub(super) visibility: Visibility,
141} 145}
142 146
143#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 147#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -148,6 +152,7 @@ impl_arena_id!(Def);
148pub(super) struct DefData { 152pub(super) struct DefData {
149 pub(super) name: Name, 153 pub(super) name: Name,
150 pub(super) kind: DefKind, 154 pub(super) kind: DefKind,
155 pub(super) visibility: Visibility,
151} 156}
152 157
153#[derive(Debug, PartialEq, Eq, Clone, Copy)] 158#[derive(Debug, PartialEq, Eq, Clone, Copy)]
@@ -218,6 +223,7 @@ impl RawItemsCollector {
218 223
219 fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) { 224 fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) {
220 let attrs = self.parse_attrs(&item); 225 let attrs = self.parse_attrs(&item);
226 let visibility = Visibility::from_ast_with_hygiene(item.visibility(), &self.hygiene);
221 let (kind, name) = match item { 227 let (kind, name) = match item {
222 ast::ModuleItem::Module(module) => { 228 ast::ModuleItem::Module(module) => {
223 self.add_module(current_module, module); 229 self.add_module(current_module, module);
@@ -266,7 +272,7 @@ impl RawItemsCollector {
266 }; 272 };
267 if let Some(name) = name { 273 if let Some(name) = name {
268 let name = name.as_name(); 274 let name = name.as_name();
269 let def = self.raw_items.defs.alloc(DefData { name, kind }); 275 let def = self.raw_items.defs.alloc(DefData { name, kind, visibility });
270 self.push_item(current_module, attrs, RawItemKind::Def(def)); 276 self.push_item(current_module, attrs, RawItemKind::Def(def));
271 } 277 }
272 } 278 }
@@ -302,6 +308,7 @@ impl RawItemsCollector {
302 // FIXME: cfg_attr 308 // FIXME: cfg_attr
303 let is_prelude = use_item.has_atom_attr("prelude_import"); 309 let is_prelude = use_item.has_atom_attr("prelude_import");
304 let attrs = self.parse_attrs(&use_item); 310 let attrs = self.parse_attrs(&use_item);
311 let visibility = Visibility::from_ast_with_hygiene(use_item.visibility(), &self.hygiene);
305 312
306 let mut buf = Vec::new(); 313 let mut buf = Vec::new();
307 ModPath::expand_use_item( 314 ModPath::expand_use_item(
@@ -315,6 +322,7 @@ impl RawItemsCollector {
315 is_prelude, 322 is_prelude,
316 is_extern_crate: false, 323 is_extern_crate: false,
317 is_macro_use: false, 324 is_macro_use: false,
325 visibility: visibility.clone(),
318 }; 326 };
319 buf.push(import_data); 327 buf.push(import_data);
320 }, 328 },
@@ -331,6 +339,8 @@ impl RawItemsCollector {
331 ) { 339 ) {
332 if let Some(name_ref) = extern_crate.name_ref() { 340 if let Some(name_ref) = extern_crate.name_ref() {
333 let path = ModPath::from_name_ref(&name_ref); 341 let path = ModPath::from_name_ref(&name_ref);
342 let visibility =
343 Visibility::from_ast_with_hygiene(extern_crate.visibility(), &self.hygiene);
334 let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); 344 let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name());
335 let attrs = self.parse_attrs(&extern_crate); 345 let attrs = self.parse_attrs(&extern_crate);
336 // FIXME: cfg_attr 346 // FIXME: cfg_attr
@@ -342,6 +352,7 @@ impl RawItemsCollector {
342 is_prelude: false, 352 is_prelude: false,
343 is_extern_crate: true, 353 is_extern_crate: true,
344 is_macro_use, 354 is_macro_use,
355 visibility,
345 }; 356 };
346 self.push_import(current_module, attrs, import_data); 357 self.push_import(current_module, attrs, import_data);
347 } 358 }
diff --git a/crates/ra_hir_def/src/resolver.rs b/crates/ra_hir_def/src/resolver.rs
index d509dc3dd..b57dcf635 100644
--- a/crates/ra_hir_def/src/resolver.rs
+++ b/crates/ra_hir_def/src/resolver.rs
@@ -238,15 +238,12 @@ impl Resolver {
238 visibility: &Visibility, 238 visibility: &Visibility,
239 ) -> Option<ResolvedVisibility> { 239 ) -> Option<ResolvedVisibility> {
240 match visibility { 240 match visibility {
241 Visibility::Module(mod_path) => { 241 Visibility::Module(_) => {
242 let resolved = self.resolve_module_path_in_items(db, &mod_path).take_types()?; 242 let (item_map, module) = match self.module() {
243 match resolved { 243 Some(it) => it,
244 ModuleDefId::ModuleId(m) => Some(ResolvedVisibility::Module(m)), 244 None => return None,
245 _ => { 245 };
246 // error: visibility needs to refer to module 246 item_map.resolve_visibility(db, module, visibility)
247 None
248 }
249 }
250 } 247 }
251 Visibility::Public => Some(ResolvedVisibility::Public), 248 Visibility::Public => Some(ResolvedVisibility::Public),
252 } 249 }
diff --git a/crates/ra_hir_def/src/visibility.rs b/crates/ra_hir_def/src/visibility.rs
index ef7732749..8cac52630 100644
--- a/crates/ra_hir_def/src/visibility.rs
+++ b/crates/ra_hir_def/src/visibility.rs
@@ -4,7 +4,7 @@ use std::sync::Arc;
4 4
5use either::Either; 5use either::Either;
6 6
7use hir_expand::InFile; 7use hir_expand::{hygiene::Hygiene, InFile};
8use ra_syntax::ast::{self, VisibilityOwner}; 8use ra_syntax::ast::{self, VisibilityOwner};
9 9
10use crate::{ 10use crate::{
@@ -73,14 +73,20 @@ impl Visibility {
73 } 73 }
74 74
75 fn from_ast(db: &impl DefDatabase, node: InFile<Option<ast::Visibility>>) -> Visibility { 75 fn from_ast(db: &impl DefDatabase, node: InFile<Option<ast::Visibility>>) -> Visibility {
76 let file_id = node.file_id; 76 Self::from_ast_with_hygiene(node.value, &Hygiene::new(db, node.file_id))
77 let node = match node.value { 77 }
78
79 pub(crate) fn from_ast_with_hygiene(
80 node: Option<ast::Visibility>,
81 hygiene: &Hygiene,
82 ) -> Visibility {
83 let node = match node {
78 None => return Visibility::private(), 84 None => return Visibility::private(),
79 Some(node) => node, 85 Some(node) => node,
80 }; 86 };
81 match node.kind() { 87 match node.kind() {
82 ast::VisibilityKind::In(path) => { 88 ast::VisibilityKind::In(path) => {
83 let path = ModPath::from_src(path, &hir_expand::hygiene::Hygiene::new(db, file_id)); 89 let path = ModPath::from_src(path, hygiene);
84 let path = match path { 90 let path = match path {
85 None => return Visibility::private(), 91 None => return Visibility::private(),
86 Some(path) => path, 92 Some(path) => path,