diff options
author | Florian Diebold <[email protected]> | 2019-12-24 22:45:14 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-12-26 15:23:40 +0000 |
commit | 79c90b5641d2934864c587380e4f050ab63ac029 (patch) | |
tree | b87f4cdb1f6a2b477e111bf611db797f8360e6de /crates/ra_hir_def/src | |
parent | c31dae2aca8f0847df23b6976c3475cea57ada27 (diff) |
Collect visibility of items during nameres
Diffstat (limited to 'crates/ra_hir_def/src')
-rw-r--r-- | crates/ra_hir_def/src/nameres/path_resolution.rs | 27 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 17 | ||||
-rw-r--r-- | crates/ra_hir_def/src/resolver.rs | 15 | ||||
-rw-r--r-- | crates/ra_hir_def/src/visibility.rs | 14 |
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::{ | |||
16 | use ra_arena::{impl_arena_id, Arena, RawId}; | 16 | use ra_arena::{impl_arena_id, Arena, RawId}; |
17 | use ra_prof::profile; | 17 | use ra_prof::profile; |
18 | use ra_syntax::{ | 18 | use ra_syntax::{ |
19 | ast::{self, AttrsOwner, NameOwner}, | 19 | ast::{self, AttrsOwner, NameOwner, VisibilityOwner}, |
20 | AstNode, | 20 | AstNode, |
21 | }; | 21 | }; |
22 | use test_utils::tested_by; | 22 | use test_utils::tested_by; |
23 | 23 | ||
24 | use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; | 24 | use 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); | |||
148 | pub(super) struct DefData { | 152 | pub(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 | ||
5 | use either::Either; | 5 | use either::Either; |
6 | 6 | ||
7 | use hir_expand::InFile; | 7 | use hir_expand::{hygiene::Hygiene, InFile}; |
8 | use ra_syntax::ast::{self, VisibilityOwner}; | 8 | use ra_syntax::ast::{self, VisibilityOwner}; |
9 | 9 | ||
10 | use crate::{ | 10 | use 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, |