diff options
Diffstat (limited to 'crates/hir/src/attrs.rs')
-rw-r--r-- | crates/hir/src/attrs.rs | 132 |
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..2603411eb --- /dev/null +++ b/crates/hir/src/attrs.rs | |||
@@ -0,0 +1,132 @@ | |||
1 | use hir_def::{ | ||
2 | attr::Attrs, | ||
3 | db::DefDatabase, | ||
4 | docs::Documentation, | ||
5 | resolver::{HasResolver, Resolver}, | ||
6 | AdtId, FunctionId, GenericDefId, ModuleId, StaticId, TraitId, VariantId, | ||
7 | }; | ||
8 | use hir_ty::db::HirDatabase; | ||
9 | use stdx::impl_from; | ||
10 | |||
11 | use crate::{ | ||
12 | doc_links::Resolvable, Adt, Const, Enum, EnumVariant, Field, Function, GenericDef, ImplDef, | ||
13 | Local, MacroDef, Module, ModuleDef, Static, Struct, Trait, TypeAlias, TypeParam, Union, | ||
14 | VariantDef, | ||
15 | }; | ||
16 | |||
17 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | ||
18 | pub 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 | |||
31 | impl_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 | |||
45 | pub trait HasAttrs { | ||
46 | fn attrs(self, db: &dyn HirDatabase) -> Attrs; | ||
47 | fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>; | ||
48 | } | ||
49 | |||
50 | impl<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 | |||
61 | impl 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 | |||
84 | impl Resolvable for TypeParam { | ||
85 | fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { | ||
86 | Some(Into::<ModuleId>::into(self.module(db)).resolver(db)) | ||
87 | } | ||
88 | |||
89 | fn try_into_module_def(self) -> Option<ModuleDef> { | ||
90 | None | ||
91 | } | ||
92 | } | ||
93 | |||
94 | impl Resolvable for MacroDef { | ||
95 | fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { | ||
96 | Some(Into::<ModuleId>::into(self.module(db)?).resolver(db)) | ||
97 | } | ||
98 | |||
99 | fn try_into_module_def(self) -> Option<ModuleDef> { | ||
100 | None | ||
101 | } | ||
102 | } | ||
103 | |||
104 | impl Resolvable for Field { | ||
105 | fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { | ||
106 | Some(Into::<VariantId>::into(Into::<VariantDef>::into(self.parent_def(db))).resolver(db)) | ||
107 | } | ||
108 | |||
109 | fn try_into_module_def(self) -> Option<ModuleDef> { | ||
110 | None | ||
111 | } | ||
112 | } | ||
113 | |||
114 | impl Resolvable for ImplDef { | ||
115 | fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { | ||
116 | Some(Into::<ModuleId>::into(self.module(db)).resolver(db)) | ||
117 | } | ||
118 | |||
119 | fn try_into_module_def(self) -> Option<ModuleDef> { | ||
120 | None | ||
121 | } | ||
122 | } | ||
123 | |||
124 | impl Resolvable for Local { | ||
125 | fn resolver<D: DefDatabase + HirDatabase>(&self, db: &D) -> Option<Resolver> { | ||
126 | Some(Into::<ModuleId>::into(self.module(db)).resolver(db)) | ||
127 | } | ||
128 | |||
129 | fn try_into_module_def(self) -> Option<ModuleDef> { | ||
130 | None | ||
131 | } | ||
132 | } | ||