diff options
Diffstat (limited to 'crates/ra_hir/src')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 52 |
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 | ||
3 | use std::{ops::Index, sync::Arc}; | 3 | use std::{ops::Index, sync::Arc}; |
4 | 4 | ||
5 | use mbe::ast_to_token_tree; | ||
5 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | 6 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; |
6 | use ra_syntax::{ | 7 | use 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 | ||
32 | type Attrs = Arc<[tt::Subtree]>; | ||
33 | |||
31 | #[derive(Debug, Default, PartialEq, Eq)] | 34 | #[derive(Debug, Default, PartialEq, Eq)] |
32 | pub struct ImportSourceMap { | 35 | pub 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)] | ||
126 | pub(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)] |
123 | pub(super) enum RawItem { | 132 | pub(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 | ||