@@ -53,7 +53,7 @@ use hir_expand::{
53
53
use intern:: Interned ;
54
54
use la_arena:: Idx ;
55
55
use rustc_hash:: FxHashMap ;
56
- use span:: { AstIdNode , Edition , ErasedFileAstId , FileAstId , SyntaxContext } ;
56
+ use span:: { AstIdNode , Edition , FileAstId , SyntaxContext } ;
57
57
use stdx:: never;
58
58
use syntax:: { SyntaxKind , ast, match_ast} ;
59
59
use triomphe:: Arc ;
@@ -89,9 +89,8 @@ impl fmt::Debug for RawVisibilityId {
89
89
#[ derive( Debug , Default , Eq , PartialEq ) ]
90
90
pub struct ItemTree {
91
91
top_level : Box < [ ModItemId ] > ,
92
- // Consider splitting this into top level RawAttrs and the map?
93
- attrs : FxHashMap < AttrOwner , RawAttrs > ,
94
-
92
+ top_attrs : RawAttrs ,
93
+ attrs : FxHashMap < FileAstId < ast:: Item > , RawAttrs > ,
95
94
vis : ItemVisibilities ,
96
95
// FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead?
97
96
data : FxHashMap < FileAstId < ast:: Item > , ModItem > ,
@@ -104,12 +103,13 @@ impl ItemTree {
104
103
105
104
let ctx = lower:: Ctx :: new ( db, file_id) ;
106
105
let syntax = db. parse_or_expand ( file_id) ;
107
- let mut top_attrs = None ;
108
106
let mut item_tree = match_ast ! {
109
107
match syntax {
110
108
ast:: SourceFile ( file) => {
111
- top_attrs = Some ( RawAttrs :: new( db, & file, ctx. span_map( ) ) ) ;
112
- ctx. lower_module_items( & 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
113
} ,
114
114
ast:: MacroItems ( items) => {
115
115
ctx. lower_module_items( & items)
@@ -128,17 +128,18 @@ impl ItemTree {
128
128
}
129
129
} ;
130
130
131
- if let Some ( attrs ) = top_attrs {
132
- item_tree. attrs . insert ( AttrOwner :: TopLevel , attrs ) ;
133
- }
134
- if item_tree . data . is_empty ( ) && item_tree . top_level . is_empty ( ) && item_tree. attrs . is_empty ( )
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
135
{
136
136
EMPTY
137
137
. get_or_init ( || {
138
138
Arc :: new ( ItemTree {
139
139
top_level : Box :: new ( [ ] ) ,
140
140
attrs : FxHashMap :: default ( ) ,
141
141
data : FxHashMap :: default ( ) ,
142
+ top_attrs : RawAttrs :: EMPTY ,
142
143
vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
143
144
} )
144
145
} )
@@ -158,14 +159,18 @@ impl ItemTree {
158
159
159
160
let ctx = lower:: Ctx :: new ( db, loc. ast_id . file_id ) ;
160
161
let mut item_tree = ctx. lower_block ( & block) ;
161
- if item_tree. data . is_empty ( ) && item_tree. top_level . is_empty ( ) && item_tree. attrs . is_empty ( )
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 ( )
162
166
{
163
167
EMPTY
164
168
. get_or_init ( || {
165
169
Arc :: new ( ItemTree {
166
170
top_level : Box :: new ( [ ] ) ,
167
171
attrs : FxHashMap :: default ( ) ,
168
172
data : FxHashMap :: default ( ) ,
173
+ top_attrs : RawAttrs :: EMPTY ,
169
174
vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
170
175
} )
171
176
} )
@@ -182,20 +187,26 @@ impl ItemTree {
182
187
& self . top_level
183
188
}
184
189
190
+ /// Returns the inner attributes of the source file.
191
+ pub fn top_level_raw_attrs ( & self ) -> & RawAttrs {
192
+ & self . top_attrs
193
+ }
194
+
185
195
/// Returns the inner attributes of the source file.
186
196
pub fn top_level_attrs ( & self , db : & dyn DefDatabase , krate : Crate ) -> Attrs {
187
- Attrs :: expand_cfg_attr (
188
- db,
189
- krate,
190
- self . attrs . get ( & AttrOwner :: TopLevel ) . unwrap_or ( & RawAttrs :: EMPTY ) . clone ( ) ,
191
- )
197
+ Attrs :: expand_cfg_attr ( db, krate, self . top_attrs . clone ( ) )
192
198
}
193
199
194
- pub ( crate ) fn raw_attrs ( & self , of : AttrOwner ) -> & RawAttrs {
200
+ pub ( crate ) fn raw_attrs ( & self , of : FileAstId < ast :: Item > ) -> & RawAttrs {
195
201
self . attrs . get ( & of) . unwrap_or ( & RawAttrs :: EMPTY )
196
202
}
197
203
198
- pub ( crate ) fn attrs ( & self , db : & dyn DefDatabase , krate : Crate , of : AttrOwner ) -> Attrs {
204
+ pub ( crate ) fn attrs (
205
+ & self ,
206
+ db : & dyn DefDatabase ,
207
+ krate : Crate ,
208
+ of : FileAstId < ast:: Item > ,
209
+ ) -> Attrs {
199
210
Attrs :: expand_cfg_attr ( db, krate, self . raw_attrs ( of) . clone ( ) )
200
211
}
201
212
@@ -226,7 +237,7 @@ impl ItemTree {
226
237
}
227
238
228
239
fn shrink_to_fit ( & mut self ) {
229
- let ItemTree { top_level : _, attrs, data, vis : _ } = self ;
240
+ let ItemTree { top_level : _, attrs, data, vis : _, top_attrs : _ } = self ;
230
241
attrs. shrink_to_fit ( ) ;
231
242
data. shrink_to_fit ( ) ;
232
243
}
@@ -266,21 +277,6 @@ pub struct ItemTreeDataStats {
266
277
pub macro_rules : usize ,
267
278
}
268
279
269
- #[ derive( Copy , Clone , Debug , Eq , PartialEq , Hash ) ]
270
- pub enum AttrOwner {
271
- /// Attributes on an item.
272
- Item ( ErasedFileAstId ) ,
273
- /// Inner attributes of the source file.
274
- TopLevel ,
275
- }
276
-
277
- impl From < ModItemId > for AttrOwner {
278
- #[ inline]
279
- fn from ( value : ModItemId ) -> Self {
280
- AttrOwner :: Item ( value. ast_id ( ) . erase ( ) )
281
- }
282
- }
283
-
284
280
/// Trait implemented by all nodes in the item tree.
285
281
pub trait ItemTreeNode : Clone {
286
282
type Source : AstIdNode ;
0 commit comments