diff options
-rw-r--r-- | crates/ra_hir/src/code_model/attrs.rs | 16 | ||||
-rw-r--r-- | crates/ra_hir/src/db.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 36 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 18 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/presentation.rs | 5 |
6 files changed, 57 insertions, 42 deletions
diff --git a/crates/ra_hir/src/code_model/attrs.rs b/crates/ra_hir/src/code_model/attrs.rs index 9e304217c..9923cde81 100644 --- a/crates/ra_hir/src/code_model/attrs.rs +++ b/crates/ra_hir/src/code_model/attrs.rs | |||
@@ -8,7 +8,6 @@ use crate::{ | |||
8 | use hir_def::attr::Attr; | 8 | use hir_def::attr::Attr; |
9 | use hir_expand::hygiene::Hygiene; | 9 | use hir_expand::hygiene::Hygiene; |
10 | use ra_syntax::ast; | 10 | use ra_syntax::ast; |
11 | use std::sync::Arc; | ||
12 | 11 | ||
13 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 12 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
14 | pub enum AttrDef { | 13 | pub enum AttrDef { |
@@ -38,16 +37,19 @@ impl_froms!( | |||
38 | ); | 37 | ); |
39 | 38 | ||
40 | pub trait Attrs { | 39 | pub trait Attrs { |
41 | fn attrs(&self, db: &impl HirDatabase) -> Option<Arc<[Attr]>>; | 40 | fn attrs(&self, db: &impl HirDatabase) -> hir_def::attr::Attrs; |
42 | } | 41 | } |
43 | 42 | ||
44 | pub(crate) fn attributes_query( | 43 | pub(crate) fn attributes_query( |
45 | db: &(impl DefDatabase + AstDatabase), | 44 | db: &(impl DefDatabase + AstDatabase), |
46 | def: AttrDef, | 45 | def: AttrDef, |
47 | ) -> Option<Arc<[Attr]>> { | 46 | ) -> hir_def::attr::Attrs { |
48 | match def { | 47 | match def { |
49 | AttrDef::Module(it) => { | 48 | AttrDef::Module(it) => { |
50 | let src = it.declaration_source(db)?; | 49 | let src = match it.declaration_source(db) { |
50 | Some(it) => it, | ||
51 | None => return hir_def::attr::Attrs::default(), | ||
52 | }; | ||
51 | let hygiene = Hygiene::new(db, src.file_id); | 53 | let hygiene = Hygiene::new(db, src.file_id); |
52 | Attr::from_attrs_owner(&src.value, &hygiene) | 54 | Attr::from_attrs_owner(&src.value, &hygiene) |
53 | } | 55 | } |
@@ -57,7 +59,7 @@ pub(crate) fn attributes_query( | |||
57 | let hygiene = Hygiene::new(db, src.file_id); | 59 | let hygiene = Hygiene::new(db, src.file_id); |
58 | Attr::from_attrs_owner(&named, &hygiene) | 60 | Attr::from_attrs_owner(&named, &hygiene) |
59 | } | 61 | } |
60 | FieldSource::Pos(..) => None, | 62 | FieldSource::Pos(..) => hir_def::attr::Attrs::default(), |
61 | }, | 63 | }, |
62 | AttrDef::Adt(it) => match it { | 64 | AttrDef::Adt(it) => match it { |
63 | Adt::Struct(it) => attrs_from_ast(it, db), | 65 | Adt::Struct(it) => attrs_from_ast(it, db), |
@@ -74,7 +76,7 @@ pub(crate) fn attributes_query( | |||
74 | } | 76 | } |
75 | } | 77 | } |
76 | 78 | ||
77 | fn attrs_from_ast<T, D>(node: T, db: &D) -> Option<Arc<[Attr]>> | 79 | fn attrs_from_ast<T, D>(node: T, db: &D) -> hir_def::attr::Attrs |
78 | where | 80 | where |
79 | T: HasSource, | 81 | T: HasSource, |
80 | T::Ast: ast::AttrsOwner, | 82 | T::Ast: ast::AttrsOwner, |
@@ -86,7 +88,7 @@ where | |||
86 | } | 88 | } |
87 | 89 | ||
88 | impl<T: Into<AttrDef> + Copy> Attrs for T { | 90 | impl<T: Into<AttrDef> + Copy> Attrs for T { |
89 | fn attrs(&self, db: &impl HirDatabase) -> Option<Arc<[Attr]>> { | 91 | fn attrs(&self, db: &impl HirDatabase) -> hir_def::attr::Attrs { |
90 | db.attrs((*self).into()) | 92 | db.attrs((*self).into()) |
91 | } | 93 | } |
92 | } | 94 | } |
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs index ed0d68001..1f63be3b9 100644 --- a/crates/ra_hir/src/db.rs +++ b/crates/ra_hir/src/db.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use hir_def::attr::Attr; | 5 | use hir_def::attr::Attrs; |
6 | use ra_db::salsa; | 6 | use ra_db::salsa; |
7 | use ra_syntax::SmolStr; | 7 | use ra_syntax::SmolStr; |
8 | 8 | ||
@@ -61,7 +61,7 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 { | |||
61 | fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>; | 61 | fn documentation(&self, def: crate::DocDef) -> Option<crate::Documentation>; |
62 | 62 | ||
63 | #[salsa::invoke(crate::code_model::attrs::attributes_query)] | 63 | #[salsa::invoke(crate::code_model::attrs::attributes_query)] |
64 | fn attrs(&self, def: crate::AttrDef) -> Option<Arc<[Attr]>>; | 64 | fn attrs(&self, def: crate::AttrDef) -> Attrs; |
65 | } | 65 | } |
66 | 66 | ||
67 | #[salsa::query_group(HirDatabaseStorage)] | 67 | #[salsa::query_group(HirDatabaseStorage)] |
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index 0e961ca12..7a9d0fdf4 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! A higher level attributes based on TokenTree, with also some shortcuts. | 1 | //! A higher level attributes based on TokenTree, with also some shortcuts. |
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::{ops, sync::Arc}; |
4 | 4 | ||
5 | use hir_expand::hygiene::Hygiene; | 5 | use hir_expand::hygiene::Hygiene; |
6 | use mbe::ast_to_token_tree; | 6 | use mbe::ast_to_token_tree; |
@@ -13,6 +13,28 @@ use tt::Subtree; | |||
13 | 13 | ||
14 | use crate::path::Path; | 14 | use crate::path::Path; |
15 | 15 | ||
16 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | ||
17 | pub struct Attrs { | ||
18 | entries: Option<Arc<[Attr]>>, | ||
19 | } | ||
20 | |||
21 | impl ops::Deref for Attrs { | ||
22 | type Target = [Attr]; | ||
23 | |||
24 | fn deref(&self) -> &[Attr] { | ||
25 | match &self.entries { | ||
26 | Some(it) => &*it, | ||
27 | None => &[], | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | |||
32 | impl Attrs { | ||
33 | pub fn has_atom(&self, atom: &str) -> bool { | ||
34 | self.iter().any(|it| it.is_simple_atom(atom)) | ||
35 | } | ||
36 | } | ||
37 | |||
16 | #[derive(Debug, Clone, PartialEq, Eq)] | 38 | #[derive(Debug, Clone, PartialEq, Eq)] |
17 | pub struct Attr { | 39 | pub struct Attr { |
18 | pub(crate) path: Path, | 40 | pub(crate) path: Path, |
@@ -43,13 +65,15 @@ impl Attr { | |||
43 | Some(Attr { path, input }) | 65 | Some(Attr { path, input }) |
44 | } | 66 | } |
45 | 67 | ||
46 | pub fn from_attrs_owner(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Option<Arc<[Attr]>> { | 68 | pub fn from_attrs_owner(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs { |
47 | let mut attrs = owner.attrs().peekable(); | 69 | let mut attrs = owner.attrs().peekable(); |
48 | if attrs.peek().is_none() { | 70 | let entries = if attrs.peek().is_none() { |
49 | // Avoid heap allocation | 71 | // Avoid heap allocation |
50 | return None; | 72 | None |
51 | } | 73 | } else { |
52 | Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect()) | 74 | Some(attrs.flat_map(|ast| Attr::from_src(ast, hygiene)).collect()) |
75 | }; | ||
76 | Attrs { entries } | ||
53 | } | 77 | } |
54 | 78 | ||
55 | pub fn is_simple_atom(&self, name: &str) -> bool { | 79 | pub fn is_simple_atom(&self, name: &str) -> bool { |
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index aae3dcadf..7902293e8 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -12,7 +12,7 @@ use rustc_hash::FxHashMap; | |||
12 | use test_utils::tested_by; | 12 | use test_utils::tested_by; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | attr::Attr, | 15 | attr::Attrs, |
16 | db::DefDatabase2, | 16 | db::DefDatabase2, |
17 | nameres::{ | 17 | nameres::{ |
18 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, | 18 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, |
@@ -549,7 +549,7 @@ where | |||
549 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting | 549 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting |
550 | // any other items. | 550 | // any other items. |
551 | for item in items { | 551 | for item in items { |
552 | if self.is_cfg_enabled(item.attrs()) { | 552 | if self.is_cfg_enabled(&item.attrs) { |
553 | if let raw::RawItemKind::Import(import_id) = item.kind { | 553 | if let raw::RawItemKind::Import(import_id) = item.kind { |
554 | let import = self.raw_items[import_id].clone(); | 554 | let import = self.raw_items[import_id].clone(); |
555 | if import.is_extern_crate && import.is_macro_use { | 555 | if import.is_extern_crate && import.is_macro_use { |
@@ -560,10 +560,10 @@ where | |||
560 | } | 560 | } |
561 | 561 | ||
562 | for item in items { | 562 | for item in items { |
563 | if self.is_cfg_enabled(item.attrs()) { | 563 | if self.is_cfg_enabled(&item.attrs) { |
564 | match item.kind { | 564 | match item.kind { |
565 | raw::RawItemKind::Module(m) => { | 565 | raw::RawItemKind::Module(m) => { |
566 | self.collect_module(&self.raw_items[m], item.attrs()) | 566 | self.collect_module(&self.raw_items[m], &item.attrs) |
567 | } | 567 | } |
568 | raw::RawItemKind::Import(import_id) => self | 568 | raw::RawItemKind::Import(import_id) => self |
569 | .def_collector | 569 | .def_collector |
@@ -585,9 +585,9 @@ where | |||
585 | } | 585 | } |
586 | } | 586 | } |
587 | 587 | ||
588 | fn collect_module(&mut self, module: &raw::ModuleData, attrs: &[Attr]) { | 588 | fn collect_module(&mut self, module: &raw::ModuleData, attrs: &Attrs) { |
589 | let path_attr = self.path_attr(attrs); | 589 | let path_attr = self.path_attr(attrs); |
590 | let is_macro_use = self.is_macro_use(attrs); | 590 | let is_macro_use = attrs.has_atom("macro_use"); |
591 | match module { | 591 | match module { |
592 | // inline module, just recurse | 592 | // inline module, just recurse |
593 | raw::ModuleData::Definition { name, items, ast_id } => { | 593 | raw::ModuleData::Definition { name, items, ast_id } => { |
@@ -779,17 +779,13 @@ where | |||
779 | } | 779 | } |
780 | } | 780 | } |
781 | 781 | ||
782 | fn is_cfg_enabled(&self, attrs: &[Attr]) -> bool { | 782 | fn is_cfg_enabled(&self, attrs: &Attrs) -> bool { |
783 | attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) | 783 | attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) |
784 | } | 784 | } |
785 | 785 | ||
786 | fn path_attr<'a>(&self, attrs: &'a [Attr]) -> Option<&'a SmolStr> { | 786 | fn path_attr<'a>(&self, attrs: &'a Attrs) -> Option<&'a SmolStr> { |
787 | attrs.iter().find_map(|attr| attr.as_path()) | 787 | attrs.iter().find_map(|attr| attr.as_path()) |
788 | } | 788 | } |
789 | |||
790 | fn is_macro_use<'a>(&self, attrs: &'a [Attr]) -> bool { | ||
791 | attrs.iter().any(|attr| attr.is_simple_atom("macro_use")) | ||
792 | } | ||
793 | } | 789 | } |
794 | 790 | ||
795 | fn is_macro_rules(path: &Path) -> bool { | 791 | fn is_macro_rules(path: &Path) -> bool { |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 7c68fd638..55a9634f8 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -16,7 +16,12 @@ use ra_syntax::{ | |||
16 | }; | 16 | }; |
17 | use test_utils::tested_by; | 17 | use test_utils::tested_by; |
18 | 18 | ||
19 | use crate::{attr::Attr, db::DefDatabase2, path::Path, FileAstId, HirFileId, ModuleSource, Source}; | 19 | use crate::{ |
20 | attr::{Attr, Attrs}, | ||
21 | db::DefDatabase2, | ||
22 | path::Path, | ||
23 | FileAstId, HirFileId, ModuleSource, Source, | ||
24 | }; | ||
20 | 25 | ||
21 | /// `RawItems` is a set of top-level items in a file (except for impls). | 26 | /// `RawItems` is a set of top-level items in a file (except for impls). |
22 | /// | 27 | /// |
@@ -129,21 +134,12 @@ impl Index<Impl> for RawItems { | |||
129 | } | 134 | } |
130 | } | 135 | } |
131 | 136 | ||
132 | // Avoid heap allocation on items without attributes. | ||
133 | type Attrs = Option<Arc<[Attr]>>; | ||
134 | |||
135 | #[derive(Debug, PartialEq, Eq, Clone)] | 137 | #[derive(Debug, PartialEq, Eq, Clone)] |
136 | pub(super) struct RawItem { | 138 | pub(super) struct RawItem { |
137 | attrs: Attrs, | 139 | pub(super) attrs: Attrs, |
138 | pub(super) kind: RawItemKind, | 140 | pub(super) kind: RawItemKind, |
139 | } | 141 | } |
140 | 142 | ||
141 | impl RawItem { | ||
142 | pub(super) fn attrs(&self) -> &[Attr] { | ||
143 | self.attrs.as_ref().map_or(&[], |it| &*it) | ||
144 | } | ||
145 | } | ||
146 | |||
147 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 143 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
148 | pub(super) enum RawItemKind { | 144 | pub(super) enum RawItemKind { |
149 | Module(Module), | 145 | Module(Module), |
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index b20329459..cbaf169bf 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs | |||
@@ -286,10 +286,7 @@ impl Completions { | |||
286 | } | 286 | } |
287 | 287 | ||
288 | fn is_deprecated(node: impl Attrs, db: &impl HirDatabase) -> bool { | 288 | fn is_deprecated(node: impl Attrs, db: &impl HirDatabase) -> bool { |
289 | match node.attrs(db) { | 289 | node.attrs(db).has_atom("deprecated") |
290 | None => false, | ||
291 | Some(attrs) => attrs.iter().any(|x| x.is_simple_atom("deprecated")), | ||
292 | } | ||
293 | } | 290 | } |
294 | 291 | ||
295 | fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { | 292 | fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { |