Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir/src/attrs.rs')
| -rw-r--r-- | crates/hir/src/attrs.rs | 256 |
1 files changed, 53 insertions, 203 deletions
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs index 3376c51fe5..147f1b8653 100644 --- a/crates/hir/src/attrs.rs +++ b/crates/hir/src/attrs.rs @@ -2,12 +2,9 @@ use std::ops::ControlFlow; -use cfg::CfgExpr; -use either::Either; use hir_def::{ - AssocItemId, AttrDefId, FieldId, InternedModuleId, LifetimeParamId, ModuleDefId, - TypeOrConstParamId, - attrs::{AttrFlags, Docs, IsInnerDoc}, + AssocItemId, AttrDefId, ModuleDefId, + attr::AttrsWithOwner, expr_store::path::Path, item_scope::ItemInNs, per_ns::Namespace, @@ -18,7 +15,6 @@ use hir_expand::{ name::Name, }; use hir_ty::{db::HirDatabase, method_resolution}; -use intern::Symbol; use crate::{ Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl, @@ -26,161 +22,28 @@ use crate::{ Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef, }; -#[derive(Debug, Clone, Copy)] -pub enum AttrsOwner { - AttrDef(AttrDefId), - Field(FieldId), - LifetimeParam(LifetimeParamId), - TypeOrConstParam(TypeOrConstParamId), -} - -impl AttrsOwner { - #[inline] - fn attr_def(&self) -> Option<AttrDefId> { - match self { - AttrsOwner::AttrDef(it) => Some(*it), - _ => None, - } - } -} - -#[derive(Debug, Clone)] -pub struct AttrsWithOwner { - pub(crate) attrs: AttrFlags, - owner: AttrsOwner, -} - -impl AttrsWithOwner { - fn new(db: &dyn HirDatabase, owner: AttrDefId) -> Self { - Self { attrs: AttrFlags::query(db, owner), owner: AttrsOwner::AttrDef(owner) } - } - - fn new_field(db: &dyn HirDatabase, owner: FieldId) -> Self { - Self { attrs: AttrFlags::query_field(db, owner), owner: AttrsOwner::Field(owner) } - } - - fn new_lifetime_param(db: &dyn HirDatabase, owner: LifetimeParamId) -> Self { - Self { - attrs: AttrFlags::query_lifetime_param(db, owner), - owner: AttrsOwner::LifetimeParam(owner), - } - } - fn new_type_or_const_param(db: &dyn HirDatabase, owner: TypeOrConstParamId) -> Self { - Self { - attrs: AttrFlags::query_type_or_const_param(db, owner), - owner: AttrsOwner::TypeOrConstParam(owner), - } - } - - #[inline] - pub fn is_unstable(&self) -> bool { - self.attrs.contains(AttrFlags::IS_UNSTABLE) - } - - #[inline] - pub fn is_macro_export(&self) -> bool { - self.attrs.contains(AttrFlags::IS_MACRO_EXPORT) - } - - #[inline] - pub fn is_doc_notable_trait(&self) -> bool { - self.attrs.contains(AttrFlags::IS_DOC_NOTABLE_TRAIT) - } - - #[inline] - pub fn is_doc_hidden(&self) -> bool { - self.attrs.contains(AttrFlags::IS_DOC_HIDDEN) - } - - #[inline] - pub fn is_deprecated(&self) -> bool { - self.attrs.contains(AttrFlags::IS_DEPRECATED) - } - - #[inline] - pub fn is_non_exhaustive(&self) -> bool { - self.attrs.contains(AttrFlags::NON_EXHAUSTIVE) - } - - #[inline] - pub fn is_test(&self) -> bool { - self.attrs.contains(AttrFlags::IS_TEST) - } - - #[inline] - pub fn lang(&self, db: &dyn HirDatabase) -> Option<&'static str> { - self.owner - .attr_def() - .and_then(|owner| self.attrs.lang_item_with_attrs(db, owner)) - .map(|lang| lang.name()) - } - - #[inline] - pub fn doc_aliases<'db>(&self, db: &'db dyn HirDatabase) -> &'db [Symbol] { - let owner = match self.owner { - AttrsOwner::AttrDef(it) => Either::Left(it), - AttrsOwner::Field(it) => Either::Right(it), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => return &[], - }; - self.attrs.doc_aliases(db, owner) - } - - #[inline] - pub fn cfgs<'db>(&self, db: &'db dyn HirDatabase) -> Option<&'db CfgExpr> { - let owner = match self.owner { - AttrsOwner::AttrDef(it) => Either::Left(it), - AttrsOwner::Field(it) => Either::Right(it), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => return None, - }; - self.attrs.cfgs(db, owner) - } - - #[inline] - pub fn hir_docs<'db>(&self, db: &'db dyn HirDatabase) -> Option<&'db Docs> { - match self.owner { - AttrsOwner::AttrDef(it) => AttrFlags::docs(db, it).as_deref(), - AttrsOwner::Field(it) => AttrFlags::field_docs(db, it), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => None, - } - } -} - -pub trait HasAttrs: Sized { - #[inline] - fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner { - match self.attr_id(db) { - AttrsOwner::AttrDef(it) => AttrsWithOwner::new(db, it), - AttrsOwner::Field(it) => AttrsWithOwner::new_field(db, it), - AttrsOwner::LifetimeParam(it) => AttrsWithOwner::new_lifetime_param(db, it), - AttrsOwner::TypeOrConstParam(it) => AttrsWithOwner::new_type_or_const_param(db, it), - } - } - +pub trait HasAttrs { + fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner; #[doc(hidden)] - fn attr_id(self, db: &dyn HirDatabase) -> AttrsOwner; - - #[inline] - fn hir_docs(self, db: &dyn HirDatabase) -> Option<&Docs> { - match self.attr_id(db) { - AttrsOwner::AttrDef(it) => AttrFlags::docs(db, it).as_deref(), - AttrsOwner::Field(it) => AttrFlags::field_docs(db, it), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => None, - } - } + fn attr_id(self) -> AttrDefId; } macro_rules! impl_has_attrs { ($(($def:ident, $def_id:ident),)*) => {$( impl HasAttrs for $def { - #[inline] - fn attr_id(self, _db: &dyn HirDatabase) -> AttrsOwner { - AttrsOwner::AttrDef(AttrDefId::$def_id(self.into())) + fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner { + let def = AttrDefId::$def_id(self.into()); + AttrsWithOwner::new(db, def) + } + fn attr_id(self) -> AttrDefId { + AttrDefId::$def_id(self.into()) } } )*}; } impl_has_attrs![ + (Field, FieldId), (Variant, EnumVariantId), (Static, StaticId), (Const, ConstId), @@ -189,6 +52,8 @@ impl_has_attrs![ (Macro, MacroId), (Function, FunctionId), (Adt, AdtId), + (Module, ModuleId), + (GenericParam, GenericParamId), (Impl, ImplId), (ExternCrateDecl, ExternCrateId), ]; @@ -196,9 +61,11 @@ impl_has_attrs![ macro_rules! impl_has_attrs_enum { ($($variant:ident),* for $enum:ident) => {$( impl HasAttrs for $variant { - #[inline] - fn attr_id(self, db: &dyn HirDatabase) -> AttrsOwner { - $enum::$variant(self).attr_id(db) + fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner { + $enum::$variant(self).attrs(db) + } + fn attr_id(self) -> AttrDefId { + $enum::$variant(self).attr_id() } } )*}; @@ -207,46 +74,30 @@ macro_rules! impl_has_attrs_enum { impl_has_attrs_enum![Struct, Union, Enum for Adt]; impl_has_attrs_enum![TypeParam, ConstParam, LifetimeParam for GenericParam]; -impl HasAttrs for Module { - #[inline] - fn attr_id(self, db: &dyn HirDatabase) -> AttrsOwner { - AttrsOwner::AttrDef(AttrDefId::ModuleId(InternedModuleId::new(db, self.id))) - } -} - -impl HasAttrs for GenericParam { - #[inline] - fn attr_id(self, _db: &dyn HirDatabase) -> AttrsOwner { +impl HasAttrs for AssocItem { + fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner { match self { - GenericParam::TypeParam(it) => AttrsOwner::TypeOrConstParam(it.merge().into()), - GenericParam::ConstParam(it) => AttrsOwner::TypeOrConstParam(it.merge().into()), - GenericParam::LifetimeParam(it) => AttrsOwner::LifetimeParam(it.into()), + AssocItem::Function(it) => it.attrs(db), + AssocItem::Const(it) => it.attrs(db), + AssocItem::TypeAlias(it) => it.attrs(db), } } -} - -impl HasAttrs for AssocItem { - #[inline] - fn attr_id(self, db: &dyn HirDatabase) -> AttrsOwner { + fn attr_id(self) -> AttrDefId { match self { - AssocItem::Function(it) => it.attr_id(db), - AssocItem::Const(it) => it.attr_id(db), - AssocItem::TypeAlias(it) => it.attr_id(db), + AssocItem::Function(it) => it.attr_id(), + AssocItem::Const(it) => it.attr_id(), + AssocItem::TypeAlias(it) => it.attr_id(), } } } impl HasAttrs for crate::Crate { - #[inline] - fn attr_id(self, db: &dyn HirDatabase) -> AttrsOwner { - self.root_module().attr_id(db) + fn attrs(self, db: &dyn HirDatabase) -> AttrsWithOwner { + let def = AttrDefId::ModuleId(self.root_module().id); + AttrsWithOwner::new(db, def) } -} - -impl HasAttrs for Field { - #[inline] - fn attr_id(self, _db: &dyn HirDatabase) -> AttrsOwner { - AttrsOwner::Field(self.into()) + fn attr_id(self) -> AttrDefId { + AttrDefId::ModuleId(self.root_module().id) } } @@ -256,22 +107,21 @@ pub fn resolve_doc_path_on( def: impl HasAttrs + Copy, link: &str, ns: Option<Namespace>, - is_inner_doc: IsInnerDoc, + is_inner_doc: bool, ) -> Option<DocLinkDef> { - resolve_doc_path_on_(db, link, def.attr_id(db), ns, is_inner_doc) + resolve_doc_path_on_(db, link, def.attr_id(), ns, is_inner_doc) } fn resolve_doc_path_on_( db: &dyn HirDatabase, link: &str, - attr_id: AttrsOwner, + attr_id: AttrDefId, ns: Option<Namespace>, - is_inner_doc: IsInnerDoc, + is_inner_doc: bool, ) -> Option<DocLinkDef> { let resolver = match attr_id { - AttrsOwner::AttrDef(AttrDefId::ModuleId(it)) => { - let it = it.loc(db); - if is_inner_doc.yes() { + AttrDefId::ModuleId(it) => { + if is_inner_doc { it.resolver(db) } else if let Some(parent) = Module::from(it).parent(db) { parent.id.resolver(db) @@ -279,20 +129,20 @@ fn resolve_doc_path_on_( it.resolver(db) } } - AttrsOwner::AttrDef(AttrDefId::AdtId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::FunctionId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::EnumVariantId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::StaticId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::ConstId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::TraitId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::TypeAliasId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::ImplId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::ExternBlockId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::UseId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::MacroId(it)) => it.resolver(db), - AttrsOwner::AttrDef(AttrDefId::ExternCrateId(it)) => it.resolver(db), - AttrsOwner::Field(it) => it.parent.resolver(db), - AttrsOwner::LifetimeParam(_) | AttrsOwner::TypeOrConstParam(_) => return None, + AttrDefId::FieldId(it) => it.parent.resolver(db), + AttrDefId::AdtId(it) => it.resolver(db), + AttrDefId::FunctionId(it) => it.resolver(db), + AttrDefId::EnumVariantId(it) => it.resolver(db), + AttrDefId::StaticId(it) => it.resolver(db), + AttrDefId::ConstId(it) => it.resolver(db), + AttrDefId::TraitId(it) => it.resolver(db), + AttrDefId::TypeAliasId(it) => it.resolver(db), + AttrDefId::ImplId(it) => it.resolver(db), + AttrDefId::ExternBlockId(it) => it.resolver(db), + AttrDefId::UseId(it) => it.resolver(db), + AttrDefId::MacroId(it) => it.resolver(db), + AttrDefId::ExternCrateId(it) => it.resolver(db), + AttrDefId::GenericParamId(_) => return None, }; let mut modpath = doc_modpath_from_str(link)?; |