diff options
Diffstat (limited to 'crates/ra_hir_def/src/item_tree.rs')
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index a75271703..d55b3f777 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs | |||
@@ -35,16 +35,8 @@ use crate::{ | |||
35 | }; | 35 | }; |
36 | use smallvec::SmallVec; | 36 | use smallvec::SmallVec; |
37 | 37 | ||
38 | /// The item tree of a source file. | 38 | #[derive(Default, Debug, Eq, PartialEq)] |
39 | #[derive(Debug, Eq, PartialEq)] | 39 | struct ItemTreeData { |
40 | pub struct ItemTree { | ||
41 | file_id: HirFileId, | ||
42 | top_level: Vec<ModItem>, | ||
43 | top_attrs: Attrs, | ||
44 | attrs: FxHashMap<ModItem, Attrs>, | ||
45 | empty_attrs: Attrs, | ||
46 | inner_items: FxHashMap<FileAstId<ast::ModuleItem>, SmallVec<[ModItem; 1]>>, | ||
47 | |||
48 | imports: Arena<Import>, | 40 | imports: Arena<Import>, |
49 | extern_crates: Arena<ExternCrate>, | 41 | extern_crates: Arena<ExternCrate>, |
50 | functions: Arena<Function>, | 42 | functions: Arena<Function>, |
@@ -63,6 +55,26 @@ pub struct ItemTree { | |||
63 | exprs: Arena<Expr>, | 55 | exprs: Arena<Expr>, |
64 | } | 56 | } |
65 | 57 | ||
58 | #[derive(Debug, Eq, PartialEq, Hash)] | ||
59 | enum AttrOwner { | ||
60 | /// Attributes on an item. | ||
61 | ModItem(ModItem), | ||
62 | /// Inner attributes of the source file. | ||
63 | TopLevel, | ||
64 | // FIXME: Store variant and field attrs, and stop reparsing them in `attrs_query`. | ||
65 | } | ||
66 | |||
67 | /// The item tree of a source file. | ||
68 | #[derive(Debug, Eq, PartialEq)] | ||
69 | pub struct ItemTree { | ||
70 | file_id: HirFileId, | ||
71 | top_level: SmallVec<[ModItem; 1]>, | ||
72 | attrs: FxHashMap<AttrOwner, Attrs>, | ||
73 | inner_items: FxHashMap<FileAstId<ast::ModuleItem>, SmallVec<[ModItem; 1]>>, | ||
74 | |||
75 | data: Option<Box<ItemTreeData>>, | ||
76 | } | ||
77 | |||
66 | impl ItemTree { | 78 | impl ItemTree { |
67 | pub fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> { | 79 | pub fn item_tree_query(db: &dyn DefDatabase, file_id: HirFileId) -> Arc<ItemTree> { |
68 | let _p = ra_prof::profile("item_tree_query").detail(|| format!("{:?}", file_id)); | 80 | let _p = ra_prof::profile("item_tree_query").detail(|| format!("{:?}", file_id)); |
@@ -95,7 +107,9 @@ impl ItemTree { | |||
95 | } | 107 | } |
96 | }; | 108 | }; |
97 | 109 | ||
98 | item_tree.top_attrs = top_attrs.unwrap_or_default(); | 110 | if let Some(attrs) = top_attrs { |
111 | item_tree.attrs.insert(AttrOwner::TopLevel, attrs); | ||
112 | } | ||
99 | Arc::new(item_tree) | 113 | Arc::new(item_tree) |
100 | } | 114 | } |
101 | 115 | ||
@@ -103,26 +117,9 @@ impl ItemTree { | |||
103 | Self { | 117 | Self { |
104 | file_id, | 118 | file_id, |
105 | top_level: Default::default(), | 119 | top_level: Default::default(), |
106 | top_attrs: Default::default(), | ||
107 | attrs: Default::default(), | 120 | attrs: Default::default(), |
108 | empty_attrs: Default::default(), | ||
109 | inner_items: Default::default(), | 121 | inner_items: Default::default(), |
110 | imports: Default::default(), | 122 | data: Default::default(), |
111 | extern_crates: Default::default(), | ||
112 | functions: Default::default(), | ||
113 | structs: Default::default(), | ||
114 | fields: Default::default(), | ||
115 | unions: Default::default(), | ||
116 | enums: Default::default(), | ||
117 | variants: Default::default(), | ||
118 | consts: Default::default(), | ||
119 | statics: Default::default(), | ||
120 | traits: Default::default(), | ||
121 | impls: Default::default(), | ||
122 | type_aliases: Default::default(), | ||
123 | mods: Default::default(), | ||
124 | macro_calls: Default::default(), | ||
125 | exprs: Default::default(), | ||
126 | } | 123 | } |
127 | } | 124 | } |
128 | 125 | ||
@@ -134,11 +131,11 @@ impl ItemTree { | |||
134 | 131 | ||
135 | /// Returns the inner attributes of the source file. | 132 | /// Returns the inner attributes of the source file. |
136 | pub fn top_level_attrs(&self) -> &Attrs { | 133 | pub fn top_level_attrs(&self) -> &Attrs { |
137 | &self.top_attrs | 134 | self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY) |
138 | } | 135 | } |
139 | 136 | ||
140 | pub fn attrs(&self, of: ModItem) -> &Attrs { | 137 | pub fn attrs(&self, of: ModItem) -> &Attrs { |
141 | self.attrs.get(&of).unwrap_or(&self.empty_attrs) | 138 | self.attrs.get(&AttrOwner::ModItem(of)).unwrap_or(&Attrs::EMPTY) |
142 | } | 139 | } |
143 | 140 | ||
144 | /// Returns the lowered inner items that `ast` corresponds to. | 141 | /// Returns the lowered inner items that `ast` corresponds to. |
@@ -169,6 +166,14 @@ impl ItemTree { | |||
169 | let ptr = map.get(id); | 166 | let ptr = map.get(id); |
170 | ptr.to_node(&root) | 167 | ptr.to_node(&root) |
171 | } | 168 | } |
169 | |||
170 | fn data(&self) -> &ItemTreeData { | ||
171 | self.data.as_ref().expect("attempted to access data of empty ItemTree") | ||
172 | } | ||
173 | |||
174 | fn data_mut(&mut self) -> &mut ItemTreeData { | ||
175 | self.data.get_or_insert_with(Box::default) | ||
176 | } | ||
172 | } | 177 | } |
173 | 178 | ||
174 | /// Trait implemented by all nodes in the item tree. | 179 | /// Trait implemented by all nodes in the item tree. |
@@ -246,7 +251,7 @@ macro_rules! mod_items { | |||
246 | } | 251 | } |
247 | 252 | ||
248 | fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self { | 253 | fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self { |
249 | &tree.$fld[index] | 254 | &tree.data().$fld[index] |
250 | } | 255 | } |
251 | 256 | ||
252 | fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>> { | 257 | fn id_from_mod_item(mod_item: ModItem) -> Option<FileItemTreeId<Self>> { |
@@ -266,7 +271,7 @@ macro_rules! mod_items { | |||
266 | type Output = $typ; | 271 | type Output = $typ; |
267 | 272 | ||
268 | fn index(&self, index: Idx<$typ>) -> &Self::Output { | 273 | fn index(&self, index: Idx<$typ>) -> &Self::Output { |
269 | &self.$fld[index] | 274 | &self.data().$fld[index] |
270 | } | 275 | } |
271 | } | 276 | } |
272 | )+ | 277 | )+ |
@@ -296,7 +301,7 @@ macro_rules! impl_index { | |||
296 | type Output = $t; | 301 | type Output = $t; |
297 | 302 | ||
298 | fn index(&self, index: Idx<$t>) -> &Self::Output { | 303 | fn index(&self, index: Idx<$t>) -> &Self::Output { |
299 | &self.$fld[index] | 304 | &self.data().$fld[index] |
300 | } | 305 | } |
301 | } | 306 | } |
302 | )+ | 307 | )+ |