aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/attr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/attr.rs')
-rw-r--r--crates/ra_hir_def/src/attr.rs49
1 files changed, 32 insertions, 17 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 2eeba0572..197737ffc 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -13,7 +13,11 @@ use ra_syntax::{
13use tt::Subtree; 13use tt::Subtree;
14 14
15use crate::{ 15use crate::{
16 db::DefDatabase, nameres::ModuleSource, path::ModPath, src::HasChildSource, src::HasSource, 16 db::DefDatabase,
17 item_tree::{ItemTreeId, ItemTreeNode},
18 nameres::ModuleSource,
19 path::ModPath,
20 src::HasChildSource,
17 AdtId, AttrDefId, Lookup, 21 AdtId, AttrDefId, Lookup,
18}; 22};
19 23
@@ -34,6 +38,8 @@ impl ops::Deref for Attrs {
34} 38}
35 39
36impl Attrs { 40impl Attrs {
41 pub const EMPTY: Attrs = Attrs { entries: None };
42
37 pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { 43 pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
38 match def { 44 match def {
39 AttrDefId::ModuleId(module) => { 45 AttrDefId::ModuleId(module) => {
@@ -65,19 +71,19 @@ impl Attrs {
65 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) 71 Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner))
66 } 72 }
67 AttrDefId::AdtId(it) => match it { 73 AttrDefId::AdtId(it) => match it {
68 AdtId::StructId(it) => attrs_from_loc(it.lookup(db), db), 74 AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db),
69 AdtId::EnumId(it) => attrs_from_loc(it.lookup(db), db), 75 AdtId::EnumId(it) => attrs_from_item_tree(it.lookup(db).id, db),
70 AdtId::UnionId(it) => attrs_from_loc(it.lookup(db), db), 76 AdtId::UnionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
71 }, 77 },
72 AttrDefId::TraitId(it) => attrs_from_loc(it.lookup(db), db), 78 AttrDefId::TraitId(it) => attrs_from_item_tree(it.lookup(db).id, db),
73 AttrDefId::MacroDefId(it) => { 79 AttrDefId::MacroDefId(it) => {
74 it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db)) 80 it.ast_id.map_or_else(Default::default, |ast_id| attrs_from_ast(ast_id, db))
75 } 81 }
76 AttrDefId::ImplId(it) => attrs_from_loc(it.lookup(db), db), 82 AttrDefId::ImplId(it) => attrs_from_item_tree(it.lookup(db).id, db),
77 AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), 83 AttrDefId::ConstId(it) => attrs_from_item_tree(it.lookup(db).id, db),
78 AttrDefId::StaticId(it) => attrs_from_loc(it.lookup(db), db), 84 AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db),
79 AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), 85 AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db),
80 AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), 86 AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db),
81 } 87 }
82 } 88 }
83 89
@@ -103,6 +109,18 @@ impl Attrs {
103 Attrs { entries } 109 Attrs { entries }
104 } 110 }
105 111
112 pub fn merge(&self, other: Attrs) -> Attrs {
113 match (&self.entries, &other.entries) {
114 (None, None) => Attrs { entries: None },
115 (Some(entries), None) | (None, Some(entries)) => {
116 Attrs { entries: Some(entries.clone()) }
117 }
118 (Some(a), Some(b)) => {
119 Attrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) }
120 }
121 }
122 }
123
106 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { 124 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
107 AttrQuery { attrs: self, key } 125 AttrQuery { attrs: self, key }
108 } 126 }
@@ -187,11 +205,8 @@ where
187 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) 205 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
188} 206}
189 207
190fn attrs_from_loc<T>(node: T, db: &dyn DefDatabase) -> Attrs 208fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs {
191where 209 let tree = db.item_tree(id.file_id);
192 T: HasSource, 210 let mod_item = N::id_to_mod_item(id.value);
193 T::Value: ast::AttrsOwner, 211 tree.attrs(mod_item).clone()
194{
195 let src = node.source(db);
196 Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner))
197} 212}