aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/attr.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2019-11-24 13:03:02 +0000
committerAleksey Kladov <[email protected]>2019-11-24 13:03:02 +0000
commit4b74fb1d896ce5a1c8c4c4bf73ad2940fb86abc5 (patch)
tree1d4d51e200305e5adee78b28a0f86343d3bab0fd /crates/ra_hir_def/src/attr.rs
parent1956d57ed4896bb29dfcfaed2a5291ec69251f52 (diff)
Nicer API for attrs
Diffstat (limited to 'crates/ra_hir_def/src/attr.rs')
-rw-r--r--crates/ra_hir_def/src/attr.rs52
1 files changed, 27 insertions, 25 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 5c1b151f7..53456fc08 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -4,7 +4,6 @@ use std::{ops, sync::Arc};
4 4
5use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source}; 5use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source};
6use mbe::ast_to_token_tree; 6use mbe::ast_to_token_tree;
7use ra_cfg::CfgOptions;
8use ra_syntax::{ 7use ra_syntax::{
9 ast::{self, AstNode, AttrsOwner}, 8 ast::{self, AstNode, AttrsOwner},
10 SmolStr, 9 SmolStr,
@@ -85,17 +84,8 @@ impl Attrs {
85 Attrs { entries } 84 Attrs { entries }
86 } 85 }
87 86
88 pub fn has_atom(&self, atom: &str) -> bool { 87 pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> {
89 self.iter().any(|it| it.is_simple_atom(atom)) 88 AttrQuery { attrs: self, key }
90 }
91
92 pub fn find_string_value(&self, key: &str) -> Option<SmolStr> {
93 self.iter().filter(|attr| attr.is_simple_atom(key)).find_map(|attr| {
94 match attr.input.as_ref()? {
95 AttrInput::Literal(it) => Some(it.clone()),
96 _ => None,
97 }
98 })
99 } 89 }
100} 90}
101 91
@@ -128,25 +118,37 @@ impl Attr {
128 118
129 Some(Attr { path, input }) 119 Some(Attr { path, input })
130 } 120 }
121}
122
123pub struct AttrQuery<'a> {
124 attrs: &'a Attrs,
125 key: &'static str,
126}
131 127
132 pub fn is_simple_atom(&self, name: &str) -> bool { 128impl<'a> AttrQuery<'a> {
133 // FIXME: Avoid cloning 129 pub fn tt_values(self) -> impl Iterator<Item = &'a Subtree> {
134 self.path.as_ident().map_or(false, |s| s.to_string() == name) 130 self.attrs().filter_map(|attr| match attr.input.as_ref()? {
131 AttrInput::TokenTree(it) => Some(it),
132 _ => None,
133 })
135 } 134 }
136 135
137 // FIXME: handle cfg_attr :-) 136 pub fn string_value(self) -> Option<&'a SmolStr> {
138 pub fn as_cfg(&self) -> Option<&Subtree> { 137 self.attrs().find_map(|attr| match attr.input.as_ref()? {
139 if !self.is_simple_atom("cfg") { 138 AttrInput::Literal(it) => Some(it),
140 return None;
141 }
142 match &self.input {
143 Some(AttrInput::TokenTree(subtree)) => Some(subtree),
144 _ => None, 139 _ => None,
145 } 140 })
141 }
142
143 pub fn exists(self) -> bool {
144 self.attrs().next().is_some()
146 } 145 }
147 146
148 pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Option<bool> { 147 fn attrs(self) -> impl Iterator<Item = &'a Attr> {
149 cfg_options.is_cfg_enabled(self.as_cfg()?) 148 let key = self.key;
149 self.attrs
150 .iter()
151 .filter(move |attr| attr.path.as_ident().map_or(false, |s| s.to_string() == key))
150 } 152 }
151} 153}
152 154