Collect visibility of items during nameres

This commit is contained in:
Florian Diebold 2019-12-24 23:45:14 +01:00
parent c31dae2aca
commit 79c90b5641
6 changed files with 63 additions and 19 deletions

View file

@ -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<ResolvedVisibility> {
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(

View file

@ -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<Module>, 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);
}

View file

@ -238,15 +238,12 @@ impl Resolver {
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::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),
}

View file

@ -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<Option<ast::Visibility>>) -> 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<ast::Visibility>,
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,

View file

@ -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<NameRef> {
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<UseTree> {
AstChildren::new(&self.syntax).next()

View file

@ -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": (