diff options
Diffstat (limited to 'crates/hir_def/src/item_tree.rs')
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 41 |
1 files changed, 21 insertions, 20 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 9a433b61c..b8d7608e7 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -21,6 +21,7 @@ use hir_expand::{ | |||
21 | HirFileId, InFile, | 21 | HirFileId, InFile, |
22 | }; | 22 | }; |
23 | use la_arena::{Arena, Idx, RawIdx}; | 23 | use la_arena::{Arena, Idx, RawIdx}; |
24 | use profile::Count; | ||
24 | use rustc_hash::FxHashMap; | 25 | use rustc_hash::FxHashMap; |
25 | use smallvec::SmallVec; | 26 | use smallvec::SmallVec; |
26 | use syntax::{ast, match_ast}; | 27 | use syntax::{ast, match_ast}; |
@@ -67,15 +68,16 @@ impl GenericParamsId { | |||
67 | /// The item tree of a source file. | 68 | /// The item tree of a source file. |
68 | #[derive(Debug, Eq, PartialEq)] | 69 | #[derive(Debug, Eq, PartialEq)] |
69 | pub struct ItemTree { | 70 | pub struct ItemTree { |
71 | _c: Count<Self>, | ||
72 | |||
70 | top_level: SmallVec<[ModItem; 1]>, | 73 | top_level: SmallVec<[ModItem; 1]>, |
71 | attrs: FxHashMap<AttrOwner, RawAttrs>, | 74 | attrs: FxHashMap<AttrOwner, RawAttrs>, |
72 | inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>, | ||
73 | 75 | ||
74 | data: Option<Box<ItemTreeData>>, | 76 | data: Option<Box<ItemTreeData>>, |
75 | } | 77 | } |
76 | 78 | ||
77 | impl ItemTree { | 79 | impl ItemTree { |
78 | pub fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> { | 80 | pub(crate) fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> { |
79 | let _p = profile::span("item_tree_query").detail(|| format!("{:?}", file_id)); | 81 | let _p = profile::span("item_tree_query").detail(|| format!("{:?}", file_id)); |
80 | let syntax = if let Some(node) = db.parse_or_expand(file_id) { | 82 | let syntax = if let Some(node) = db.parse_or_expand(file_id) { |
81 | node | 83 | node |
@@ -118,9 +120,9 @@ impl ItemTree { | |||
118 | 120 | ||
119 | fn empty() -> Self { | 121 | fn empty() -> Self { |
120 | Self { | 122 | Self { |
123 | _c: Count::new(), | ||
121 | top_level: Default::default(), | 124 | top_level: Default::default(), |
122 | attrs: Default::default(), | 125 | attrs: Default::default(), |
123 | inner_items: Default::default(), | ||
124 | data: Default::default(), | 126 | data: Default::default(), |
125 | } | 127 | } |
126 | } | 128 | } |
@@ -145,9 +147,9 @@ impl ItemTree { | |||
145 | macro_calls, | 147 | macro_calls, |
146 | macro_rules, | 148 | macro_rules, |
147 | macro_defs, | 149 | macro_defs, |
148 | exprs, | ||
149 | vis, | 150 | vis, |
150 | generics, | 151 | generics, |
152 | inner_items, | ||
151 | } = &mut **data; | 153 | } = &mut **data; |
152 | 154 | ||
153 | imports.shrink_to_fit(); | 155 | imports.shrink_to_fit(); |
@@ -167,10 +169,11 @@ impl ItemTree { | |||
167 | macro_calls.shrink_to_fit(); | 169 | macro_calls.shrink_to_fit(); |
168 | macro_rules.shrink_to_fit(); | 170 | macro_rules.shrink_to_fit(); |
169 | macro_defs.shrink_to_fit(); | 171 | macro_defs.shrink_to_fit(); |
170 | exprs.shrink_to_fit(); | ||
171 | 172 | ||
172 | vis.arena.shrink_to_fit(); | 173 | vis.arena.shrink_to_fit(); |
173 | generics.arena.shrink_to_fit(); | 174 | generics.arena.shrink_to_fit(); |
175 | |||
176 | inner_items.shrink_to_fit(); | ||
174 | } | 177 | } |
175 | } | 178 | } |
176 | 179 | ||
@@ -193,16 +196,18 @@ impl ItemTree { | |||
193 | self.raw_attrs(of).clone().filter(db, krate) | 196 | self.raw_attrs(of).clone().filter(db, krate) |
194 | } | 197 | } |
195 | 198 | ||
196 | /// Returns the lowered inner items that `ast` corresponds to. | 199 | pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ { |
197 | /// | 200 | match &self.data { |
198 | /// Most AST items are lowered to a single `ModItem`, but some (eg. `use` items) may be lowered | 201 | Some(data) => Some(data.inner_items.values().flatten().copied()).into_iter().flatten(), |
199 | /// to multiple items in the `ItemTree`. | 202 | None => None.into_iter().flatten(), |
200 | pub fn inner_items(&self, ast: FileAstId<ast::Item>) -> &[ModItem] { | 203 | } |
201 | &self.inner_items[&ast] | ||
202 | } | 204 | } |
203 | 205 | ||
204 | pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ { | 206 | pub fn inner_items_of_block(&self, block: FileAstId<ast::BlockExpr>) -> &[ModItem] { |
205 | self.inner_items.values().flatten().copied() | 207 | match &self.data { |
208 | Some(data) => data.inner_items.get(&block).map(|it| &**it).unwrap_or(&[]), | ||
209 | None => &[], | ||
210 | } | ||
206 | } | 211 | } |
207 | 212 | ||
208 | pub fn source<S: ItemTreeNode>(&self, db: &dyn DefDatabase, of: ItemTreeId<S>) -> S::Source { | 213 | pub fn source<S: ItemTreeNode>(&self, db: &dyn DefDatabase, of: ItemTreeId<S>) -> S::Source { |
@@ -296,10 +301,11 @@ struct ItemTreeData { | |||
296 | macro_calls: Arena<MacroCall>, | 301 | macro_calls: Arena<MacroCall>, |
297 | macro_rules: Arena<MacroRules>, | 302 | macro_rules: Arena<MacroRules>, |
298 | macro_defs: Arena<MacroDef>, | 303 | macro_defs: Arena<MacroDef>, |
299 | exprs: Arena<Expr>, | ||
300 | 304 | ||
301 | vis: ItemVisibilities, | 305 | vis: ItemVisibilities, |
302 | generics: GenericParamsStorage, | 306 | generics: GenericParamsStorage, |
307 | |||
308 | inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>, | ||
303 | } | 309 | } |
304 | 310 | ||
305 | #[derive(Debug, Eq, PartialEq, Hash)] | 311 | #[derive(Debug, Eq, PartialEq, Hash)] |
@@ -461,7 +467,7 @@ macro_rules! impl_index { | |||
461 | }; | 467 | }; |
462 | } | 468 | } |
463 | 469 | ||
464 | impl_index!(fields: Field, variants: Variant, exprs: Expr); | 470 | impl_index!(fields: Field, variants: Variant); |
465 | 471 | ||
466 | impl Index<RawVisibilityId> for ItemTree { | 472 | impl Index<RawVisibilityId> for ItemTree { |
467 | type Output = RawVisibility; | 473 | type Output = RawVisibility; |
@@ -664,11 +670,6 @@ pub struct MacroDef { | |||
664 | pub ast_id: FileAstId<ast::MacroDef>, | 670 | pub ast_id: FileAstId<ast::MacroDef>, |
665 | } | 671 | } |
666 | 672 | ||
667 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array | ||
668 | // lengths, but we don't do much with them yet. | ||
669 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
670 | pub struct Expr; | ||
671 | |||
672 | macro_rules! impl_froms { | 673 | macro_rules! impl_froms { |
673 | ($e:ident { $($v:ident ($t:ty)),* $(,)? }) => { | 674 | ($e:ident { $($v:ident ($t:ty)),* $(,)? }) => { |
674 | $( | 675 | $( |