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 | 177 |
1 files changed, 76 insertions, 101 deletions
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs index 7650dfe9f3..28eebb286e 100644 --- a/crates/hir-def/src/item_tree.rs +++ b/crates/hir-def/src/item_tree.rs @@ -46,8 +46,8 @@ use ast::{AstNode, StructKind}; use base_db::CrateId; use either::Either; use hir_expand::{attrs::RawAttrs, name::Name, ExpandTo, HirFileId, InFile}; -use intern::Interned; -use la_arena::{Arena, Idx, IdxRange, RawIdx}; +use intern::{Interned, Symbol}; +use la_arena::{Arena, Idx, RawIdx}; use once_cell::sync::OnceCell; use rustc_hash::FxHashMap; use smallvec::SmallVec; @@ -218,9 +218,7 @@ impl ItemTree { extern_crates, extern_blocks, functions, - params, structs, - fields, unions, enums, variants, @@ -241,9 +239,7 @@ impl ItemTree { extern_crates.shrink_to_fit(); extern_blocks.shrink_to_fit(); functions.shrink_to_fit(); - params.shrink_to_fit(); structs.shrink_to_fit(); - fields.shrink_to_fit(); unions.shrink_to_fit(); enums.shrink_to_fit(); variants.shrink_to_fit(); @@ -295,9 +291,7 @@ struct ItemTreeData { extern_crates: Arena<ExternCrate>, extern_blocks: Arena<ExternBlock>, functions: Arena<Function>, - params: Arena<Param>, structs: Arena<Struct>, - fields: Arena<Field>, unions: Arena<Union>, enums: Arena<Enum>, variants: Arena<Variant>, @@ -315,7 +309,7 @@ struct ItemTreeData { vis: ItemVisibilities, } -#[derive(Debug, Eq, PartialEq, Hash)] +#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] pub enum AttrOwner { /// Attributes on an item. ModItem(ModItem), @@ -323,12 +317,28 @@ pub enum AttrOwner { TopLevel, Variant(FileItemTreeId<Variant>), - Field(Idx<Field>), - Param(Idx<Param>), + Field(FieldParent, ItemTreeFieldId), + Param(FileItemTreeId<Function>, ItemTreeParamId), TypeOrConstParamData(GenericModItem, LocalTypeOrConstParamId), LifetimeParamData(GenericModItem, LocalLifetimeParamId), } +impl AttrOwner { + pub fn make_field_indexed(parent: FieldParent, idx: usize) -> Self { + AttrOwner::Field(parent, ItemTreeFieldId::from_raw(RawIdx::from_u32(idx as u32))) + } +} + +#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] +pub enum FieldParent { + Struct(FileItemTreeId<Struct>), + Union(FileItemTreeId<Union>), + Variant(FileItemTreeId<Variant>), +} + +pub type ItemTreeParamId = Idx<Param>; +pub type ItemTreeFieldId = Idx<Field>; + macro_rules! from_attrs { ( $( $var:ident($t:ty) ),+ $(,)? ) => { $( @@ -341,12 +351,7 @@ macro_rules! from_attrs { }; } -from_attrs!( - ModItem(ModItem), - Variant(FileItemTreeId<Variant>), - Field(Idx<Field>), - Param(Idx<Param>), -); +from_attrs!(ModItem(ModItem), Variant(FileItemTreeId<Variant>)); /// Trait implemented by all nodes in the item tree. pub trait ItemTreeNode: Clone { @@ -365,7 +370,7 @@ pub trait GenericsItemTreeNode: ItemTreeNode { pub struct FileItemTreeId<N>(Idx<N>); impl<N> FileItemTreeId<N> { - pub fn range_iter(range: Range<Self>) -> impl Iterator<Item = Self> { + pub fn range_iter(range: Range<Self>) -> impl Iterator<Item = Self> + Clone { (range.start.index().into_raw().into_u32()..range.end.index().into_raw().into_u32()) .map(RawIdx::from_u32) .map(Idx::from_raw) @@ -417,18 +422,18 @@ impl TreeId { Self { file, block } } - pub(crate) fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> { + pub fn item_tree(&self, db: &dyn DefDatabase) -> Arc<ItemTree> { match self.block { Some(block) => db.block_item_tree(block), None => db.file_item_tree(self.file), } } - pub(crate) fn file_id(self) -> HirFileId { + pub fn file_id(self) -> HirFileId { self.file } - pub(crate) fn is_block(self) -> bool { + pub fn is_block(self) -> bool { self.block.is_some() } } @@ -505,6 +510,27 @@ macro_rules! mod_items { )+ } + impl ModItem { + pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> { + match self { + $(ModItem::$typ(it) => tree[it.index()].ast_id().upcast()),+ + } + } + } + + impl GenericModItem { + pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::AnyHasGenericParams> { + match self { + $( + $( + #[cfg_attr(ignore_fragment, $generic_params)] + GenericModItem::$typ(it) => tree[it.index()].ast_id().upcast(), + )? + )+ + } + } + } + impl From<GenericModItem> for ModItem { fn from(id: GenericModItem) -> ModItem { match id { @@ -596,22 +622,6 @@ mod_items! { Macro2 in macro_defs -> ast::MacroDef, } -macro_rules! impl_index { - ( $($fld:ident: $t:ty),+ $(,)? ) => { - $( - impl Index<Idx<$t>> for ItemTree { - type Output = $t; - - fn index(&self, index: Idx<$t>) -> &Self::Output { - &self.data().$fld[index] - } - } - )+ - }; -} - -impl_index!(fields: Field, variants: Variant, params: Param); - impl Index<RawVisibilityId> for ItemTree { type Output = RawVisibility; fn index(&self, index: RawVisibilityId) -> &Self::Output { @@ -712,7 +722,7 @@ pub struct ExternCrate { #[derive(Debug, Clone, Eq, PartialEq)] pub struct ExternBlock { - pub abi: Option<Interned<str>>, + pub abi: Option<Symbol>, pub ast_id: FileAstId<ast::ExternBlock>, pub children: Box<[ModItem]>, } @@ -722,8 +732,8 @@ pub struct Function { pub name: Name, pub visibility: RawVisibilityId, pub explicit_generic_params: Interned<GenericParams>, - pub abi: Option<Interned<str>>, - pub params: IdxRange<Param>, + pub abi: Option<Symbol>, + pub params: Box<[Param]>, pub ret_type: Interned<TypeRef>, pub ast_id: FileAstId<ast::Fn>, pub(crate) flags: FnFlags, @@ -731,15 +741,7 @@ pub struct Function { #[derive(Debug, Clone, PartialEq, Eq)] pub struct Param { - /// This is [`None`] for varargs pub type_ref: Option<Interned<TypeRef>>, - pub ast_id: ParamAstId, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum ParamAstId { - Param(FileAstId<ast::Param>), - SelfParam(FileAstId<ast::SelfParam>), } bitflags::bitflags! { @@ -760,7 +762,8 @@ pub struct Struct { pub name: Name, pub visibility: RawVisibilityId, pub generic_params: Interned<GenericParams>, - pub fields: Fields, + pub fields: Box<[Field]>, + pub shape: FieldsShape, pub ast_id: FileAstId<ast::Struct>, } @@ -769,7 +772,7 @@ pub struct Union { pub name: Name, pub visibility: RawVisibilityId, pub generic_params: Interned<GenericParams>, - pub fields: Fields, + pub fields: Box<[Field]>, pub ast_id: FileAstId<ast::Union>, } @@ -782,6 +785,29 @@ pub struct Enum { pub ast_id: FileAstId<ast::Enum>, } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Variant { + pub name: Name, + pub fields: Box<[Field]>, + pub shape: FieldsShape, + pub ast_id: FileAstId<ast::Variant>, +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub enum FieldsShape { + Record, + Tuple, + Unit, +} + +/// A single field of an enum variant or struct +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Field { + pub name: Name, + pub type_ref: Interned<TypeRef>, + pub visibility: RawVisibilityId, +} + #[derive(Debug, Clone, Eq, PartialEq)] pub struct Const { /// `None` for `const _: () = ();` @@ -1039,28 +1065,6 @@ impl ModItem { &ModItem::Function(func) => Some(AssocItem::Function(func)), } } - - pub fn ast_id(&self, tree: &ItemTree) -> FileAstId<ast::Item> { - match self { - ModItem::Use(it) => tree[it.index()].ast_id().upcast(), - ModItem::ExternCrate(it) => tree[it.index()].ast_id().upcast(), - ModItem::ExternBlock(it) => tree[it.index()].ast_id().upcast(), - ModItem::Function(it) => tree[it.index()].ast_id().upcast(), - ModItem::Struct(it) => tree[it.index()].ast_id().upcast(), - ModItem::Union(it) => tree[it.index()].ast_id().upcast(), - ModItem::Enum(it) => tree[it.index()].ast_id().upcast(), - ModItem::Const(it) => tree[it.index()].ast_id().upcast(), - ModItem::Static(it) => tree[it.index()].ast_id().upcast(), - ModItem::Trait(it) => tree[it.index()].ast_id().upcast(), - ModItem::TraitAlias(it) => tree[it.index()].ast_id().upcast(), - ModItem::Impl(it) => tree[it.index()].ast_id().upcast(), - ModItem::TypeAlias(it) => tree[it.index()].ast_id().upcast(), - ModItem::Mod(it) => tree[it.index()].ast_id().upcast(), - ModItem::MacroCall(it) => tree[it.index()].ast_id().upcast(), - ModItem::MacroRules(it) => tree[it.index()].ast_id().upcast(), - ModItem::Macro2(it) => tree[it.index()].ast_id().upcast(), - } - } } #[derive(Debug, Copy, Clone, Eq, PartialEq)] @@ -1099,32 +1103,3 @@ impl AssocItem { } } } - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Variant { - pub name: Name, - pub fields: Fields, - pub ast_id: FileAstId<ast::Variant>, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum Fields { - Record(IdxRange<Field>), - Tuple(IdxRange<Field>), - Unit, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum FieldAstId { - Record(FileAstId<ast::RecordField>), - Tuple(FileAstId<ast::TupleField>), -} - -/// A single field of an enum variant or struct -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Field { - pub name: Name, - pub type_ref: Interned<TypeRef>, - pub visibility: RawVisibilityId, - pub ast_id: FieldAstId, -} |