aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r--crates/ra_hir/src/nameres/collector.rs19
-rw-r--r--crates/ra_hir/src/nameres/raw.rs52
2 files changed, 51 insertions, 20 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index a568fdabd..40e56dfe0 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -523,7 +523,7 @@ where
523 // `#[macro_use] extern crate` is hoisted to imports macros before collecting 523 // `#[macro_use] extern crate` is hoisted to imports macros before collecting
524 // any other items. 524 // any other items.
525 for item in items { 525 for item in items {
526 if let raw::RawItem::Import(import_id) = *item { 526 if let raw::RawItemKind::Import(import_id) = item.kind {
527 let import = self.raw_items[import_id].clone(); 527 let import = self.raw_items[import_id].clone();
528 if import.is_extern_crate && import.is_macro_use { 528 if import.is_extern_crate && import.is_macro_use {
529 self.def_collector.import_macros_from_extern_crate(self.module_id, &import); 529 self.def_collector.import_macros_from_extern_crate(self.module_id, &import);
@@ -532,15 +532,14 @@ where
532 } 532 }
533 533
534 for item in items { 534 for item in items {
535 match *item { 535 match item.kind {
536 raw::RawItem::Module(m) => self.collect_module(&self.raw_items[m]), 536 raw::RawItemKind::Module(m) => self.collect_module(&self.raw_items[m]),
537 raw::RawItem::Import(import_id) => self.def_collector.unresolved_imports.push(( 537 raw::RawItemKind::Import(import_id) => self
538 self.module_id, 538 .def_collector
539 import_id, 539 .unresolved_imports
540 self.raw_items[import_id].clone(), 540 .push((self.module_id, import_id, self.raw_items[import_id].clone())),
541 )), 541 raw::RawItemKind::Def(def) => self.define_def(&self.raw_items[def]),
542 raw::RawItem::Def(def) => self.define_def(&self.raw_items[def]), 542 raw::RawItemKind::Macro(mac) => self.collect_macro(&self.raw_items[mac]),
543 raw::RawItem::Macro(mac) => self.collect_macro(&self.raw_items[mac]),
544 } 543 }
545 } 544 }
546 } 545 }
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 606bd1a95..cacbcb517 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -2,6 +2,7 @@
2 2
3use std::{ops::Index, sync::Arc}; 3use std::{ops::Index, sync::Arc};
4 4
5use mbe::ast_to_token_tree;
5use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; 6use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId};
6use ra_syntax::{ 7use ra_syntax::{
7 ast::{self, AttrsOwner, NameOwner}, 8 ast::{self, AttrsOwner, NameOwner},
@@ -28,6 +29,8 @@ pub struct RawItems {
28 items: Vec<RawItem>, 29 items: Vec<RawItem>,
29} 30}
30 31
32type Attrs = Arc<[tt::Subtree]>;
33
31#[derive(Debug, Default, PartialEq, Eq)] 34#[derive(Debug, Default, PartialEq, Eq)]
32pub struct ImportSourceMap { 35pub struct ImportSourceMap {
33 map: ArenaMap<ImportId, ImportSourcePtr>, 36 map: ArenaMap<ImportId, ImportSourcePtr>,
@@ -119,8 +122,14 @@ impl Index<Macro> for RawItems {
119 } 122 }
120} 123}
121 124
125#[derive(Debug, PartialEq, Eq, Clone)]
126pub(super) struct RawItem {
127 pub(super) attrs: Attrs,
128 pub(super) kind: RawItemKind,
129}
130
122#[derive(Debug, PartialEq, Eq, Clone, Copy)] 131#[derive(Debug, PartialEq, Eq, Clone, Copy)]
123pub(super) enum RawItem { 132pub(super) enum RawItemKind {
124 Module(Module), 133 Module(Module),
125 Import(ImportId), 134 Import(ImportId),
126 Def(Def), 135 Def(Def),
@@ -215,6 +224,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
215 } 224 }
216 225
217 fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) { 226 fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) {
227 let attrs = self.parse_attrs(&item);
218 let (kind, name) = match item { 228 let (kind, name) = match item {
219 ast::ModuleItem::Module(module) => { 229 ast::ModuleItem::Module(module) => {
220 self.add_module(current_module, module); 230 self.add_module(current_module, module);
@@ -263,7 +273,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
263 if let Some(name) = name { 273 if let Some(name) = name {
264 let name = name.as_name(); 274 let name = name.as_name();
265 let def = self.raw_items.defs.alloc(DefData { name, kind }); 275 let def = self.raw_items.defs.alloc(DefData { name, kind });
266 self.push_item(current_module, RawItem::Def(def)) 276 self.push_item(current_module, attrs, RawItemKind::Def(def));
267 } 277 }
268 } 278 }
269 279
@@ -272,6 +282,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
272 Some(it) => it.as_name(), 282 Some(it) => it.as_name(),
273 None => return, 283 None => return,
274 }; 284 };
285 let attrs = self.parse_attrs(&module);
275 286
276 let ast_id = self.source_ast_id_map.ast_id(&module); 287 let ast_id = self.source_ast_id_map.ast_id(&module);
277 let is_macro_use = module.has_atom_attr("macro_use"); 288 let is_macro_use = module.has_atom_attr("macro_use");
@@ -283,7 +294,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
283 attr_path, 294 attr_path,
284 is_macro_use, 295 is_macro_use,
285 }); 296 });
286 self.push_item(current_module, RawItem::Module(item)); 297 self.push_item(current_module, attrs, RawItemKind::Module(item));
287 return; 298 return;
288 } 299 }
289 300
@@ -297,7 +308,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
297 is_macro_use, 308 is_macro_use,
298 }); 309 });
299 self.process_module(Some(item), item_list); 310 self.process_module(Some(item), item_list);
300 self.push_item(current_module, RawItem::Module(item)); 311 self.push_item(current_module, attrs, RawItemKind::Module(item));
301 return; 312 return;
302 } 313 }
303 tested_by!(name_res_works_for_broken_modules); 314 tested_by!(name_res_works_for_broken_modules);
@@ -305,6 +316,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
305 316
306 fn add_use_item(&mut self, current_module: Option<Module>, use_item: ast::UseItem) { 317 fn add_use_item(&mut self, current_module: Option<Module>, use_item: ast::UseItem) {
307 let is_prelude = use_item.has_atom_attr("prelude_import"); 318 let is_prelude = use_item.has_atom_attr("prelude_import");
319 let attrs = self.parse_attrs(&use_item);
308 320
309 Path::expand_use_item( 321 Path::expand_use_item(
310 Source { ast: use_item, file_id: self.file_id }, 322 Source { ast: use_item, file_id: self.file_id },
@@ -318,7 +330,12 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
318 is_extern_crate: false, 330 is_extern_crate: false,
319 is_macro_use: false, 331 is_macro_use: false,
320 }; 332 };
321 self.push_import(current_module, import_data, Either::A(AstPtr::new(use_tree))); 333 self.push_import(
334 current_module,
335 attrs.clone(),
336 import_data,
337 Either::A(AstPtr::new(use_tree)),
338 );
322 }, 339 },
323 ) 340 )
324 } 341 }
@@ -331,6 +348,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
331 if let Some(name_ref) = extern_crate.name_ref() { 348 if let Some(name_ref) = extern_crate.name_ref() {
332 let path = Path::from_name_ref(&name_ref); 349 let path = Path::from_name_ref(&name_ref);
333 let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); 350 let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name());
351 let attrs = self.parse_attrs(&extern_crate);
334 let is_macro_use = extern_crate.has_atom_attr("macro_use"); 352 let is_macro_use = extern_crate.has_atom_attr("macro_use");
335 let import_data = ImportData { 353 let import_data = ImportData {
336 path, 354 path,
@@ -340,7 +358,12 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
340 is_extern_crate: true, 358 is_extern_crate: true,
341 is_macro_use, 359 is_macro_use,
342 }; 360 };
343 self.push_import(current_module, import_data, Either::B(AstPtr::new(&extern_crate))); 361 self.push_import(
362 current_module,
363 attrs,
364 import_data,
365 Either::B(AstPtr::new(&extern_crate)),
366 );
344 } 367 }
345 } 368 }
346 369
@@ -358,21 +381,22 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
358 let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export"); 381 let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export");
359 382
360 let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export }); 383 let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export });
361 self.push_item(current_module, RawItem::Macro(m)); 384 self.push_item(current_module, attrs, RawItemKind::Macro(m));
362 } 385 }
363 386
364 fn push_import( 387 fn push_import(
365 &mut self, 388 &mut self,
366 current_module: Option<Module>, 389 current_module: Option<Module>,
390 attrs: Attrs,
367 data: ImportData, 391 data: ImportData,
368 source: ImportSourcePtr, 392 source: ImportSourcePtr,
369 ) { 393 ) {
370 let import = self.raw_items.imports.alloc(data); 394 let import = self.raw_items.imports.alloc(data);
371 self.source_map.insert(import, source); 395 self.source_map.insert(import, source);
372 self.push_item(current_module, RawItem::Import(import)) 396 self.push_item(current_module, attrs, RawItemKind::Import(import))
373 } 397 }
374 398
375 fn push_item(&mut self, current_module: Option<Module>, item: RawItem) { 399 fn push_item(&mut self, current_module: Option<Module>, attrs: Attrs, kind: RawItemKind) {
376 match current_module { 400 match current_module {
377 Some(module) => match &mut self.raw_items.modules[module] { 401 Some(module) => match &mut self.raw_items.modules[module] {
378 ModuleData::Definition { items, .. } => items, 402 ModuleData::Definition { items, .. } => items,
@@ -380,7 +404,15 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
380 }, 404 },
381 None => &mut self.raw_items.items, 405 None => &mut self.raw_items.items,
382 } 406 }
383 .push(item) 407 .push(RawItem { attrs, kind })
408 }
409
410 fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
411 item.attrs()
412 .flat_map(|attr| attr.value())
413 .flat_map(|tt| ast_to_token_tree(&tt))
414 .map(|(tt, _)| tt)
415 .collect()
384 } 416 }
385} 417}
386 418