@@ -53,7 +53,7 @@ use hir_expand::{
5353use intern:: Interned ;
5454use la_arena:: Idx ;
5555use rustc_hash:: FxHashMap ;
56- use span:: { AstIdNode , Edition , ErasedFileAstId , FileAstId , SyntaxContext } ;
56+ use span:: { AstIdNode , Edition , FileAstId , SyntaxContext } ;
5757use stdx:: never;
5858use syntax:: { SyntaxKind , ast, match_ast} ;
5959use triomphe:: Arc ;
@@ -89,9 +89,8 @@ impl fmt::Debug for RawVisibilityId {
8989#[ derive( Debug , Default , Eq , PartialEq ) ]
9090pub struct ItemTree {
9191 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 > ,
9594 vis : ItemVisibilities ,
9695 // FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead?
9796 data : FxHashMap < FileAstId < ast:: Item > , ModItem > ,
@@ -104,12 +103,13 @@ impl ItemTree {
104103
105104 let ctx = lower:: Ctx :: new ( db, file_id) ;
106105 let syntax = db. parse_or_expand ( file_id) ;
107- let mut top_attrs = None ;
108106 let mut item_tree = match_ast ! {
109107 match syntax {
110108 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
113113 } ,
114114 ast:: MacroItems ( items) => {
115115 ctx. lower_module_items( & items)
@@ -128,17 +128,18 @@ impl ItemTree {
128128 }
129129 } ;
130130
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 ( )
135135 {
136136 EMPTY
137137 . get_or_init ( || {
138138 Arc :: new ( ItemTree {
139139 top_level : Box :: new ( [ ] ) ,
140140 attrs : FxHashMap :: default ( ) ,
141141 data : FxHashMap :: default ( ) ,
142+ top_attrs : RawAttrs :: EMPTY ,
142143 vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
143144 } )
144145 } )
@@ -158,14 +159,18 @@ impl ItemTree {
158159
159160 let ctx = lower:: Ctx :: new ( db, loc. ast_id . file_id ) ;
160161 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 ( )
162166 {
163167 EMPTY
164168 . get_or_init ( || {
165169 Arc :: new ( ItemTree {
166170 top_level : Box :: new ( [ ] ) ,
167171 attrs : FxHashMap :: default ( ) ,
168172 data : FxHashMap :: default ( ) ,
173+ top_attrs : RawAttrs :: EMPTY ,
169174 vis : ItemVisibilities { arena : Box :: new ( [ ] ) } ,
170175 } )
171176 } )
@@ -182,20 +187,26 @@ impl ItemTree {
182187 & self . top_level
183188 }
184189
190+ /// Returns the inner attributes of the source file.
191+ pub fn top_level_raw_attrs ( & self ) -> & RawAttrs {
192+ & self . top_attrs
193+ }
194+
185195 /// Returns the inner attributes of the source file.
186196 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 ( ) )
192198 }
193199
194- pub ( crate ) fn raw_attrs ( & self , of : AttrOwner ) -> & RawAttrs {
200+ pub ( crate ) fn raw_attrs ( & self , of : FileAstId < ast :: Item > ) -> & RawAttrs {
195201 self . attrs . get ( & of) . unwrap_or ( & RawAttrs :: EMPTY )
196202 }
197203
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 {
199210 Attrs :: expand_cfg_attr ( db, krate, self . raw_attrs ( of) . clone ( ) )
200211 }
201212
@@ -226,7 +237,7 @@ impl ItemTree {
226237 }
227238
228239 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 ;
230241 attrs. shrink_to_fit ( ) ;
231242 data. shrink_to_fit ( ) ;
232243 }
@@ -266,21 +277,6 @@ pub struct ItemTreeDataStats {
266277 pub macro_rules : usize ,
267278}
268279
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-
284280/// Trait implemented by all nodes in the item tree.
285281pub trait ItemTreeNode : Clone {
286282 type Source : AstIdNode ;
0 commit comments