aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_hir/src/attr.rs24
-rw-r--r--crates/ra_hir/src/nameres/collector.rs30
-rw-r--r--crates/ra_hir/src/nameres/raw.rs43
3 files changed, 42 insertions, 55 deletions
diff --git a/crates/ra_hir/src/attr.rs b/crates/ra_hir/src/attr.rs
index f67e80bfd..bd159a566 100644
--- a/crates/ra_hir/src/attr.rs
+++ b/crates/ra_hir/src/attr.rs
@@ -63,14 +63,24 @@ impl Attr {
63 self.path.as_ident().map_or(false, |s| s.to_string() == name) 63 self.path.as_ident().map_or(false, |s| s.to_string() == name)
64 } 64 }
65 65
66 // FIXME: handle cfg_attr :-)
66 pub(crate) fn as_cfg(&self) -> Option<&Subtree> { 67 pub(crate) fn as_cfg(&self) -> Option<&Subtree> {
67 if self.is_simple_atom("cfg") { 68 if !self.is_simple_atom("cfg") {
68 match &self.input { 69 return None;
69 Some(AttrInput::TokenTree(subtree)) => Some(subtree), 70 }
70 _ => None, 71 match &self.input {
71 } 72 Some(AttrInput::TokenTree(subtree)) => Some(subtree),
72 } else { 73 _ => None,
73 None 74 }
75 }
76
77 pub(crate) fn as_path(&self) -> Option<&SmolStr> {
78 if !self.is_simple_atom("path") {
79 return None;
80 }
81 match &self.input {
82 Some(AttrInput::Literal(it)) => Some(it),
83 _ => None,
74 } 84 }
75 } 85 }
76 86
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 5dacdb0d9..aa5885f04 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -2,7 +2,7 @@
2 2
3use ra_cfg::CfgOptions; 3use ra_cfg::CfgOptions;
4use ra_db::FileId; 4use ra_db::FileId;
5use ra_syntax::ast; 5use ra_syntax::{ast, SmolStr};
6use rustc_hash::FxHashMap; 6use rustc_hash::FxHashMap;
7use test_utils::tested_by; 7use test_utils::tested_by;
8 8
@@ -546,7 +546,9 @@ where
546 for item in items { 546 for item in items {
547 if self.is_cfg_enabled(item.attrs()) { 547 if self.is_cfg_enabled(item.attrs()) {
548 match item.kind { 548 match item.kind {
549 raw::RawItemKind::Module(m) => self.collect_module(&self.raw_items[m]), 549 raw::RawItemKind::Module(m) => {
550 self.collect_module(&self.raw_items[m], item.attrs())
551 }
550 raw::RawItemKind::Import(import_id) => self 552 raw::RawItemKind::Import(import_id) => self
551 .def_collector 553 .def_collector
552 .unresolved_imports 554 .unresolved_imports
@@ -558,10 +560,12 @@ where
558 } 560 }
559 } 561 }
560 562
561 fn collect_module(&mut self, module: &raw::ModuleData) { 563 fn collect_module(&mut self, module: &raw::ModuleData, attrs: &[Attr]) {
564 let path_attr = self.path_attr(attrs);
565 let is_macro_use = self.is_macro_use(attrs);
562 match module { 566 match module {
563 // inline module, just recurse 567 // inline module, just recurse
564 raw::ModuleData::Definition { name, items, ast_id, attr_path, is_macro_use } => { 568 raw::ModuleData::Definition { name, items, ast_id } => {
565 let module_id = 569 let module_id =
566 self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); 570 self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None);
567 571
@@ -570,21 +574,21 @@ where
570 module_id, 574 module_id,
571 file_id: self.file_id, 575 file_id: self.file_id,
572 raw_items: self.raw_items, 576 raw_items: self.raw_items,
573 mod_dir: self.mod_dir.descend_into_definition(name, attr_path.as_ref()), 577 mod_dir: self.mod_dir.descend_into_definition(name, path_attr),
574 } 578 }
575 .collect(&*items); 579 .collect(&*items);
576 if *is_macro_use { 580 if is_macro_use {
577 self.import_all_legacy_macros(module_id); 581 self.import_all_legacy_macros(module_id);
578 } 582 }
579 } 583 }
580 // out of line module, resolve, parse and recurse 584 // out of line module, resolve, parse and recurse
581 raw::ModuleData::Declaration { name, ast_id, attr_path, is_macro_use } => { 585 raw::ModuleData::Declaration { name, ast_id } => {
582 let ast_id = ast_id.with_file_id(self.file_id); 586 let ast_id = ast_id.with_file_id(self.file_id);
583 match self.mod_dir.resolve_submodule( 587 match self.mod_dir.resolve_submodule(
584 self.def_collector.db, 588 self.def_collector.db,
585 self.file_id, 589 self.file_id,
586 name, 590 name,
587 attr_path.as_ref(), 591 path_attr,
588 ) { 592 ) {
589 Ok((file_id, mod_dir)) => { 593 Ok((file_id, mod_dir)) => {
590 let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); 594 let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
@@ -597,7 +601,7 @@ where
597 mod_dir, 601 mod_dir,
598 } 602 }
599 .collect(raw_items.items()); 603 .collect(raw_items.items());
600 if *is_macro_use { 604 if is_macro_use {
601 self.import_all_legacy_macros(module_id); 605 self.import_all_legacy_macros(module_id);
602 } 606 }
603 } 607 }
@@ -713,6 +717,14 @@ where
713 fn is_cfg_enabled(&self, attrs: &[Attr]) -> bool { 717 fn is_cfg_enabled(&self, attrs: &[Attr]) -> bool {
714 attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) 718 attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false))
715 } 719 }
720
721 fn path_attr<'a>(&self, attrs: &'a [Attr]) -> Option<&'a SmolStr> {
722 attrs.iter().find_map(|attr| attr.as_path())
723 }
724
725 fn is_macro_use<'a>(&self, attrs: &'a [Attr]) -> bool {
726 attrs.iter().any(|attr| attr.is_simple_atom("macro_use"))
727 }
716} 728}
717 729
718fn is_macro_rules(path: &Path) -> bool { 730fn is_macro_rules(path: &Path) -> bool {
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 5f93f920f..57f2929c3 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -5,7 +5,7 @@ use std::{ops::Index, sync::Arc};
5use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 5use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
6use ra_syntax::{ 6use ra_syntax::{
7 ast::{self, AttrsOwner, NameOwner}, 7 ast::{self, AttrsOwner, NameOwner},
8 AstNode, AstPtr, SmolStr, SourceFile, 8 AstNode, AstPtr, SourceFile,
9}; 9};
10use test_utils::tested_by; 10use test_utils::tested_by;
11 11
@@ -149,19 +149,8 @@ impl_arena_id!(Module);
149 149
150#[derive(Debug, PartialEq, Eq)] 150#[derive(Debug, PartialEq, Eq)]
151pub(super) enum ModuleData { 151pub(super) enum ModuleData {
152 Declaration { 152 Declaration { name: Name, ast_id: FileAstId<ast::Module> },
153 name: Name, 153 Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> },
154 ast_id: FileAstId<ast::Module>,
155 attr_path: Option<SmolStr>,
156 is_macro_use: bool,
157 },
158 Definition {
159 name: Name,
160 ast_id: FileAstId<ast::Module>,
161 items: Vec<RawItem>,
162 attr_path: Option<SmolStr>,
163 is_macro_use: bool,
164 },
165} 154}
166 155
167#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] 156#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -292,28 +281,17 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
292 let attrs = self.parse_attrs(&module); 281 let attrs = self.parse_attrs(&module);
293 282
294 let ast_id = self.source_ast_id_map.ast_id(&module); 283 let ast_id = self.source_ast_id_map.ast_id(&module);
295 // FIXME: cfg_attr
296 let is_macro_use = module.has_atom_attr("macro_use");
297 if module.has_semi() { 284 if module.has_semi() {
298 let attr_path = extract_mod_path_attribute(&module); 285 let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id });
299 let item = self.raw_items.modules.alloc(ModuleData::Declaration {
300 name,
301 ast_id,
302 attr_path,
303 is_macro_use,
304 });
305 self.push_item(current_module, attrs, RawItemKind::Module(item)); 286 self.push_item(current_module, attrs, RawItemKind::Module(item));
306 return; 287 return;
307 } 288 }
308 289
309 if let Some(item_list) = module.item_list() { 290 if let Some(item_list) = module.item_list() {
310 let attr_path = extract_mod_path_attribute(&module);
311 let item = self.raw_items.modules.alloc(ModuleData::Definition { 291 let item = self.raw_items.modules.alloc(ModuleData::Definition {
312 name, 292 name,
313 ast_id, 293 ast_id,
314 items: Vec::new(), 294 items: Vec::new(),
315 attr_path,
316 is_macro_use,
317 }); 295 });
318 self.process_module(Some(item), item_list); 296 self.process_module(Some(item), item_list);
319 self.push_item(current_module, attrs, RawItemKind::Module(item)); 297 self.push_item(current_module, attrs, RawItemKind::Module(item));
@@ -423,16 +401,3 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
423 Attr::from_attrs_owner(self.file_id, item, self.db) 401 Attr::from_attrs_owner(self.file_id, item, self.db)
424 } 402 }
425} 403}
426
427fn extract_mod_path_attribute(module: &ast::Module) -> Option<SmolStr> {
428 module.attrs().into_iter().find_map(|attr| {
429 attr.as_simple_key_value().and_then(|(name, value)| {
430 let is_path = name == "path";
431 if is_path {
432 Some(value)
433 } else {
434 None
435 }
436 })
437 })
438}