aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/attr.rs52
-rw-r--r--crates/ra_hir_def/src/lang_item.rs2
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs14
3 files changed, 37 insertions, 31 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
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