aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres/raw.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/nameres/raw.rs')
-rw-r--r--crates/ra_hir/src/nameres/raw.rs54
1 files changed, 44 insertions, 10 deletions
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs
index 606bd1a95..623b343c4 100644
--- a/crates/ra_hir/src/nameres/raw.rs
+++ b/crates/ra_hir/src/nameres/raw.rs
@@ -10,6 +10,7 @@ use ra_syntax::{
10use test_utils::tested_by; 10use test_utils::tested_by;
11 11
12use crate::{ 12use crate::{
13 attr::Attr,
13 db::{AstDatabase, DefDatabase}, 14 db::{AstDatabase, DefDatabase},
14 AsName, AstIdMap, Either, FileAstId, HirFileId, ModuleSource, Name, Path, Source, 15 AsName, AstIdMap, Either, FileAstId, HirFileId, ModuleSource, Name, Path, Source,
15}; 16};
@@ -119,8 +120,17 @@ impl Index<Macro> for RawItems {
119 } 120 }
120} 121}
121 122
123// Avoid heap allocation on items without attributes.
124pub(super) type Attrs = Option<Arc<[Attr]>>;
125
126#[derive(Debug, PartialEq, Eq, Clone)]
127pub(super) struct RawItem {
128 pub(super) attrs: Attrs,
129 pub(super) kind: RawItemKind,
130}
131
122#[derive(Debug, PartialEq, Eq, Clone, Copy)] 132#[derive(Debug, PartialEq, Eq, Clone, Copy)]
123pub(super) enum RawItem { 133pub(super) enum RawItemKind {
124 Module(Module), 134 Module(Module),
125 Import(ImportId), 135 Import(ImportId),
126 Def(Def), 136 Def(Def),
@@ -215,6 +225,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
215 } 225 }
216 226
217 fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) { 227 fn add_item(&mut self, current_module: Option<Module>, item: ast::ModuleItem) {
228 let attrs = self.parse_attrs(&item);
218 let (kind, name) = match item { 229 let (kind, name) = match item {
219 ast::ModuleItem::Module(module) => { 230 ast::ModuleItem::Module(module) => {
220 self.add_module(current_module, module); 231 self.add_module(current_module, module);
@@ -263,7 +274,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
263 if let Some(name) = name { 274 if let Some(name) = name {
264 let name = name.as_name(); 275 let name = name.as_name();
265 let def = self.raw_items.defs.alloc(DefData { name, kind }); 276 let def = self.raw_items.defs.alloc(DefData { name, kind });
266 self.push_item(current_module, RawItem::Def(def)) 277 self.push_item(current_module, attrs, RawItemKind::Def(def));
267 } 278 }
268 } 279 }
269 280
@@ -272,8 +283,10 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
272 Some(it) => it.as_name(), 283 Some(it) => it.as_name(),
273 None => return, 284 None => return,
274 }; 285 };
286 let attrs = self.parse_attrs(&module);
275 287
276 let ast_id = self.source_ast_id_map.ast_id(&module); 288 let ast_id = self.source_ast_id_map.ast_id(&module);
289 // FIXME: cfg_attr
277 let is_macro_use = module.has_atom_attr("macro_use"); 290 let is_macro_use = module.has_atom_attr("macro_use");
278 if module.has_semi() { 291 if module.has_semi() {
279 let attr_path = extract_mod_path_attribute(&module); 292 let attr_path = extract_mod_path_attribute(&module);
@@ -283,7 +296,7 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
283 attr_path, 296 attr_path,
284 is_macro_use, 297 is_macro_use,
285 }); 298 });
286 self.push_item(current_module, RawItem::Module(item)); 299 self.push_item(current_module, attrs, RawItemKind::Module(item));
287 return; 300 return;
288 } 301 }
289 302
@@ -297,14 +310,16 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
297 is_macro_use, 310 is_macro_use,
298 }); 311 });
299 self.process_module(Some(item), item_list); 312 self.process_module(Some(item), item_list);
300 self.push_item(current_module, RawItem::Module(item)); 313 self.push_item(current_module, attrs, RawItemKind::Module(item));
301 return; 314 return;
302 } 315 }
303 tested_by!(name_res_works_for_broken_modules); 316 tested_by!(name_res_works_for_broken_modules);
304 } 317 }
305 318
306 fn add_use_item(&mut self, current_module: Option<Module>, use_item: ast::UseItem) { 319 fn add_use_item(&mut self, current_module: Option<Module>, use_item: ast::UseItem) {
320 // FIXME: cfg_attr
307 let is_prelude = use_item.has_atom_attr("prelude_import"); 321 let is_prelude = use_item.has_atom_attr("prelude_import");
322 let attrs = self.parse_attrs(&use_item);
308 323
309 Path::expand_use_item( 324 Path::expand_use_item(
310 Source { ast: use_item, file_id: self.file_id }, 325 Source { ast: use_item, file_id: self.file_id },
@@ -318,7 +333,12 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
318 is_extern_crate: false, 333 is_extern_crate: false,
319 is_macro_use: false, 334 is_macro_use: false,
320 }; 335 };
321 self.push_import(current_module, import_data, Either::A(AstPtr::new(use_tree))); 336 self.push_import(
337 current_module,
338 attrs.clone(),
339 import_data,
340 Either::A(AstPtr::new(use_tree)),
341 );
322 }, 342 },
323 ) 343 )
324 } 344 }
@@ -331,6 +351,8 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
331 if let Some(name_ref) = extern_crate.name_ref() { 351 if let Some(name_ref) = extern_crate.name_ref() {
332 let path = Path::from_name_ref(&name_ref); 352 let path = Path::from_name_ref(&name_ref);
333 let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name()); 353 let alias = extern_crate.alias().and_then(|a| a.name()).map(|it| it.as_name());
354 let attrs = self.parse_attrs(&extern_crate);
355 // FIXME: cfg_attr
334 let is_macro_use = extern_crate.has_atom_attr("macro_use"); 356 let is_macro_use = extern_crate.has_atom_attr("macro_use");
335 let import_data = ImportData { 357 let import_data = ImportData {
336 path, 358 path,
@@ -340,11 +362,17 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
340 is_extern_crate: true, 362 is_extern_crate: true,
341 is_macro_use, 363 is_macro_use,
342 }; 364 };
343 self.push_import(current_module, import_data, Either::B(AstPtr::new(&extern_crate))); 365 self.push_import(
366 current_module,
367 attrs,
368 import_data,
369 Either::B(AstPtr::new(&extern_crate)),
370 );
344 } 371 }
345 } 372 }
346 373
347 fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) { 374 fn add_macro(&mut self, current_module: Option<Module>, m: ast::MacroCall) {
375 let attrs = self.parse_attrs(&m);
348 let path = match m 376 let path = match m
349 .path() 377 .path()
350 .and_then(|path| Path::from_src(Source { ast: path, file_id: self.file_id }, self.db)) 378 .and_then(|path| Path::from_src(Source { ast: path, file_id: self.file_id }, self.db))
@@ -355,24 +383,26 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
355 383
356 let name = m.name().map(|it| it.as_name()); 384 let name = m.name().map(|it| it.as_name());
357 let ast_id = self.source_ast_id_map.ast_id(&m); 385 let ast_id = self.source_ast_id_map.ast_id(&m);
386 // FIXME: cfg_attr
358 let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export"); 387 let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export");
359 388
360 let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export }); 389 let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export });
361 self.push_item(current_module, RawItem::Macro(m)); 390 self.push_item(current_module, attrs, RawItemKind::Macro(m));
362 } 391 }
363 392
364 fn push_import( 393 fn push_import(
365 &mut self, 394 &mut self,
366 current_module: Option<Module>, 395 current_module: Option<Module>,
396 attrs: Attrs,
367 data: ImportData, 397 data: ImportData,
368 source: ImportSourcePtr, 398 source: ImportSourcePtr,
369 ) { 399 ) {
370 let import = self.raw_items.imports.alloc(data); 400 let import = self.raw_items.imports.alloc(data);
371 self.source_map.insert(import, source); 401 self.source_map.insert(import, source);
372 self.push_item(current_module, RawItem::Import(import)) 402 self.push_item(current_module, attrs, RawItemKind::Import(import))
373 } 403 }
374 404
375 fn push_item(&mut self, current_module: Option<Module>, item: RawItem) { 405 fn push_item(&mut self, current_module: Option<Module>, attrs: Attrs, kind: RawItemKind) {
376 match current_module { 406 match current_module {
377 Some(module) => match &mut self.raw_items.modules[module] { 407 Some(module) => match &mut self.raw_items.modules[module] {
378 ModuleData::Definition { items, .. } => items, 408 ModuleData::Definition { items, .. } => items,
@@ -380,7 +410,11 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> {
380 }, 410 },
381 None => &mut self.raw_items.items, 411 None => &mut self.raw_items.items,
382 } 412 }
383 .push(item) 413 .push(RawItem { attrs, kind })
414 }
415
416 fn parse_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
417 Attr::from_attrs_owner(self.file_id, item, self.db)
384 } 418 }
385} 419}
386 420