aboutsummaryrefslogtreecommitdiff
path: root/crates/hir/src/attrs.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir/src/attrs.rs')
-rw-r--r--crates/hir/src/attrs.rs132
1 files changed, 132 insertions, 0 deletions
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
new file mode 100644
index 000000000..953960e14
--- /dev/null
+++ b/crates/hir/src/attrs.rs
@@ -0,0 +1,132 @@
1//! Attributes & documentation for hir types.
2use hir_def::{
3 attr::Attrs,
4 db::DefDatabase,
5 docs::Documentation,
6 resolver::{HasResolver, Resolver},
7 AdtId, FunctionId, GenericDefId, ModuleId, StaticId, TraitId, VariantId,
8};
9use hir_ty::db::HirDatabase;
10use stdx::impl_from;
11
12use crate::{
13 doc_links::Resolvable, Adt, Const, Enum, EnumVariant, Field, Function, GenericDef, ImplDef,
14 Local, MacroDef, Module, ModuleDef, Static, Struct, Trait, TypeAlias, TypeParam, Union,
15};
16
17#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
18pub enum AttrDef {
19 Module(Module),
20 Field(Field),
21 Adt(Adt),
22 Function(Function),
23 EnumVariant(EnumVariant),
24 Static(Static),
25 Const(Const),
26 Trait(Trait),
27 TypeAlias(TypeAlias),
28 MacroDef(MacroDef),
29}
30
31impl_from!(
32 Module,
33 Field,
34 Adt(Struct, Enum, Union),
35 EnumVariant,
36 Static,
37 Const,
38 Function,
39 Trait,
40 TypeAlias,
41 MacroDef
42 for AttrDef
43);
44
45pub trait HasAttrs {
46 fn attrs(self, db: &dyn HirDatabase) -> Attrs;
47 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>;
48}
49
50impl<T: Into<AttrDef>> HasAttrs for T {
51 fn attrs(self, db: &dyn HirDatabase) -> Attrs {
52 let def: AttrDef = self.into();
53 db.attrs(def.into())
54 }
55 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
56 let def: AttrDef = self.into();
57 db.documentation(def.into())
58 }
59}
60
61impl Resolvable for ModuleDef {
62 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
63 Some(match self {
64 ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db),
65 ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db),
66 ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db),
67 ModuleDef::EnumVariant(ev) => {
68 GenericDefId::from(GenericDef::from(ev.clone())).resolver(db)
69 }
70 ModuleDef::Const(c) => GenericDefId::from(GenericDef::from(c.clone())).resolver(db),
71 ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db),
72 ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db),
73 ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db),
74 // FIXME: This should be a resolver relative to `std/core`
75 ModuleDef::BuiltinType(_t) => None?,
76 })
77 }
78
79 fn try_into_module_def(self) -> Option<ModuleDef> {
80 Some(self)
81 }
82}
83
84impl Resolvable for TypeParam {
85 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
86 Some(ModuleId::from(self.module(db)).resolver(db))
87 }
88
89 fn try_into_module_def(self) -> Option<ModuleDef> {
90 None
91 }
92}
93
94impl Resolvable for MacroDef {
95 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
96 Some(ModuleId::from(self.module(db)?).resolver(db))
97 }
98
99 fn try_into_module_def(self) -> Option<ModuleDef> {
100 None
101 }
102}
103
104impl Resolvable for Field {
105 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
106 Some(VariantId::from(self.parent_def(db)).resolver(db))
107 }
108
109 fn try_into_module_def(self) -> Option<ModuleDef> {
110 None
111 }
112}
113
114impl Resolvable for ImplDef {
115 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
116 Some(ModuleId::from(self.module(db)).resolver(db))
117 }
118
119 fn try_into_module_def(self) -> Option<ModuleDef> {
120 None
121 }
122}
123
124impl Resolvable for Local {
125 fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> {
126 Some(ModuleId::from(self.module(db)).resolver(db))
127 }
128
129 fn try_into_module_def(self) -> Option<ModuleDef> {
130 None
131 }
132}