From 79c90b5641d2934864c587380e4f050ab63ac029 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Tue, 24 Dec 2019 23:45:14 +0100 Subject: Collect visibility of items during nameres --- crates/ra_hir_def/src/nameres/path_resolution.rs | 27 ++++++++++++++++++++++++ crates/ra_hir_def/src/nameres/raw.rs | 17 ++++++++++++--- crates/ra_hir_def/src/resolver.rs | 15 ++++++------- crates/ra_hir_def/src/visibility.rs | 14 ++++++++---- crates/ra_syntax/src/ast/generated.rs | 3 +++ crates/ra_syntax/src/grammar.ron | 6 +++--- 6 files changed, 63 insertions(+), 19 deletions(-) (limited to 'crates') 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::{ nameres::{BuiltinShadowMode, CrateDefMap}, path::{ModPath, PathKind}, per_ns::PerNs, + visibility::{ResolvedVisibility, Visibility}, AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId, }; @@ -64,6 +65,32 @@ impl CrateDefMap { self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)) } + pub(crate) fn resolve_visibility( + &self, + db: &impl DefDatabase, + original_module: LocalModuleId, + visibility: &Visibility, + ) -> Option { + match visibility { + Visibility::Module(path) => { + let (result, remaining) = + self.resolve_path(db, original_module, &path, BuiltinShadowMode::Module); + if remaining.is_some() { + return None; + } + let types = result.take_types()?; + match types { + ModuleDefId::ModuleId(m) => Some(ResolvedVisibility::Module(m)), + _ => { + // error: visibility needs to refer to module + None + } + } + } + Visibility::Public => Some(ResolvedVisibility::Public), + } + } + // Returns Yes if we are sure that additions to `ItemMap` wouldn't change // the result. 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::{ use ra_arena::{impl_arena_id, Arena, RawId}; use ra_prof::profile; use ra_syntax::{ - ast::{self, AttrsOwner, NameOwner}, + ast::{self, AttrsOwner, NameOwner, VisibilityOwner}, AstNode, }; use test_utils::tested_by; -use crate::{attr::Attrs, db::DefDatabase, path::ModPath, FileAstId, HirFileId, InFile}; +use crate::{ + attr::Attrs, db::DefDatabase, path::ModPath, visibility::Visibility, FileAstId, HirFileId, + InFile, +}; /// `RawItems` is a set of top-level items in a file (except for impls). /// @@ -138,6 +141,7 @@ pub struct ImportData { pub(super) is_prelude: bool, pub(super) is_extern_crate: bool, pub(super) is_macro_use: bool, + pub(super) visibility: Visibility, } #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -148,6 +152,7 @@ impl_arena_id!(Def); pub(super) struct DefData { pub(super) name: Name, pub(super) kind: DefKind, + pub(super) visibility: Visibility, } #[derive(Debug, PartialEq, Eq, Clone, Copy)] @@ -218,6 +223,7 @@ impl RawItemsCollector { fn add_item(&mut self, current_module: Option, item: ast::ModuleItem) { let attrs = self.parse_attrs(&item); + let visibility = Visibility::from_ast_with_hygiene(item.visibility(), &self.hygiene); let (kind, name) = match item { ast::ModuleItem::Module(module) => { self.add_module(current_module, module); @@ -266,7 +272,7 @@ impl RawItemsCollector { }; if let Some(name) = name { let name = name.as_name(); - let def = self.raw_items.defs.alloc(DefData { name, kind }); + let def = self.raw_items.defs.alloc(DefData { name, kind, visibility }); self.push_item(current_module, attrs, RawItemKind::Def(def)); } } @@ -302,6 +308,7 @@ impl RawItemsCollector { // FIXME: cfg_attr let is_prelude = use_item.has_atom_attr("prelude_import"); let attrs = self.parse_attrs(&use_item); + let visibility = Visibility::from_ast_with_hygiene(use_item.visibility(), &self.hygiene); let mut buf = Vec::new(); ModPath::expand_use_item( @@ -315,6 +322,7 @@ impl RawItemsCollector { is_prelude, is_extern_crate: false, is_macro_use: false, + visibility: visibility.clone(), }; buf.push(import_data); }, @@ -331,6 +339,8 @@ impl RawItemsCollector { ) { if let Some(name_ref) = extern_crate.name_ref() { let path = ModPath::from_name_ref(&name_ref); + let visibility = + Visibility::from_ast_with_hygiene(extern_crate.visibility(), &self.hygiene); let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); let attrs = self.parse_attrs(&extern_crate); // FIXME: cfg_attr @@ -342,6 +352,7 @@ impl RawItemsCollector { is_prelude: false, is_extern_crate: true, is_macro_use, + visibility, }; self.push_import(current_module, attrs, import_data); } 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 { visibility: &Visibility, ) -> Option { 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::Module(_) => { + let (item_map, module) = match self.module() { + Some(it) => it, + None => return None, + }; + item_map.resolve_visibility(db, module, visibility) } Visibility::Public => Some(ResolvedVisibility::Public), } 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; use either::Either; -use hir_expand::InFile; +use hir_expand::{hygiene::Hygiene, InFile}; use ra_syntax::ast::{self, VisibilityOwner}; use crate::{ @@ -73,14 +73,20 @@ impl Visibility { } fn from_ast(db: &impl DefDatabase, node: InFile>) -> Visibility { - let file_id = node.file_id; - let node = match node.value { + Self::from_ast_with_hygiene(node.value, &Hygiene::new(db, node.file_id)) + } + + pub(crate) fn from_ast_with_hygiene( + node: Option, + hygiene: &Hygiene, + ) -> Visibility { + let node = match node { None => return Visibility::private(), Some(node) => node, }; match node.kind() { ast::VisibilityKind::In(path) => { - let path = ModPath::from_src(path, &hir_expand::hygiene::Hygiene::new(db, file_id)); + let path = ModPath::from_src(path, hygiene); let path = match path { None => return Visibility::private(), Some(path) => path, diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 9f9d6e63c..e64c83d33 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1064,6 +1064,7 @@ impl AstNode for ExternCrateItem { } } impl ast::AttrsOwner for ExternCrateItem {} +impl ast::VisibilityOwner for ExternCrateItem {} impl ExternCrateItem { pub fn name_ref(&self) -> Option { AstChildren::new(&self.syntax).next() @@ -2006,6 +2007,7 @@ impl AstNode for ModuleItem { } } impl ast::AttrsOwner for ModuleItem {} +impl ast::VisibilityOwner for ModuleItem {} impl ModuleItem {} #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Name { @@ -3893,6 +3895,7 @@ impl AstNode for UseItem { } } impl ast::AttrsOwner for UseItem {} +impl ast::VisibilityOwner for UseItem {} impl UseItem { pub fn use_tree(&self) -> Option { AstChildren::new(&self.syntax).next() diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 08aafb610..e43a724f0 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -412,7 +412,7 @@ Grammar( "ModuleItem": ( enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock", "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ], - traits: ["AttrsOwner"], + traits: ["AttrsOwner", "VisibilityOwner"], ), "ImplItem": ( enum: ["FnDef", "TypeAliasDef", "ConstDef"], @@ -683,7 +683,7 @@ Grammar( ] ), "UseItem": ( - traits: ["AttrsOwner"], + traits: ["AttrsOwner", "VisibilityOwner"], options: [ "UseTree" ], ), "UseTree": ( @@ -696,7 +696,7 @@ Grammar( collections: [("use_trees", "UseTree")] ), "ExternCrateItem": ( - traits: ["AttrsOwner"], + traits: ["AttrsOwner", "VisibilityOwner"], options: ["NameRef", "Alias"], ), "ArgList": ( -- cgit v1.2.3