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.rs66
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
3use std::{ops, sync::Arc}; 3use std::{ops, sync::Arc};
4 4
5use hir_expand::hygiene::Hygiene; 5use hir_expand::{either::Either, hygiene::Hygiene, AstId};
6use mbe::ast_to_token_tree; 6use mbe::ast_to_token_tree;
7use ra_cfg::CfgOptions; 7use ra_cfg::CfgOptions;
8use ra_syntax::{ 8use ra_syntax::{
@@ -11,7 +11,9 @@ use ra_syntax::{
11}; 11};
12use tt::Subtree; 12use tt::Subtree;
13 13
14use crate::path::Path; 14use 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)]
17pub struct Attrs { 19pub struct Attrs {
@@ -30,6 +32,46 @@ impl ops::Deref for Attrs {
30} 32}
31 33
32impl Attrs { 34impl 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
152fn attrs_from_ast<D, N>(src: AstId<N>, db: &D) -> Attrs
153where
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
161fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs
162where
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}