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.rs133
1 files changed, 54 insertions, 79 deletions
diff --git a/crates/hir/src/attrs.rs b/crates/hir/src/attrs.rs
index e5a539cb8..c3e820d89 100644
--- a/crates/hir/src/attrs.rs
+++ b/crates/hir/src/attrs.rs
@@ -1,20 +1,32 @@
1//! Attributes & documentation for hir types. 1//! Attributes & documentation for hir types.
2use hir_def::{ 2use hir_def::{
3 attr::Attrs, 3 attr::Attrs, docs::Documentation, path::ModPath, resolver::HasResolver, AttrDefId, ModuleDefId,
4 docs::Documentation,
5 resolver::{HasResolver, Resolver},
6 AdtId, AttrDefId, FunctionId, GenericDefId, ModuleId, StaticId, TraitId, VariantId,
7}; 4};
5use hir_expand::hygiene::Hygiene;
8use hir_ty::db::HirDatabase; 6use hir_ty::db::HirDatabase;
7use syntax::ast;
9 8
10use crate::{ 9use crate::{
11 doc_links::Resolvable, Adt, Const, Enum, EnumVariant, Field, Function, GenericDef, ImplDef, 10 Adt, Const, Enum, EnumVariant, Field, Function, MacroDef, Module, ModuleDef, Static, Struct,
12 Local, MacroDef, Module, ModuleDef, Static, Struct, Trait, TypeAlias, TypeParam, Union, 11 Trait, TypeAlias, Union,
13}; 12};
14 13
15pub trait HasAttrs { 14pub trait HasAttrs {
16 fn attrs(self, db: &dyn HirDatabase) -> Attrs; 15 fn attrs(self, db: &dyn HirDatabase) -> Attrs;
17 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>; 16 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation>;
17 fn resolve_doc_path(
18 self,
19 db: &dyn HirDatabase,
20 link: &str,
21 ns: Option<Namespace>,
22 ) -> Option<ModuleDef>;
23}
24
25#[derive(PartialEq, Eq, Hash, Copy, Clone, Debug)]
26pub enum Namespace {
27 Types,
28 Values,
29 Macros,
18} 30}
19 31
20macro_rules! impl_has_attrs { 32macro_rules! impl_has_attrs {
@@ -28,6 +40,10 @@ macro_rules! impl_has_attrs {
28 let def = AttrDefId::$def_id(self.into()); 40 let def = AttrDefId::$def_id(self.into());
29 db.documentation(def) 41 db.documentation(def)
30 } 42 }
43 fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
44 let def = AttrDefId::$def_id(self.into());
45 resolve_doc_path(db, def, link, ns).map(ModuleDef::from)
46 }
31 } 47 }
32 )*}; 48 )*};
33} 49}
@@ -54,83 +70,42 @@ macro_rules! impl_has_attrs_adt {
54 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> { 70 fn docs(self, db: &dyn HirDatabase) -> Option<Documentation> {
55 Adt::$adt(self).docs(db) 71 Adt::$adt(self).docs(db)
56 } 72 }
73 fn resolve_doc_path(self, db: &dyn HirDatabase, link: &str, ns: Option<Namespace>) -> Option<ModuleDef> {
74 Adt::$adt(self).resolve_doc_path(db, link, ns)
75 }
57 } 76 }
58 )*}; 77 )*};
59} 78}
60 79
61impl_has_attrs_adt![Struct, Union, Enum]; 80impl_has_attrs_adt![Struct, Union, Enum];
62 81
63impl Resolvable for ModuleDef { 82fn resolve_doc_path(
64 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> { 83 db: &dyn HirDatabase,
65 Some(match self { 84 def: AttrDefId,
66 ModuleDef::Module(m) => ModuleId::from(m.clone()).resolver(db.upcast()), 85 link: &str,
67 ModuleDef::Function(f) => FunctionId::from(f.clone()).resolver(db.upcast()), 86 ns: Option<Namespace>,
68 ModuleDef::Adt(adt) => AdtId::from(adt.clone()).resolver(db.upcast()), 87) -> Option<ModuleDefId> {
69 ModuleDef::EnumVariant(ev) => { 88 let resolver = match def {
70 GenericDefId::from(GenericDef::from(ev.clone())).resolver(db.upcast()) 89 AttrDefId::ModuleId(it) => it.resolver(db.upcast()),
71 } 90 AttrDefId::FieldId(it) => it.parent.resolver(db.upcast()),
72 ModuleDef::Const(c) => { 91 AttrDefId::AdtId(it) => it.resolver(db.upcast()),
73 GenericDefId::from(GenericDef::from(c.clone())).resolver(db.upcast()) 92 AttrDefId::FunctionId(it) => it.resolver(db.upcast()),
74 } 93 AttrDefId::EnumVariantId(it) => it.parent.resolver(db.upcast()),
75 ModuleDef::Static(s) => StaticId::from(s.clone()).resolver(db.upcast()), 94 AttrDefId::StaticId(it) => it.resolver(db.upcast()),
76 ModuleDef::Trait(t) => TraitId::from(t.clone()).resolver(db.upcast()), 95 AttrDefId::ConstId(it) => it.resolver(db.upcast()),
77 ModuleDef::TypeAlias(t) => ModuleId::from(t.module(db)).resolver(db.upcast()), 96 AttrDefId::TraitId(it) => it.resolver(db.upcast()),
78 // FIXME: This should be a resolver relative to `std/core` 97 AttrDefId::TypeAliasId(it) => it.resolver(db.upcast()),
79 ModuleDef::BuiltinType(_t) => None?, 98 AttrDefId::ImplId(it) => it.resolver(db.upcast()),
80 }) 99 AttrDefId::MacroDefId(_) => return None,
81 } 100 };
82 101 let path = ast::Path::parse(link).ok()?;
83 fn try_into_module_def(self) -> Option<ModuleDef> { 102 let modpath = ModPath::from_src(path, &Hygiene::new_unhygienic()).unwrap();
84 Some(self) 103 let resolved = resolver.resolve_module_path_in_items(db.upcast(), &modpath);
85 } 104 let def = match ns {
86} 105 Some(Namespace::Types) => resolved.take_types()?,
87 106 Some(Namespace::Values) => resolved.take_values()?,
88impl Resolvable for TypeParam { 107 Some(Namespace::Macros) => return None,
89 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> { 108 None => resolved.iter_items().find_map(|it| it.as_module_def_id())?,
90 Some(ModuleId::from(self.module(db)).resolver(db.upcast())) 109 };
91 } 110 Some(def.into())
92
93 fn try_into_module_def(self) -> Option<ModuleDef> {
94 None
95 }
96}
97
98impl Resolvable for MacroDef {
99 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
100 Some(ModuleId::from(self.module(db)?).resolver(db.upcast()))
101 }
102
103 fn try_into_module_def(self) -> Option<ModuleDef> {
104 None
105 }
106}
107
108impl Resolvable for Field {
109 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
110 Some(VariantId::from(self.parent_def(db)).resolver(db.upcast()))
111 }
112
113 fn try_into_module_def(self) -> Option<ModuleDef> {
114 None
115 }
116}
117
118impl Resolvable for ImplDef {
119 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
120 Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
121 }
122
123 fn try_into_module_def(self) -> Option<ModuleDef> {
124 None
125 }
126}
127
128impl Resolvable for Local {
129 fn resolver(&self, db: &dyn HirDatabase) -> Option<Resolver> {
130 Some(ModuleId::from(self.module(db)).resolver(db.upcast()))
131 }
132
133 fn try_into_module_def(self) -> Option<ModuleDef> {
134 None
135 }
136} 111}