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.rs256
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)?;