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.rs76
1 files changed, 74 insertions, 2 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 7a9d0fdf4..48ce8cd93 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::DefDatabase, 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,9 +32,59 @@ impl ops::Deref for Attrs {
30} 32}
31 33
32impl Attrs { 34impl Attrs {
35 pub(crate) fn attrs_query(db: &impl DefDatabase, 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::EnumVariantId(it) => {
57 let src = it.parent.child_source(db);
58 let hygiene = Hygiene::new(db, src.file_id);
59 Attr::from_attrs_owner(&src.value[it.local_id], &hygiene)
60 }
61 AttrDefId::AdtId(it) => match it {
62 AdtId::StructId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db),
63 AdtId::EnumId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
64 AdtId::UnionId(it) => attrs_from_ast(it.0.lookup_intern(db).ast_id, db),
65 },
66 AttrDefId::StaticId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
67 AttrDefId::TraitId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
68 AttrDefId::MacroDefId(it) => attrs_from_ast(it.ast_id, db),
69 AttrDefId::ImplId(it) => attrs_from_ast(it.lookup_intern(db).ast_id, db),
70 AttrDefId::ConstId(it) => attrs_from_loc(it.lookup(db), db),
71 AttrDefId::FunctionId(it) => attrs_from_loc(it.lookup(db), db),
72 AttrDefId::TypeAliasId(it) => attrs_from_loc(it.lookup(db), db),
73 }
74 }
75
33 pub fn has_atom(&self, atom: &str) -> bool { 76 pub fn has_atom(&self, atom: &str) -> bool {
34 self.iter().any(|it| it.is_simple_atom(atom)) 77 self.iter().any(|it| it.is_simple_atom(atom))
35 } 78 }
79
80 pub fn find_string_value(&self, key: &str) -> Option<SmolStr> {
81 self.iter().filter(|attr| attr.is_simple_atom(key)).find_map(|attr| {
82 match attr.input.as_ref()? {
83 AttrInput::Literal(it) => Some(it.clone()),
84 _ => None,
85 }
86 })
87 }
36} 88}
37 89
38#[derive(Debug, Clone, PartialEq, Eq)] 90#[derive(Debug, Clone, PartialEq, Eq)]
@@ -106,3 +158,23 @@ impl Attr {
106 cfg_options.is_cfg_enabled(self.as_cfg()?) 158 cfg_options.is_cfg_enabled(self.as_cfg()?)
107 } 159 }
108} 160}
161
162fn attrs_from_ast<D, N>(src: AstId<N>, db: &D) -> Attrs
163where
164 N: ast::AttrsOwner,
165 D: DefDatabase,
166{
167 let hygiene = Hygiene::new(db, src.file_id());
168 Attr::from_attrs_owner(&src.to_node(db), &hygiene)
169}
170
171fn attrs_from_loc<T, D>(node: T, db: &D) -> Attrs
172where
173 T: HasSource,
174 T::Value: ast::AttrsOwner,
175 D: DefDatabase,
176{
177 let src = node.source(db);
178 let hygiene = Hygiene::new(db, src.file_id);
179 Attr::from_attrs_owner(&src.value, &hygiene)
180}