diff options
Diffstat (limited to 'crates/ra_hir_def/src/item_tree.rs')
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 136 |
1 files changed, 104 insertions, 32 deletions
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index a13a989dd..9656f845e 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs | |||
@@ -3,6 +3,9 @@ | |||
3 | mod lower; | 3 | mod lower; |
4 | 4 | ||
5 | use std::{ | 5 | use std::{ |
6 | fmt::{self, Debug}, | ||
7 | hash::{Hash, Hasher}, | ||
8 | marker::PhantomData, | ||
6 | ops::{Index, Range}, | 9 | ops::{Index, Range}, |
7 | sync::Arc, | 10 | sync::Arc, |
8 | }; | 11 | }; |
@@ -109,6 +112,68 @@ impl ItemTree { | |||
109 | } | 112 | } |
110 | } | 113 | } |
111 | 114 | ||
115 | pub trait ItemTreeNode: Sized { | ||
116 | fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self; | ||
117 | } | ||
118 | |||
119 | pub struct FileItemTreeId<N: ItemTreeNode> { | ||
120 | index: Idx<N>, | ||
121 | _p: PhantomData<N>, | ||
122 | } | ||
123 | |||
124 | impl<N: ItemTreeNode> Clone for FileItemTreeId<N> { | ||
125 | fn clone(&self) -> Self { | ||
126 | Self { index: self.index, _p: PhantomData } | ||
127 | } | ||
128 | } | ||
129 | impl<N: ItemTreeNode> Copy for FileItemTreeId<N> {} | ||
130 | |||
131 | impl<N: ItemTreeNode> PartialEq for FileItemTreeId<N> { | ||
132 | fn eq(&self, other: &FileItemTreeId<N>) -> bool { | ||
133 | self.index == other.index | ||
134 | } | ||
135 | } | ||
136 | impl<N: ItemTreeNode> Eq for FileItemTreeId<N> {} | ||
137 | |||
138 | impl<N: ItemTreeNode> Hash for FileItemTreeId<N> { | ||
139 | fn hash<H: Hasher>(&self, state: &mut H) { | ||
140 | self.index.hash(state) | ||
141 | } | ||
142 | } | ||
143 | |||
144 | impl<N: ItemTreeNode> fmt::Debug for FileItemTreeId<N> { | ||
145 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
146 | self.index.fmt(f) | ||
147 | } | ||
148 | } | ||
149 | |||
150 | pub type ItemTreeId<N> = InFile<FileItemTreeId<N>>; | ||
151 | |||
152 | macro_rules! nodes { | ||
153 | ( $($node:ident in $fld:ident),+ $(,)? ) => { $( | ||
154 | impl ItemTreeNode for $node { | ||
155 | fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self { | ||
156 | &tree.$fld[index] | ||
157 | } | ||
158 | } | ||
159 | )+ }; | ||
160 | } | ||
161 | |||
162 | nodes!( | ||
163 | Import in imports, | ||
164 | Function in functions, | ||
165 | Struct in structs, | ||
166 | Union in unions, | ||
167 | Enum in enums, | ||
168 | Const in consts, | ||
169 | Static in statics, | ||
170 | Trait in traits, | ||
171 | Impl in impls, | ||
172 | TypeAlias in type_aliases, | ||
173 | Mod in mods, | ||
174 | MacroCall in macro_calls, | ||
175 | ); | ||
176 | |||
112 | macro_rules! impl_index { | 177 | macro_rules! impl_index { |
113 | ( $($fld:ident: $t:ty),+ $(,)? ) => { | 178 | ( $($fld:ident: $t:ty),+ $(,)? ) => { |
114 | $( | 179 | $( |
@@ -141,6 +206,13 @@ impl_index!( | |||
141 | exprs: Expr, | 206 | exprs: Expr, |
142 | ); | 207 | ); |
143 | 208 | ||
209 | impl<N: ItemTreeNode> Index<FileItemTreeId<N>> for ItemTree { | ||
210 | type Output = N; | ||
211 | fn index(&self, id: FileItemTreeId<N>) -> &N { | ||
212 | N::lookup(self, id.index) | ||
213 | } | ||
214 | } | ||
215 | |||
144 | /// A desugared `extern crate` or `use` import. | 216 | /// A desugared `extern crate` or `use` import. |
145 | #[derive(Debug, Clone, Eq, PartialEq)] | 217 | #[derive(Debug, Clone, Eq, PartialEq)] |
146 | pub struct Import { | 218 | pub struct Import { |
@@ -304,48 +376,48 @@ macro_rules! impl_froms { | |||
304 | 376 | ||
305 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] | 377 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] |
306 | pub enum ModItem { | 378 | pub enum ModItem { |
307 | Import(Idx<Import>), | 379 | Import(FileItemTreeId<Import>), |
308 | Function(Idx<Function>), | 380 | Function(FileItemTreeId<Function>), |
309 | Struct(Idx<Struct>), | 381 | Struct(FileItemTreeId<Struct>), |
310 | Union(Idx<Union>), | 382 | Union(FileItemTreeId<Union>), |
311 | Enum(Idx<Enum>), | 383 | Enum(FileItemTreeId<Enum>), |
312 | Const(Idx<Const>), | 384 | Const(FileItemTreeId<Const>), |
313 | Static(Idx<Static>), | 385 | Static(FileItemTreeId<Static>), |
314 | Trait(Idx<Trait>), | 386 | Trait(FileItemTreeId<Trait>), |
315 | Impl(Idx<Impl>), | 387 | Impl(FileItemTreeId<Impl>), |
316 | TypeAlias(Idx<TypeAlias>), | 388 | TypeAlias(FileItemTreeId<TypeAlias>), |
317 | Mod(Idx<Mod>), | 389 | Mod(FileItemTreeId<Mod>), |
318 | MacroCall(Idx<MacroCall>), | 390 | MacroCall(FileItemTreeId<MacroCall>), |
319 | } | 391 | } |
320 | 392 | ||
321 | impl_froms!(ModItem { | 393 | impl_froms!(ModItem { |
322 | Import(Idx<Import>), | 394 | Import(FileItemTreeId<Import>), |
323 | Function(Idx<Function>), | 395 | Function(FileItemTreeId<Function>), |
324 | Struct(Idx<Struct>), | 396 | Struct(FileItemTreeId<Struct>), |
325 | Union(Idx<Union>), | 397 | Union(FileItemTreeId<Union>), |
326 | Enum(Idx<Enum>), | 398 | Enum(FileItemTreeId<Enum>), |
327 | Const(Idx<Const>), | 399 | Const(FileItemTreeId<Const>), |
328 | Static(Idx<Static>), | 400 | Static(FileItemTreeId<Static>), |
329 | Trait(Idx<Trait>), | 401 | Trait(FileItemTreeId<Trait>), |
330 | Impl(Idx<Impl>), | 402 | Impl(FileItemTreeId<Impl>), |
331 | TypeAlias(Idx<TypeAlias>), | 403 | TypeAlias(FileItemTreeId<TypeAlias>), |
332 | Mod(Idx<Mod>), | 404 | Mod(FileItemTreeId<Mod>), |
333 | MacroCall(Idx<MacroCall>), | 405 | MacroCall(FileItemTreeId<MacroCall>), |
334 | }); | 406 | }); |
335 | 407 | ||
336 | #[derive(Debug, Eq, PartialEq)] | 408 | #[derive(Debug, Eq, PartialEq)] |
337 | pub enum AssocItem { | 409 | pub enum AssocItem { |
338 | Function(Idx<Function>), | 410 | Function(FileItemTreeId<Function>), |
339 | TypeAlias(Idx<TypeAlias>), | 411 | TypeAlias(FileItemTreeId<TypeAlias>), |
340 | Const(Idx<Const>), | 412 | Const(FileItemTreeId<Const>), |
341 | MacroCall(Idx<MacroCall>), | 413 | MacroCall(FileItemTreeId<MacroCall>), |
342 | } | 414 | } |
343 | 415 | ||
344 | impl_froms!(AssocItem { | 416 | impl_froms!(AssocItem { |
345 | Function(Idx<Function>), | 417 | Function(FileItemTreeId<Function>), |
346 | TypeAlias(Idx<TypeAlias>), | 418 | TypeAlias(FileItemTreeId<TypeAlias>), |
347 | Const(Idx<Const>), | 419 | Const(FileItemTreeId<Const>), |
348 | MacroCall(Idx<MacroCall>), | 420 | MacroCall(FileItemTreeId<MacroCall>), |
349 | }); | 421 | }); |
350 | 422 | ||
351 | #[derive(Debug, Eq, PartialEq)] | 423 | #[derive(Debug, Eq, PartialEq)] |