diff options
Diffstat (limited to 'crates/hir_def/src/item_tree.rs')
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index ff62928df..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 | } |
@@ -147,6 +149,7 @@ impl ItemTree { | |||
147 | macro_defs, | 149 | macro_defs, |
148 | vis, | 150 | vis, |
149 | generics, | 151 | generics, |
152 | inner_items, | ||
150 | } = &mut **data; | 153 | } = &mut **data; |
151 | 154 | ||
152 | imports.shrink_to_fit(); | 155 | imports.shrink_to_fit(); |
@@ -169,6 +172,8 @@ impl ItemTree { | |||
169 | 172 | ||
170 | vis.arena.shrink_to_fit(); | 173 | vis.arena.shrink_to_fit(); |
171 | generics.arena.shrink_to_fit(); | 174 | generics.arena.shrink_to_fit(); |
175 | |||
176 | inner_items.shrink_to_fit(); | ||
172 | } | 177 | } |
173 | } | 178 | } |
174 | 179 | ||
@@ -191,16 +196,18 @@ impl ItemTree { | |||
191 | self.raw_attrs(of).clone().filter(db, krate) | 196 | self.raw_attrs(of).clone().filter(db, krate) |
192 | } | 197 | } |
193 | 198 | ||
194 | /// Returns the lowered inner items that `ast` corresponds to. | 199 | pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ { |
195 | /// | 200 | match &self.data { |
196 | /// 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(), |
197 | /// to multiple items in the `ItemTree`. | 202 | None => None.into_iter().flatten(), |
198 | pub fn inner_items(&self, ast: FileAstId<ast::Item>) -> &[ModItem] { | 203 | } |
199 | &self.inner_items[&ast] | ||
200 | } | 204 | } |
201 | 205 | ||
202 | pub fn all_inner_items(&self) -> impl Iterator<Item = ModItem> + '_ { | 206 | pub fn inner_items_of_block(&self, block: FileAstId<ast::BlockExpr>) -> &[ModItem] { |
203 | 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 | } | ||
204 | } | 211 | } |
205 | 212 | ||
206 | 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 { |
@@ -297,6 +304,8 @@ struct ItemTreeData { | |||
297 | 304 | ||
298 | vis: ItemVisibilities, | 305 | vis: ItemVisibilities, |
299 | generics: GenericParamsStorage, | 306 | generics: GenericParamsStorage, |
307 | |||
308 | inner_items: FxHashMap<FileAstId<ast::BlockExpr>, SmallVec<[ModItem; 1]>>, | ||
300 | } | 309 | } |
301 | 310 | ||
302 | #[derive(Debug, Eq, PartialEq, Hash)] | 311 | #[derive(Debug, Eq, PartialEq, Hash)] |