Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/item_tree.rs')
| -rw-r--r-- | crates/hir-def/src/item_tree.rs | 66 |
1 files changed, 31 insertions, 35 deletions
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 9f8d7b9e31..79f4b174e1 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -53,7 +53,7 @@ use hir_expand::{ use intern::Interned; use la_arena::Idx; use rustc_hash::FxHashMap; -use span::{AstIdNode, Edition, ErasedFileAstId, FileAstId, SyntaxContext}; +use span::{AstIdNode, Edition, FileAstId, SyntaxContext}; use stdx::never; use syntax::{SyntaxKind, ast, match_ast}; use triomphe::Arc; @@ -89,9 +89,8 @@ impl fmt::Debug for RawVisibilityId { #[derive(Debug, Default, Eq, PartialEq)] pub struct ItemTree { top_level: Box<[ModItemId]>, - // Consider splitting this into top level RawAttrs and the map? - attrs: FxHashMap<AttrOwner, RawAttrs>, - + top_attrs: RawAttrs, + attrs: FxHashMap<FileAstId<ast::Item>, RawAttrs>, vis: ItemVisibilities, // FIXME: They values store the key, turn this into a FxHashSet<ModItem> instead? data: FxHashMap<FileAstId<ast::Item>, ModItem>, @@ -104,12 +103,13 @@ impl ItemTree { let ctx = lower::Ctx::new(db, file_id); let syntax = db.parse_or_expand(file_id); - let mut top_attrs = None; let mut item_tree = match_ast! { match syntax { ast::SourceFile(file) => { - top_attrs = Some(RawAttrs::new(db, &file, ctx.span_map())); - ctx.lower_module_items(&file) + let top_attrs = RawAttrs::new(db, &file, ctx.span_map()); + let mut item_tree = ctx.lower_module_items(&file); + item_tree.top_attrs = top_attrs; + item_tree }, ast::MacroItems(items) => { ctx.lower_module_items(&items) @@ -128,10 +128,10 @@ impl ItemTree { } }; - if let Some(attrs) = top_attrs { - item_tree.attrs.insert(AttrOwner::TopLevel, attrs); - } - if item_tree.data.is_empty() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty() + if item_tree.data.is_empty() + && item_tree.top_level.is_empty() + && item_tree.attrs.is_empty() + && item_tree.top_attrs.is_empty() { EMPTY .get_or_init(|| { @@ -139,6 +139,7 @@ impl ItemTree { top_level: Box::new([]), attrs: FxHashMap::default(), data: FxHashMap::default(), + top_attrs: RawAttrs::EMPTY, vis: ItemVisibilities { arena: Box::new([]) }, }) }) @@ -158,7 +159,10 @@ impl ItemTree { let ctx = lower::Ctx::new(db, loc.ast_id.file_id); let mut item_tree = ctx.lower_block(&block); - if item_tree.data.is_empty() && item_tree.top_level.is_empty() && item_tree.attrs.is_empty() + if item_tree.data.is_empty() + && item_tree.top_level.is_empty() + && item_tree.attrs.is_empty() + && item_tree.top_attrs.is_empty() { EMPTY .get_or_init(|| { @@ -166,6 +170,7 @@ impl ItemTree { top_level: Box::new([]), attrs: FxHashMap::default(), data: FxHashMap::default(), + top_attrs: RawAttrs::EMPTY, vis: ItemVisibilities { arena: Box::new([]) }, }) }) @@ -183,19 +188,25 @@ impl ItemTree { } /// Returns the inner attributes of the source file. + pub fn top_level_raw_attrs(&self) -> &RawAttrs { + &self.top_attrs + } + + /// Returns the inner attributes of the source file. pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: Crate) -> Attrs { - Attrs::expand_cfg_attr( - db, - krate, - self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone(), - ) + Attrs::expand_cfg_attr(db, krate, self.top_attrs.clone()) } - pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs { + pub(crate) fn raw_attrs(&self, of: FileAstId<ast::Item>) -> &RawAttrs { self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY) } - pub(crate) fn attrs(&self, db: &dyn DefDatabase, krate: Crate, of: AttrOwner) -> Attrs { + pub(crate) fn attrs( + &self, + db: &dyn DefDatabase, + krate: Crate, + of: FileAstId<ast::Item>, + ) -> Attrs { Attrs::expand_cfg_attr(db, krate, self.raw_attrs(of).clone()) } @@ -226,7 +237,7 @@ impl ItemTree { } fn shrink_to_fit(&mut self) { - let ItemTree { top_level: _, attrs, data, vis: _ } = self; + let ItemTree { top_level: _, attrs, data, vis: _, top_attrs: _ } = self; attrs.shrink_to_fit(); data.shrink_to_fit(); } @@ -266,21 +277,6 @@ pub struct ItemTreeDataStats { pub macro_rules: usize, } -#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] -pub enum AttrOwner { - /// Attributes on an item. - Item(ErasedFileAstId), - /// Inner attributes of the source file. - TopLevel, -} - -impl From<ModItemId> for AttrOwner { - #[inline] - fn from(value: ModItemId) -> Self { - AttrOwner::Item(value.ast_id().erase()) - } -} - /// Trait implemented by all nodes in the item tree. pub trait ItemTreeNode: Clone { type Source: AstIdNode; |