diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/raw.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 54 |
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::{ | |||
10 | use test_utils::tested_by; | 10 | use test_utils::tested_by; |
11 | 11 | ||
12 | use crate::{ | 12 | use 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. | ||
124 | pub(super) type Attrs = Option<Arc<[Attr]>>; | ||
125 | |||
126 | #[derive(Debug, PartialEq, Eq, Clone)] | ||
127 | pub(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)] |
123 | pub(super) enum RawItem { | 133 | pub(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 | ||