aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/item_tree.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/item_tree.rs')
-rw-r--r--crates/ra_hir_def/src/item_tree.rs73
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};
36use smallvec::SmallVec; 36use smallvec::SmallVec;
37 37
38/// The item tree of a source file. 38#[derive(Default, Debug, Eq, PartialEq)]
39#[derive(Debug, Eq, PartialEq)] 39struct ItemTreeData {
40pub 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)]
59enum 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)]
69pub 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
66impl ItemTree { 78impl 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 )+