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.rs67
1 files changed, 45 insertions, 22 deletions
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 82ea5ffeba..c37cf52155 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -41,7 +41,7 @@ mod tests;
use std::{
fmt::{self, Debug},
hash::{Hash, Hasher},
- ops::Index,
+ ops::{Index, Range},
};
use ast::{AstNode, HasName, StructKind};
@@ -308,7 +308,7 @@ pub enum AttrOwner {
/// Inner attributes of the source file.
TopLevel,
- Variant(Idx<Variant>),
+ Variant(FileItemTreeId<Variant>),
Field(Idx<Field>),
Param(Idx<Param>),
TypeOrConstParamData(Idx<TypeOrConstParamData>),
@@ -329,7 +329,7 @@ macro_rules! from_attrs {
from_attrs!(
ModItem(ModItem),
- Variant(Idx<Variant>),
+ Variant(FileItemTreeId<Variant>),
Field(Idx<Field>),
Param(Idx<Param>),
TypeOrConstParamData(Idx<TypeOrConstParamData>),
@@ -337,7 +337,7 @@ from_attrs!(
);
/// Trait implemented by all item nodes in the item tree.
-pub trait ItemTreeNode: Clone {
+pub trait ItemTreeModItemNode: Clone {
type Source: AstIdNode + Into<ast::Item>;
fn ast_id(&self) -> FileAstId<Self::Source>;
@@ -352,35 +352,44 @@ pub trait ItemTreeNode: Clone {
fn id_to_mod_item(id: FileItemTreeId<Self>) -> ModItem;
}
-pub struct FileItemTreeId<N: ItemTreeNode>(Idx<N>);
+pub struct FileItemTreeId<N>(Idx<N>);
-impl<N: ItemTreeNode> FileItemTreeId<N> {
+impl<N> FileItemTreeId<N> {
+ pub fn range_iter(range: Range<Self>) -> impl Iterator<Item = Self> {
+ (range.start.index().into_raw().into_u32()..range.end.index().into_raw().into_u32())
+ .map(RawIdx::from_u32)
+ .map(Idx::from_raw)
+ .map(Self)
+ }
+}
+
+impl<N> FileItemTreeId<N> {
pub fn index(&self) -> Idx<N> {
self.0
}
}
-impl<N: ItemTreeNode> Clone for FileItemTreeId<N> {
+impl<N> Clone for FileItemTreeId<N> {
fn clone(&self) -> Self {
Self(self.0)
}
}
-impl<N: ItemTreeNode> Copy for FileItemTreeId<N> {}
+impl<N> Copy for FileItemTreeId<N> {}
-impl<N: ItemTreeNode> PartialEq for FileItemTreeId<N> {
+impl<N> PartialEq for FileItemTreeId<N> {
fn eq(&self, other: &FileItemTreeId<N>) -> bool {
self.0 == other.0
}
}
-impl<N: ItemTreeNode> Eq for FileItemTreeId<N> {}
+impl<N> Eq for FileItemTreeId<N> {}
-impl<N: ItemTreeNode> Hash for FileItemTreeId<N> {
+impl<N> Hash for FileItemTreeId<N> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.0.hash(state)
}
}
-impl<N: ItemTreeNode> fmt::Debug for FileItemTreeId<N> {
+impl<N> fmt::Debug for FileItemTreeId<N> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.0.fmt(f)
}
@@ -415,12 +424,12 @@ impl TreeId {
}
#[derive(Debug)]
-pub struct ItemTreeId<N: ItemTreeNode> {
+pub struct ItemTreeId<N> {
tree: TreeId,
pub value: FileItemTreeId<N>,
}
-impl<N: ItemTreeNode> ItemTreeId<N> {
+impl<N> ItemTreeId<N> {
pub fn new(tree: TreeId, idx: FileItemTreeId<N>) -> Self {
Self { tree, value: idx }
}
@@ -436,24 +445,31 @@ impl<N: ItemTreeNode> ItemTreeId<N> {
pub fn item_tree(self, db: &dyn DefDatabase) -> Arc<ItemTree> {
self.tree.item_tree(db)
}
+
+ pub fn resolved<R>(self, db: &dyn DefDatabase, cb: impl FnOnce(&N) -> R) -> R
+ where
+ ItemTree: Index<FileItemTreeId<N>, Output = N>,
+ {
+ cb(&self.tree.item_tree(db)[self.value])
+ }
}
-impl<N: ItemTreeNode> Copy for ItemTreeId<N> {}
-impl<N: ItemTreeNode> Clone for ItemTreeId<N> {
+impl<N> Copy for ItemTreeId<N> {}
+impl<N> Clone for ItemTreeId<N> {
fn clone(&self) -> Self {
*self
}
}
-impl<N: ItemTreeNode> PartialEq for ItemTreeId<N> {
+impl<N> PartialEq for ItemTreeId<N> {
fn eq(&self, other: &Self) -> bool {
self.tree == other.tree && self.value == other.value
}
}
-impl<N: ItemTreeNode> Eq for ItemTreeId<N> {}
+impl<N> Eq for ItemTreeId<N> {}
-impl<N: ItemTreeNode> Hash for ItemTreeId<N> {
+impl<N> Hash for ItemTreeId<N> {
fn hash<H: Hasher>(&self, state: &mut H) {
self.tree.hash(state);
self.value.hash(state);
@@ -478,7 +494,7 @@ macro_rules! mod_items {
)+
$(
- impl ItemTreeNode for $typ {
+ impl ItemTreeModItemNode for $typ {
type Source = $ast;
fn ast_id(&self) -> FileAstId<Self::Source> {
@@ -561,13 +577,20 @@ impl Index<RawVisibilityId> for ItemTree {
}
}
-impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree {
+impl<N: ItemTreeModItemNode> Index<FileItemTreeId<N>> for ItemTree {
type Output = N;
fn index(&self, id: FileItemTreeId<N>) -> &N {
N::lookup(self, id.index())
}
}
+impl Index<FileItemTreeId<Variant>> for ItemTree {
+ type Output = Variant;
+ fn index(&self, id: FileItemTreeId<Variant>) -> &Variant {
+ &self[id.index()]
+ }
+}
+
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Use {
pub visibility: RawVisibilityId,
@@ -678,7 +701,7 @@ pub struct Enum {
pub name: Name,
pub visibility: RawVisibilityId,
pub generic_params: Interned<GenericParams>,
- pub variants: IdxRange<Variant>,
+ pub variants: Range<FileItemTreeId<Variant>>,
pub ast_id: FileAstId<ast::Enum>,
}