@@ -85,6 +85,74 @@ impl fmt::Debug for RawVisibilityId {
85
85
}
86
86
}
87
87
88
+ #[ salsa_macros:: tracked( returns( ref) ) ]
89
+ pub ( crate ) fn file_item_tree_query ( db : & dyn DefDatabase , file_id : HirFileId ) -> ItemTree {
90
+ let _p = tracing:: info_span!( "file_item_tree_query" , ?file_id) . entered ( ) ;
91
+
92
+ let ctx = lower:: Ctx :: new ( db, file_id) ;
93
+ let syntax = db. parse_or_expand ( file_id) ;
94
+ let mut item_tree = match_ast ! {
95
+ match syntax {
96
+ ast:: SourceFile ( file) => {
97
+ let top_attrs = RawAttrs :: new( db, & file, ctx. span_map( ) ) ;
98
+ let mut item_tree = ctx. lower_module_items( & file) ;
99
+ item_tree. top_attrs = top_attrs;
100
+ item_tree
101
+ } ,
102
+ ast:: MacroItems ( items) => {
103
+ ctx. lower_module_items( & items)
104
+ } ,
105
+ ast:: MacroStmts ( stmts) => {
106
+ // The produced statements can include items, which should be added as top-level
107
+ // items.
108
+ ctx. lower_macro_stmts( stmts)
109
+ } ,
110
+ _ => {
111
+ if never!( syntax. kind( ) == SyntaxKind :: ERROR , "{:?} from {:?} {}" , file_id, syntax, syntax) {
112
+ return Default :: default ( ) ;
113
+ }
114
+ panic!( "cannot create item tree for file {file_id:?} from {syntax:?} {syntax}" ) ;
115
+ } ,
116
+ }
117
+ } ;
118
+
119
+ item_tree. shrink_to_fit ( ) ;
120
+ item_tree
121
+ }
122
+
123
+ #[ salsa_macros:: tracked( returns( ref) ) ]
124
+ pub ( crate ) fn block_item_tree_query ( db : & dyn DefDatabase , block : BlockId ) -> Arc < ItemTree > {
125
+ let _p = tracing:: info_span!( "block_item_tree_query" , ?block) . entered ( ) ;
126
+ // Blocks have a tendency to be empty due to macro calls that do not expand to items,
127
+ // so deduplicate this case via `Arc` to reduce the size of the query storage here.
128
+ static EMPTY : OnceLock < Arc < ItemTree > > = OnceLock :: new ( ) ;
129
+
130
+ let loc = block. lookup ( db) ;
131
+ let block = loc. ast_id . to_node ( db) ;
132
+
133
+ let ctx = lower:: Ctx :: new ( db, loc. ast_id . file_id ) ;
134
+ let mut item_tree = ctx. lower_block ( & block) ;
135
+ if item_tree. data . is_empty ( )
136
+ && item_tree. top_level . is_empty ( )
137
+ && item_tree. attrs . is_empty ( )
138
+ && item_tree. top_attrs . is_empty ( )
139
+ {
140
+ EMPTY
141
+ . get_or_init ( || {
142
+ Arc :: new ( ItemTree {
143
+ top_level : Box :: new ( [ ] ) ,
144
+ attrs : FxHashMap :: default ( ) ,
145
+ data : FxHashMap :: default ( ) ,
146
+ top_attrs : RawAttrs :: EMPTY ,
147
+ vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
148
+ } )
149
+ } )
150
+ . clone ( )
151
+ } else {
152
+ item_tree. shrink_to_fit ( ) ;
153
+ Arc :: new ( item_tree)
154
+ }
155
+ }
88
156
/// The item tree of a source file.
89
157
#[ derive( Debug , Default , Eq , PartialEq ) ]
90
158
pub struct ItemTree {
@@ -97,90 +165,6 @@ pub struct ItemTree {
97
165
}
98
166
99
167
impl ItemTree {
100
- pub ( crate ) fn file_item_tree_query ( db : & dyn DefDatabase , file_id : HirFileId ) -> Arc < ItemTree > {
101
- let _p = tracing:: info_span!( "file_item_tree_query" , ?file_id) . entered ( ) ;
102
- static EMPTY : OnceLock < Arc < ItemTree > > = OnceLock :: new ( ) ;
103
-
104
- let ctx = lower:: Ctx :: new ( db, file_id) ;
105
- let syntax = db. parse_or_expand ( file_id) ;
106
- let mut item_tree = match_ast ! {
107
- match syntax {
108
- ast:: SourceFile ( file) => {
109
- let top_attrs = RawAttrs :: new( db, & file, ctx. span_map( ) ) ;
110
- let mut item_tree = ctx. lower_module_items( & file) ;
111
- item_tree. top_attrs = top_attrs;
112
- item_tree
113
- } ,
114
- ast:: MacroItems ( items) => {
115
- ctx. lower_module_items( & items)
116
- } ,
117
- ast:: MacroStmts ( stmts) => {
118
- // The produced statements can include items, which should be added as top-level
119
- // items.
120
- ctx. lower_macro_stmts( stmts)
121
- } ,
122
- _ => {
123
- if never!( syntax. kind( ) == SyntaxKind :: ERROR , "{:?} from {:?} {}" , file_id, syntax, syntax) {
124
- return Default :: default ( ) ;
125
- }
126
- panic!( "cannot create item tree for file {file_id:?} from {syntax:?} {syntax}" ) ;
127
- } ,
128
- }
129
- } ;
130
-
131
- if item_tree. data . is_empty ( )
132
- && item_tree. top_level . is_empty ( )
133
- && item_tree. attrs . is_empty ( )
134
- && item_tree. top_attrs . is_empty ( )
135
- {
136
- EMPTY
137
- . get_or_init ( || {
138
- Arc :: new ( ItemTree {
139
- top_level : Box :: new ( [ ] ) ,
140
- attrs : FxHashMap :: default ( ) ,
141
- data : FxHashMap :: default ( ) ,
142
- top_attrs : RawAttrs :: EMPTY ,
143
- vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
144
- } )
145
- } )
146
- . clone ( )
147
- } else {
148
- item_tree. shrink_to_fit ( ) ;
149
- Arc :: new ( item_tree)
150
- }
151
- }
152
-
153
- pub ( crate ) fn block_item_tree_query ( db : & dyn DefDatabase , block : BlockId ) -> Arc < ItemTree > {
154
- let _p = tracing:: info_span!( "block_item_tree_query" , ?block) . entered ( ) ;
155
- static EMPTY : OnceLock < Arc < ItemTree > > = OnceLock :: new ( ) ;
156
-
157
- let loc = block. lookup ( db) ;
158
- let block = loc. ast_id . to_node ( db) ;
159
-
160
- let ctx = lower:: Ctx :: new ( db, loc. ast_id . file_id ) ;
161
- let mut item_tree = ctx. lower_block ( & block) ;
162
- if item_tree. data . is_empty ( )
163
- && item_tree. top_level . is_empty ( )
164
- && item_tree. attrs . is_empty ( )
165
- && item_tree. top_attrs . is_empty ( )
166
- {
167
- EMPTY
168
- . get_or_init ( || {
169
- Arc :: new ( ItemTree {
170
- top_level : Box :: new ( [ ] ) ,
171
- attrs : FxHashMap :: default ( ) ,
172
- data : FxHashMap :: default ( ) ,
173
- top_attrs : RawAttrs :: EMPTY ,
174
- vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
175
- } )
176
- } )
177
- . clone ( )
178
- } else {
179
- item_tree. shrink_to_fit ( ) ;
180
- Arc :: new ( item_tree)
181
- }
182
- }
183
-
184
168
/// Returns an iterator over all items located at the top level of the `HirFileId` this
185
169
/// `ItemTree` was created from.
186
170
pub ( crate ) fn top_level_items ( & self ) -> & [ ModItemId ] {
@@ -297,10 +281,10 @@ impl TreeId {
297
281
Self { file, block }
298
282
}
299
283
300
- pub ( crate ) fn item_tree ( & self , db : & dyn DefDatabase ) -> Arc < ItemTree > {
284
+ pub ( crate ) fn item_tree < ' db > ( & self , db : & ' db dyn DefDatabase ) -> & ' db ItemTree {
301
285
match self . block {
302
- Some ( block) => db . block_item_tree ( block) ,
303
- None => db . file_item_tree ( self . file ) ,
286
+ Some ( block) => block_item_tree_query ( db , block) ,
287
+ None => file_item_tree_query ( db , self . file ) ,
304
288
}
305
289
}
306
290
0 commit comments