diff options
Diffstat (limited to 'crates/ra_hir_def/src/attr.rs')
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 52 |
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 | ||
5 | use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source}; | 5 | use hir_expand::{either::Either, hygiene::Hygiene, AstId, Source}; |
6 | use mbe::ast_to_token_tree; | 6 | use mbe::ast_to_token_tree; |
7 | use ra_cfg::CfgOptions; | ||
8 | use ra_syntax::{ | 7 | use 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 | |||
123 | pub struct AttrQuery<'a> { | ||
124 | attrs: &'a Attrs, | ||
125 | key: &'static str, | ||
126 | } | ||
131 | 127 | ||
132 | pub fn is_simple_atom(&self, name: &str) -> bool { | 128 | impl<'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 | ||