diff options
author | Aleksey Kladov <[email protected]> | 2019-11-24 13:03:02 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-11-24 13:03:02 +0000 |
commit | 4b74fb1d896ce5a1c8c4c4bf73ad2940fb86abc5 (patch) | |
tree | 1d4d51e200305e5adee78b28a0f86343d3bab0fd /crates | |
parent | 1956d57ed4896bb29dfcfaed2a5291ec69251f52 (diff) |
Nicer API for attrs
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 52 | ||||
-rw-r--r-- | crates/ra_hir_def/src/lang_item.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 14 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/presentation.rs | 2 |
4 files changed, 38 insertions, 32 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 | ||
diff --git a/crates/ra_hir_def/src/lang_item.rs b/crates/ra_hir_def/src/lang_item.rs index 69d7bf21a..3b9fb0328 100644 --- a/crates/ra_hir_def/src/lang_item.rs +++ b/crates/ra_hir_def/src/lang_item.rs | |||
@@ -113,7 +113,7 @@ impl LangItems { | |||
113 | T: Into<AttrDefId> + Copy, | 113 | T: Into<AttrDefId> + Copy, |
114 | { | 114 | { |
115 | let attrs = db.attrs(item.into()); | 115 | let attrs = db.attrs(item.into()); |
116 | if let Some(lang_item_name) = attrs.find_string_value("lang") { | 116 | if let Some(lang_item_name) = attrs.by_key("lang").string_value() { |
117 | self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item)); | 117 | self.items.entry(lang_item_name.clone()).or_insert_with(|| constructor(item)); |
118 | } | 118 | } |
119 | } | 119 | } |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 15941a1cb..7a5f90327 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -599,8 +599,8 @@ where | |||
599 | } | 599 | } |
600 | 600 | ||
601 | fn collect_module(&mut self, module: &raw::ModuleData, attrs: &Attrs) { | 601 | fn collect_module(&mut self, module: &raw::ModuleData, attrs: &Attrs) { |
602 | let path_attr = attrs.find_string_value("path"); | 602 | let path_attr = attrs.by_key("path").string_value(); |
603 | let is_macro_use = attrs.has_atom("macro_use"); | 603 | let is_macro_use = attrs.by_key("macro_use").exists(); |
604 | match module { | 604 | match module { |
605 | // inline module, just recurse | 605 | // inline module, just recurse |
606 | raw::ModuleData::Definition { name, items, ast_id } => { | 606 | raw::ModuleData::Definition { name, items, ast_id } => { |
@@ -612,7 +612,7 @@ where | |||
612 | module_id, | 612 | module_id, |
613 | file_id: self.file_id, | 613 | file_id: self.file_id, |
614 | raw_items: self.raw_items, | 614 | raw_items: self.raw_items, |
615 | mod_dir: self.mod_dir.descend_into_definition(name, path_attr.as_ref()), | 615 | mod_dir: self.mod_dir.descend_into_definition(name, path_attr), |
616 | } | 616 | } |
617 | .collect(&*items); | 617 | .collect(&*items); |
618 | if is_macro_use { | 618 | if is_macro_use { |
@@ -626,7 +626,7 @@ where | |||
626 | self.def_collector.db, | 626 | self.def_collector.db, |
627 | self.file_id, | 627 | self.file_id, |
628 | name, | 628 | name, |
629 | path_attr.as_ref(), | 629 | path_attr, |
630 | ) { | 630 | ) { |
631 | Ok((file_id, mod_dir)) => { | 631 | Ok((file_id, mod_dir)) => { |
632 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); | 632 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); |
@@ -796,7 +796,11 @@ where | |||
796 | } | 796 | } |
797 | 797 | ||
798 | fn is_cfg_enabled(&self, attrs: &Attrs) -> bool { | 798 | fn is_cfg_enabled(&self, attrs: &Attrs) -> bool { |
799 | attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) | 799 | // FIXME: handle cfg_attr :-) |
800 | attrs | ||
801 | .by_key("cfg") | ||
802 | .tt_values() | ||
803 | .all(|tt| self.def_collector.cfg_options.is_cfg_enabled(tt) != Some(false)) | ||
800 | } | 804 | } |
801 | } | 805 | } |
802 | 806 | ||
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 896ad1517..bac3f7582 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs | |||
@@ -288,7 +288,7 @@ impl Completions { | |||
288 | } | 288 | } |
289 | 289 | ||
290 | fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool { | 290 | fn is_deprecated(node: impl HasAttrs, db: &impl HirDatabase) -> bool { |
291 | node.attrs(db).has_atom("deprecated") | 291 | node.attrs(db).by_key("deprecated").exists() |
292 | } | 292 | } |
293 | 293 | ||
294 | fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { | 294 | fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { |