diff options
Diffstat (limited to 'crates/ra_hir_def/src/attr.rs')
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 7a9d0fdf4..ce397f6b0 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::{ops, sync::Arc}; | 3 | use std::{ops, sync::Arc}; |
4 | 4 | ||
5 | use hir_expand::hygiene::Hygiene; | 5 | use hir_expand::{either::Either, hygiene::Hygiene, AstId}; |
6 | use mbe::ast_to_token_tree; | 6 | use mbe::ast_to_token_tree; |
7 | use ra_cfg::CfgOptions; | 7 | use ra_cfg::CfgOptions; |
8 | use ra_syntax::{ | 8 | use ra_syntax::{ |
@@ -11,7 +11,9 @@ use ra_syntax::{ | |||
11 | }; | 11 | }; |
12 | use tt::Subtree; | 12 | use tt::Subtree; |
13 | 13 | ||
14 | use crate::path::Path; | 14 | use crate::{ |
15 | db::DefDatabase2, path::Path, AdtId, AstItemDef, AttrDefId, HasChildSource, HasSource, Lookup, | ||
16 | }; | ||
15 | 17 | ||
16 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | 18 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
17 | pub struct Attrs { | 19 | pub struct Attrs { |
@@ -30,6 +32,46 @@ impl ops::Deref for Attrs { | |||
30 | } | 32 | } |
31 | 33 | ||
32 | impl Attrs { | 34 | impl Attrs { |
35 | pub(crate) fn attrs_query(db: &impl DefDatabase2, def: AttrDefId) -> Attrs { | ||
36 | match def { | ||
37 | AttrDefId::ModuleId(module) => { | ||
38 | let def_map = db.crate_def_map(module.krate); | ||
39 | let src = match def_map[module.module_id].declaration_source(db) { | ||
40 | Some(it) => it, | ||
41 | None => return Attrs::default(), | ||
42 | }; | ||
43 | let hygiene = Hygiene::new(db, src.file_id); | ||
44 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
45 | } | ||
46 | AttrDefId::StructFieldId(it) => { | ||
47 | let src = it.parent.child_source(db); | ||
48 | match &src.value[it.local_id] { | ||
49 | Either::A(_tuple) => Attrs::default(), | ||
50 | Either::B(record) => { | ||
51 | let hygiene = Hygiene::new(db, src.file_id); | ||
52 | Attr::from_attrs_owner(record, &hygiene) | ||
53 | } | ||
54 | } | ||
55 | } | ||
56 | AttrDefId::AdtId(it) => match it { | ||
57 | AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), | ||
58 | AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
59 | AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db), | ||
60 | }, | ||
61 | AttrDefId::EnumVariantId(it) => { | ||
62 | let src = it.parent.child_source(db); | ||
63 | let hygiene = Hygiene::new(db, src.file_id); | ||
64 | Attr::from_attrs_owner(&src.value[it.local_id], &hygiene) | ||
65 | } | ||
66 | AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
67 | AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db), | ||
68 | AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db), | ||
69 | AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db), | ||
70 | AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db), | ||
71 | AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db), | ||
72 | } | ||
73 | } | ||
74 | |||
33 | pub fn has_atom(&self, atom: &str) -> bool { | 75 | pub fn has_atom(&self, atom: &str) -> bool { |
34 | self.iter().any(|it| it.is_simple_atom(atom)) | 76 | self.iter().any(|it| it.is_simple_atom(atom)) |
35 | } | 77 | } |
@@ -106,3 +148,23 @@ impl Attr { | |||
106 | cfg_options.is_cfg_enabled(self.as_cfg()?) | 148 | cfg_options.is_cfg_enabled(self.as_cfg()?) |
107 | } | 149 | } |
108 | } | 150 | } |
151 | |||
152 | fn attrs_from_ast<D, N>(src: AstId<N>, db: &D) -> Attrs | ||
153 | where | ||
154 | N: ast::AttrsOwner, | ||
155 | D: DefDatabase2, | ||
156 | { | ||
157 | let hygiene = Hygiene::new(db, src.file_id()); | ||
158 | Attr::from_attrs_owner(&src.to_node(db), &hygiene) | ||
159 | } | ||
160 | |||
161 | fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs | ||
162 | where | ||
163 | T: HasSource, | ||
164 | T::Value: ast::AttrsOwner, | ||
165 | D: DefDatabase2, | ||
166 | { | ||
167 | let src = node.source(db); | ||
168 | let hygiene = Hygiene::new(db, src.file_id); | ||
169 | Attr::from_attrs_owner(&src.value, &hygiene) | ||
170 | } | ||