mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-14 02:49:40 +00:00
Collect visibility of items during nameres
This commit is contained in:
parent
c31dae2aca
commit
79c90b5641
@ -21,6 +21,7 @@ use crate::{
|
|||||||
nameres::{BuiltinShadowMode, CrateDefMap},
|
nameres::{BuiltinShadowMode, CrateDefMap},
|
||||||
path::{ModPath, PathKind},
|
path::{ModPath, PathKind},
|
||||||
per_ns::PerNs,
|
per_ns::PerNs,
|
||||||
|
visibility::{ResolvedVisibility, Visibility},
|
||||||
AdtId, CrateId, EnumVariantId, LocalModuleId, ModuleDefId, ModuleId,
|
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))
|
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
|
// Returns Yes if we are sure that additions to `ItemMap` wouldn't change
|
||||||
// the result.
|
// the result.
|
||||||
pub(super) fn resolve_path_fp_with_macro(
|
pub(super) fn resolve_path_fp_with_macro(
|
||||||
|
@ -16,12 +16,15 @@ use hir_expand::{
|
|||||||
use ra_arena::{impl_arena_id, Arena, RawId};
|
use ra_arena::{impl_arena_id, Arena, RawId};
|
||||||
use ra_prof::profile;
|
use ra_prof::profile;
|
||||||
use ra_syntax::{
|
use ra_syntax::{
|
||||||
ast::{self, AttrsOwner, NameOwner},
|
ast::{self, AttrsOwner, NameOwner, VisibilityOwner},
|
||||||
AstNode,
|
AstNode,
|
||||||
};
|
};
|
||||||
use test_utils::tested_by;
|
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).
|
/// `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_prelude: bool,
|
||||||
pub(super) is_extern_crate: bool,
|
pub(super) is_extern_crate: bool,
|
||||||
pub(super) is_macro_use: bool,
|
pub(super) is_macro_use: bool,
|
||||||
|
pub(super) visibility: Visibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
@ -148,6 +152,7 @@ impl_arena_id!(Def);
|
|||||||
pub(super) struct DefData {
|
pub(super) struct DefData {
|
||||||
pub(super) name: Name,
|
pub(super) name: Name,
|
||||||
pub(super) kind: DefKind,
|
pub(super) kind: DefKind,
|
||||||
|
pub(super) visibility: Visibility,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
|
||||||
@ -218,6 +223,7 @@ impl RawItemsCollector {
|
|||||||
|
|
||||||
fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) {
|
fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) {
|
||||||
let attrs = self.parse_attrs(&item);
|
let attrs = self.parse_attrs(&item);
|
||||||
|
let visibility = Visibility::from_ast_with_hygiene(item.visibility(), &self.hygiene);
|
||||||
let (kind, name) = match item {
|
let (kind, name) = match item {
|
||||||
ast::ModuleItem::Module(module) => {
|
ast::ModuleItem::Module(module) => {
|
||||||
self.add_module(current_module, module);
|
self.add_module(current_module, module);
|
||||||
@ -266,7 +272,7 @@ impl RawItemsCollector {
|
|||||||
};
|
};
|
||||||
if let Some(name) = name {
|
if let Some(name) = name {
|
||||||
let name = name.as_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));
|
self.push_item(current_module, attrs, RawItemKind::Def(def));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -302,6 +308,7 @@ impl RawItemsCollector {
|
|||||||
// FIXME: cfg_attr
|
// FIXME: cfg_attr
|
||||||
let is_prelude = use_item.has_atom_attr("prelude_import");
|
let is_prelude = use_item.has_atom_attr("prelude_import");
|
||||||
let attrs = self.parse_attrs(&use_item);
|
let attrs = self.parse_attrs(&use_item);
|
||||||
|
let visibility = Visibility::from_ast_with_hygiene(use_item.visibility(), &self.hygiene);
|
||||||
|
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
ModPath::expand_use_item(
|
ModPath::expand_use_item(
|
||||||
@ -315,6 +322,7 @@ impl RawItemsCollector {
|
|||||||
is_prelude,
|
is_prelude,
|
||||||
is_extern_crate: false,
|
is_extern_crate: false,
|
||||||
is_macro_use: false,
|
is_macro_use: false,
|
||||||
|
visibility: visibility.clone(),
|
||||||
};
|
};
|
||||||
buf.push(import_data);
|
buf.push(import_data);
|
||||||
},
|
},
|
||||||
@ -331,6 +339,8 @@ impl RawItemsCollector {
|
|||||||
) {
|
) {
|
||||||
if let Some(name_ref) = extern_crate.name_ref() {
|
if let Some(name_ref) = extern_crate.name_ref() {
|
||||||
let path = ModPath::from_name_ref(&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 alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name());
|
||||||
let attrs = self.parse_attrs(&extern_crate);
|
let attrs = self.parse_attrs(&extern_crate);
|
||||||
// FIXME: cfg_attr
|
// FIXME: cfg_attr
|
||||||
@ -342,6 +352,7 @@ impl RawItemsCollector {
|
|||||||
is_prelude: false,
|
is_prelude: false,
|
||||||
is_extern_crate: true,
|
is_extern_crate: true,
|
||||||
is_macro_use,
|
is_macro_use,
|
||||||
|
visibility,
|
||||||
};
|
};
|
||||||
self.push_import(current_module, attrs, import_data);
|
self.push_import(current_module, attrs, import_data);
|
||||||
}
|
}
|
||||||
|
@ -238,15 +238,12 @@ impl Resolver {
|
|||||||
visibility: &Visibility,
|
visibility: &Visibility,
|
||||||
) -> Option<ResolvedVisibility> {
|
) -> Option<ResolvedVisibility> {
|
||||||
match visibility {
|
match visibility {
|
||||||
Visibility::Module(mod_path) => {
|
Visibility::Module(_) => {
|
||||||
let resolved = self.resolve_module_path_in_items(db, &mod_path).take_types()?;
|
let (item_map, module) = match self.module() {
|
||||||
match resolved {
|
Some(it) => it,
|
||||||
ModuleDefId::ModuleId(m) => Some(ResolvedVisibility::Module(m)),
|
None => return None,
|
||||||
_ => {
|
};
|
||||||
// error: visibility needs to refer to module
|
item_map.resolve_visibility(db, module, visibility)
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Visibility::Public => Some(ResolvedVisibility::Public),
|
Visibility::Public => Some(ResolvedVisibility::Public),
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
|
||||||
use hir_expand::InFile;
|
use hir_expand::{hygiene::Hygiene, InFile};
|
||||||
use ra_syntax::ast::{self, VisibilityOwner};
|
use ra_syntax::ast::{self, VisibilityOwner};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -73,14 +73,20 @@ impl Visibility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn from_ast(db: &impl DefDatabase, node: InFile<Option<ast::Visibility>>) -> Visibility {
|
fn from_ast(db: &impl DefDatabase, node: InFile<Option<ast::Visibility>>) -> Visibility {
|
||||||
let file_id = node.file_id;
|
Self::from_ast_with_hygiene(node.value, &Hygiene::new(db, node.file_id))
|
||||||
let node = match node.value {
|
}
|
||||||
|
|
||||||
|
pub(crate) fn from_ast_with_hygiene(
|
||||||
|
node: Option<ast::Visibility>,
|
||||||
|
hygiene: &Hygiene,
|
||||||
|
) -> Visibility {
|
||||||
|
let node = match node {
|
||||||
None => return Visibility::private(),
|
None => return Visibility::private(),
|
||||||
Some(node) => node,
|
Some(node) => node,
|
||||||
};
|
};
|
||||||
match node.kind() {
|
match node.kind() {
|
||||||
ast::VisibilityKind::In(path) => {
|
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 {
|
let path = match path {
|
||||||
None => return Visibility::private(),
|
None => return Visibility::private(),
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
|
@ -1064,6 +1064,7 @@ impl AstNode for ExternCrateItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ast::AttrsOwner for ExternCrateItem {}
|
impl ast::AttrsOwner for ExternCrateItem {}
|
||||||
|
impl ast::VisibilityOwner for ExternCrateItem {}
|
||||||
impl ExternCrateItem {
|
impl ExternCrateItem {
|
||||||
pub fn name_ref(&self) -> Option<NameRef> {
|
pub fn name_ref(&self) -> Option<NameRef> {
|
||||||
AstChildren::new(&self.syntax).next()
|
AstChildren::new(&self.syntax).next()
|
||||||
@ -2006,6 +2007,7 @@ impl AstNode for ModuleItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ast::AttrsOwner for ModuleItem {}
|
impl ast::AttrsOwner for ModuleItem {}
|
||||||
|
impl ast::VisibilityOwner for ModuleItem {}
|
||||||
impl ModuleItem {}
|
impl ModuleItem {}
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Name {
|
pub struct Name {
|
||||||
@ -3893,6 +3895,7 @@ impl AstNode for UseItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl ast::AttrsOwner for UseItem {}
|
impl ast::AttrsOwner for UseItem {}
|
||||||
|
impl ast::VisibilityOwner for UseItem {}
|
||||||
impl UseItem {
|
impl UseItem {
|
||||||
pub fn use_tree(&self) -> Option<UseTree> {
|
pub fn use_tree(&self) -> Option<UseTree> {
|
||||||
AstChildren::new(&self.syntax).next()
|
AstChildren::new(&self.syntax).next()
|
||||||
|
@ -412,7 +412,7 @@ Grammar(
|
|||||||
"ModuleItem": (
|
"ModuleItem": (
|
||||||
enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock",
|
enum: ["StructDef", "UnionDef", "EnumDef", "FnDef", "TraitDef", "TypeAliasDef", "ImplBlock",
|
||||||
"UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ],
|
"UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ],
|
||||||
traits: ["AttrsOwner"],
|
traits: ["AttrsOwner", "VisibilityOwner"],
|
||||||
),
|
),
|
||||||
"ImplItem": (
|
"ImplItem": (
|
||||||
enum: ["FnDef", "TypeAliasDef", "ConstDef"],
|
enum: ["FnDef", "TypeAliasDef", "ConstDef"],
|
||||||
@ -683,7 +683,7 @@ Grammar(
|
|||||||
]
|
]
|
||||||
),
|
),
|
||||||
"UseItem": (
|
"UseItem": (
|
||||||
traits: ["AttrsOwner"],
|
traits: ["AttrsOwner", "VisibilityOwner"],
|
||||||
options: [ "UseTree" ],
|
options: [ "UseTree" ],
|
||||||
),
|
),
|
||||||
"UseTree": (
|
"UseTree": (
|
||||||
@ -696,7 +696,7 @@ Grammar(
|
|||||||
collections: [("use_trees", "UseTree")]
|
collections: [("use_trees", "UseTree")]
|
||||||
),
|
),
|
||||||
"ExternCrateItem": (
|
"ExternCrateItem": (
|
||||||
traits: ["AttrsOwner"],
|
traits: ["AttrsOwner", "VisibilityOwner"],
|
||||||
options: ["NameRef", "Alias"],
|
options: ["NameRef", "Alias"],
|
||||||
),
|
),
|
||||||
"ArgList": (
|
"ArgList": (
|
||||||
|
Loading…
Reference in New Issue
Block a user