mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-26 13:03:31 +00:00
Remove visibility query, instead add struct field visibility to data
Methods should be handled the same, and for items the visibility will be in the def map.
This commit is contained in:
parent
50ebff257d
commit
78111620a3
5 changed files with 35 additions and 102 deletions
|
@ -257,8 +257,8 @@ impl StructField {
|
|||
|
||||
impl HasVisibility for StructField {
|
||||
fn visibility(&self, db: &impl HirDatabase) -> Visibility {
|
||||
let struct_field_id: hir_def::StructFieldId = (*self).into();
|
||||
let visibility = db.visibility(struct_field_id.into());
|
||||
let variant_data = self.parent.variant_data(db);
|
||||
let visibility = &variant_data.fields()[self.id].visibility;
|
||||
let parent_id: hir_def::VariantId = self.parent.into();
|
||||
visibility.resolve(db, &parent_id.resolver(db))
|
||||
}
|
||||
|
|
|
@ -9,11 +9,12 @@ use hir_expand::{
|
|||
};
|
||||
use ra_arena::{map::ArenaMap, Arena};
|
||||
use ra_prof::profile;
|
||||
use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner};
|
||||
use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner};
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, type_ref::TypeRef, EnumId,
|
||||
LocalEnumVariantId, LocalStructFieldId, Lookup, StructId, UnionId, VariantId,
|
||||
db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, type_ref::TypeRef,
|
||||
visibility::RawVisibility, EnumId, LocalEnumVariantId, LocalStructFieldId, Lookup, StructId,
|
||||
UnionId, VariantId,
|
||||
};
|
||||
|
||||
/// Note that we use `StructData` for unions as well!
|
||||
|
@ -47,13 +48,14 @@ pub enum VariantData {
|
|||
pub struct StructFieldData {
|
||||
pub name: Name,
|
||||
pub type_ref: TypeRef,
|
||||
pub visibility: RawVisibility,
|
||||
}
|
||||
|
||||
impl StructData {
|
||||
pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc<StructData> {
|
||||
let src = id.lookup(db).source(db);
|
||||
let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
|
||||
let variant_data = VariantData::new(src.value.kind());
|
||||
let variant_data = VariantData::new(db, src.map(|s| s.kind()));
|
||||
let variant_data = Arc::new(variant_data);
|
||||
Arc::new(StructData { name, variant_data })
|
||||
}
|
||||
|
@ -61,10 +63,12 @@ impl StructData {
|
|||
let src = id.lookup(db).source(db);
|
||||
let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
|
||||
let variant_data = VariantData::new(
|
||||
src.value
|
||||
.record_field_def_list()
|
||||
.map(ast::StructKind::Record)
|
||||
.unwrap_or(ast::StructKind::Unit),
|
||||
db,
|
||||
src.map(|s| {
|
||||
s.record_field_def_list()
|
||||
.map(ast::StructKind::Record)
|
||||
.unwrap_or(ast::StructKind::Unit)
|
||||
}),
|
||||
);
|
||||
let variant_data = Arc::new(variant_data);
|
||||
Arc::new(StructData { name, variant_data })
|
||||
|
@ -77,7 +81,7 @@ impl EnumData {
|
|||
let src = e.lookup(db).source(db);
|
||||
let name = src.value.name().map_or_else(Name::missing, |n| n.as_name());
|
||||
let mut trace = Trace::new_for_arena();
|
||||
lower_enum(&mut trace, &src.value);
|
||||
lower_enum(db, &mut trace, &src);
|
||||
Arc::new(EnumData { name, variants: trace.into_arena() })
|
||||
}
|
||||
|
||||
|
@ -93,30 +97,31 @@ impl HasChildSource for EnumId {
|
|||
fn child_source(&self, db: &impl DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> {
|
||||
let src = self.lookup(db).source(db);
|
||||
let mut trace = Trace::new_for_map();
|
||||
lower_enum(&mut trace, &src.value);
|
||||
lower_enum(db, &mut trace, &src);
|
||||
src.with_value(trace.into_map())
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_enum(
|
||||
db: &impl DefDatabase,
|
||||
trace: &mut Trace<LocalEnumVariantId, EnumVariantData, ast::EnumVariant>,
|
||||
ast: &ast::EnumDef,
|
||||
ast: &InFile<ast::EnumDef>,
|
||||
) {
|
||||
for var in ast.variant_list().into_iter().flat_map(|it| it.variants()) {
|
||||
for var in ast.value.variant_list().into_iter().flat_map(|it| it.variants()) {
|
||||
trace.alloc(
|
||||
|| var.clone(),
|
||||
|| EnumVariantData {
|
||||
name: var.name().map_or_else(Name::missing, |it| it.as_name()),
|
||||
variant_data: Arc::new(VariantData::new(var.kind())),
|
||||
variant_data: Arc::new(VariantData::new(db, ast.with_value(var.kind()))),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
impl VariantData {
|
||||
fn new(flavor: ast::StructKind) -> Self {
|
||||
fn new(db: &impl DefDatabase, flavor: InFile<ast::StructKind>) -> Self {
|
||||
let mut trace = Trace::new_for_arena();
|
||||
match lower_struct(&mut trace, &flavor) {
|
||||
match lower_struct(db, &mut trace, &flavor) {
|
||||
StructKind::Tuple => VariantData::Tuple(trace.into_arena()),
|
||||
StructKind::Record => VariantData::Record(trace.into_arena()),
|
||||
StructKind::Unit => VariantData::Unit,
|
||||
|
@ -163,7 +168,7 @@ impl HasChildSource for VariantId {
|
|||
}),
|
||||
};
|
||||
let mut trace = Trace::new_for_map();
|
||||
lower_struct(&mut trace, &src.value);
|
||||
lower_struct(db, &mut trace, &src);
|
||||
src.with_value(trace.into_map())
|
||||
}
|
||||
}
|
||||
|
@ -175,14 +180,15 @@ enum StructKind {
|
|||
}
|
||||
|
||||
fn lower_struct(
|
||||
db: &impl DefDatabase,
|
||||
trace: &mut Trace<
|
||||
LocalStructFieldId,
|
||||
StructFieldData,
|
||||
Either<ast::TupleFieldDef, ast::RecordFieldDef>,
|
||||
>,
|
||||
ast: &ast::StructKind,
|
||||
ast: &InFile<ast::StructKind>,
|
||||
) -> StructKind {
|
||||
match ast {
|
||||
match &ast.value {
|
||||
ast::StructKind::Tuple(fl) => {
|
||||
for (i, fd) in fl.fields().enumerate() {
|
||||
trace.alloc(
|
||||
|
@ -190,6 +196,7 @@ fn lower_struct(
|
|||
|| StructFieldData {
|
||||
name: Name::new_tuple_field(i),
|
||||
type_ref: TypeRef::from_ast_opt(fd.type_ref()),
|
||||
visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -202,6 +209,7 @@ fn lower_struct(
|
|||
|| StructFieldData {
|
||||
name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
|
||||
type_ref: TypeRef::from_ast_opt(fd.ascribed_type()),
|
||||
visibility: RawVisibility::from_ast(db, ast.with_value(fd.visibility())),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -14,10 +14,9 @@ use crate::{
|
|||
generics::GenericParams,
|
||||
lang_item::{LangItemTarget, LangItems},
|
||||
nameres::{raw::RawItems, CrateDefMap},
|
||||
visibility::RawVisibility,
|
||||
AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc,
|
||||
GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId,
|
||||
TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VisibilityDefId,
|
||||
TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc,
|
||||
};
|
||||
|
||||
#[salsa::query_group(InternDatabaseStorage)]
|
||||
|
@ -91,9 +90,6 @@ pub trait DefDatabase: InternDatabase + AstDatabase {
|
|||
#[salsa::invoke(Attrs::attrs_query)]
|
||||
fn attrs(&self, def: AttrDefId) -> Attrs;
|
||||
|
||||
#[salsa::invoke(RawVisibility::visibility_query)]
|
||||
fn visibility(&self, def: VisibilityDefId) -> RawVisibility;
|
||||
|
||||
#[salsa::invoke(LangItems::module_lang_items_query)]
|
||||
fn module_lang_items(&self, module: ModuleId) -> Option<Arc<LangItems>>;
|
||||
|
||||
|
|
|
@ -325,29 +325,6 @@ impl_froms!(
|
|||
ImplId
|
||||
);
|
||||
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum VisibilityDefId {
|
||||
ModuleId(ModuleId),
|
||||
StructFieldId(StructFieldId),
|
||||
AdtId(AdtId),
|
||||
FunctionId(FunctionId),
|
||||
StaticId(StaticId),
|
||||
ConstId(ConstId),
|
||||
TraitId(TraitId),
|
||||
TypeAliasId(TypeAliasId),
|
||||
}
|
||||
|
||||
impl_froms!(
|
||||
VisibilityDefId: ModuleId,
|
||||
StructFieldId,
|
||||
AdtId(StructId, EnumId, UnionId),
|
||||
StaticId,
|
||||
ConstId,
|
||||
FunctionId,
|
||||
TraitId,
|
||||
TypeAliasId
|
||||
);
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum VariantId {
|
||||
EnumVariantId(EnumVariantId),
|
||||
|
|
|
@ -2,16 +2,13 @@
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use either::Either;
|
||||
|
||||
use hir_expand::{hygiene::Hygiene, InFile};
|
||||
use ra_syntax::ast::{self, VisibilityOwner};
|
||||
use ra_syntax::ast;
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase,
|
||||
path::{ModPath, PathKind},
|
||||
src::{HasChildSource, HasSource},
|
||||
AdtId, Lookup, ModuleId, VisibilityDefId,
|
||||
ModuleId,
|
||||
};
|
||||
|
||||
/// Visibility of an item, not yet resolved.
|
||||
|
@ -28,51 +25,15 @@ pub enum RawVisibility {
|
|||
}
|
||||
|
||||
impl RawVisibility {
|
||||
pub(crate) fn visibility_query(db: &impl DefDatabase, def: VisibilityDefId) -> RawVisibility {
|
||||
match def {
|
||||
VisibilityDefId::ModuleId(module) => {
|
||||
let def_map = db.crate_def_map(module.krate);
|
||||
let src = match def_map[module.local_id].declaration_source(db) {
|
||||
Some(it) => it,
|
||||
None => return RawVisibility::private(),
|
||||
};
|
||||
RawVisibility::from_ast(db, src.map(|it| it.visibility()))
|
||||
}
|
||||
VisibilityDefId::StructFieldId(it) => {
|
||||
let src = it.parent.child_source(db);
|
||||
let is_enum = match it.parent {
|
||||
crate::VariantId::EnumVariantId(_) => true,
|
||||
_ => false,
|
||||
};
|
||||
let vis_node = src.map(|m| match &m[it.local_id] {
|
||||
Either::Left(tuple) => tuple.visibility(),
|
||||
Either::Right(record) => record.visibility(),
|
||||
});
|
||||
if vis_node.value.is_none() && is_enum {
|
||||
RawVisibility::Public
|
||||
} else {
|
||||
RawVisibility::from_ast(db, vis_node)
|
||||
}
|
||||
}
|
||||
VisibilityDefId::AdtId(it) => match it {
|
||||
AdtId::StructId(it) => visibility_from_loc(it.lookup(db), db),
|
||||
AdtId::EnumId(it) => visibility_from_loc(it.lookup(db), db),
|
||||
AdtId::UnionId(it) => visibility_from_loc(it.lookup(db), db),
|
||||
},
|
||||
VisibilityDefId::TraitId(it) => visibility_from_loc(it.lookup(db), db),
|
||||
VisibilityDefId::ConstId(it) => visibility_from_loc(it.lookup(db), db),
|
||||
VisibilityDefId::StaticId(it) => visibility_from_loc(it.lookup(db), db),
|
||||
VisibilityDefId::FunctionId(it) => visibility_from_loc(it.lookup(db), db),
|
||||
VisibilityDefId::TypeAliasId(it) => visibility_from_loc(it.lookup(db), db),
|
||||
}
|
||||
}
|
||||
|
||||
fn private() -> RawVisibility {
|
||||
let path = ModPath { kind: PathKind::Super(0), segments: Vec::new() };
|
||||
RawVisibility::Module(Arc::new(path))
|
||||
}
|
||||
|
||||
fn from_ast(db: &impl DefDatabase, node: InFile<Option<ast::Visibility>>) -> RawVisibility {
|
||||
pub(crate) fn from_ast(
|
||||
db: &impl DefDatabase,
|
||||
node: InFile<Option<ast::Visibility>>,
|
||||
) -> RawVisibility {
|
||||
Self::from_ast_with_hygiene(node.value, &Hygiene::new(db, node.file_id))
|
||||
}
|
||||
|
||||
|
@ -155,12 +116,3 @@ impl Visibility {
|
|||
ancestors.any(|m| m == to_module.local_id)
|
||||
}
|
||||
}
|
||||
|
||||
fn visibility_from_loc<T>(node: T, db: &impl DefDatabase) -> RawVisibility
|
||||
where
|
||||
T: HasSource,
|
||||
T::Value: ast::VisibilityOwner,
|
||||
{
|
||||
let src = node.source(db);
|
||||
RawVisibility::from_ast(db, src.map(|n| n.visibility()))
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue