diff options
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 84 |
1 files changed, 69 insertions, 15 deletions
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index c3990c2eb..aca2503a0 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs | |||
@@ -112,10 +112,19 @@ impl ItemTree { | |||
112 | } | 112 | } |
113 | } | 113 | } |
114 | 114 | ||
115 | pub trait ItemTreeNode: Sized { | 115 | /// Trait implemented by all nodes in the item tree. |
116 | pub trait ItemTreeNode: Clone { | ||
117 | /// Looks up an instance of `Self` in an item tree. | ||
116 | fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self; | 118 | fn lookup(tree: &ItemTree, index: Idx<Self>) -> &Self; |
117 | } | 119 | } |
118 | 120 | ||
121 | /// Trait for item tree nodes that allow accessing the original AST node. | ||
122 | pub trait ItemTreeSource: ItemTreeNode { | ||
123 | type Source: AstNode; | ||
124 | |||
125 | fn ast_id(&self) -> FileAstId<Self::Source>; | ||
126 | } | ||
127 | |||
119 | pub struct FileItemTreeId<N: ItemTreeNode> { | 128 | pub struct FileItemTreeId<N: ItemTreeNode> { |
120 | index: Idx<N>, | 129 | index: Idx<N>, |
121 | _p: PhantomData<N>, | 130 | _p: PhantomData<N>, |
@@ -174,6 +183,32 @@ nodes!( | |||
174 | MacroCall in macro_calls, | 183 | MacroCall in macro_calls, |
175 | ); | 184 | ); |
176 | 185 | ||
186 | macro_rules! source { | ||
187 | ( $($node:ident -> $ast:path),+ $(,)? ) => { $( | ||
188 | impl ItemTreeSource for $node { | ||
189 | type Source = $ast; | ||
190 | |||
191 | fn ast_id(&self) -> FileAstId<Self::Source> { | ||
192 | self.ast_id | ||
193 | } | ||
194 | } | ||
195 | )+ }; | ||
196 | } | ||
197 | |||
198 | source! { | ||
199 | Function -> ast::FnDef, | ||
200 | Struct -> ast::StructDef, | ||
201 | Union -> ast::UnionDef, | ||
202 | Enum -> ast::EnumDef, | ||
203 | Const -> ast::ConstDef, | ||
204 | Static -> ast::StaticDef, | ||
205 | Trait -> ast::TraitDef, | ||
206 | Impl -> ast::ImplDef, | ||
207 | TypeAlias -> ast::TypeAliasDef, | ||
208 | Mod -> ast::Module, | ||
209 | MacroCall -> ast::MacroCall, | ||
210 | } | ||
211 | |||
177 | macro_rules! impl_index { | 212 | macro_rules! impl_index { |
178 | ( $($fld:ident: $t:ty),+ $(,)? ) => { | 213 | ( $($fld:ident: $t:ty),+ $(,)? ) => { |
179 | $( | 214 | $( |
@@ -225,7 +260,7 @@ pub struct Import { | |||
225 | pub is_macro_use: bool, | 260 | pub is_macro_use: bool, |
226 | } | 261 | } |
227 | 262 | ||
228 | #[derive(Debug, Eq, PartialEq)] | 263 | #[derive(Debug, Clone, Eq, PartialEq)] |
229 | pub struct Function { | 264 | pub struct Function { |
230 | pub name: Name, | 265 | pub name: Name, |
231 | pub attrs: Attrs, | 266 | pub attrs: Attrs, |
@@ -238,7 +273,7 @@ pub struct Function { | |||
238 | // FIXME inner items | 273 | // FIXME inner items |
239 | } | 274 | } |
240 | 275 | ||
241 | #[derive(Debug, Eq, PartialEq)] | 276 | #[derive(Debug, Clone, Eq, PartialEq)] |
242 | pub struct Struct { | 277 | pub struct Struct { |
243 | pub name: Name, | 278 | pub name: Name, |
244 | pub attrs: Attrs, | 279 | pub attrs: Attrs, |
@@ -249,7 +284,7 @@ pub struct Struct { | |||
249 | pub kind: StructDefKind, | 284 | pub kind: StructDefKind, |
250 | } | 285 | } |
251 | 286 | ||
252 | #[derive(Debug, Eq, PartialEq)] | 287 | #[derive(Debug, Clone, Eq, PartialEq)] |
253 | pub enum StructDefKind { | 288 | pub enum StructDefKind { |
254 | /// `struct S { ... }` - type namespace only. | 289 | /// `struct S { ... }` - type namespace only. |
255 | Record, | 290 | Record, |
@@ -259,7 +294,7 @@ pub enum StructDefKind { | |||
259 | Unit, | 294 | Unit, |
260 | } | 295 | } |
261 | 296 | ||
262 | #[derive(Debug, Eq, PartialEq)] | 297 | #[derive(Debug, Clone, Eq, PartialEq)] |
263 | pub struct Union { | 298 | pub struct Union { |
264 | pub name: Name, | 299 | pub name: Name, |
265 | pub attrs: Attrs, | 300 | pub attrs: Attrs, |
@@ -269,7 +304,7 @@ pub struct Union { | |||
269 | pub ast_id: FileAstId<ast::UnionDef>, | 304 | pub ast_id: FileAstId<ast::UnionDef>, |
270 | } | 305 | } |
271 | 306 | ||
272 | #[derive(Debug, Eq, PartialEq)] | 307 | #[derive(Debug, Clone, Eq, PartialEq)] |
273 | pub struct Enum { | 308 | pub struct Enum { |
274 | pub name: Name, | 309 | pub name: Name, |
275 | pub attrs: Attrs, | 310 | pub attrs: Attrs, |
@@ -279,7 +314,7 @@ pub struct Enum { | |||
279 | pub ast_id: FileAstId<ast::EnumDef>, | 314 | pub ast_id: FileAstId<ast::EnumDef>, |
280 | } | 315 | } |
281 | 316 | ||
282 | #[derive(Debug, Eq, PartialEq)] | 317 | #[derive(Debug, Clone, Eq, PartialEq)] |
283 | pub struct Const { | 318 | pub struct Const { |
284 | /// const _: () = (); | 319 | /// const _: () = (); |
285 | pub name: Option<Name>, | 320 | pub name: Option<Name>, |
@@ -288,7 +323,7 @@ pub struct Const { | |||
288 | pub ast_id: FileAstId<ast::ConstDef>, | 323 | pub ast_id: FileAstId<ast::ConstDef>, |
289 | } | 324 | } |
290 | 325 | ||
291 | #[derive(Debug, Eq, PartialEq)] | 326 | #[derive(Debug, Clone, Eq, PartialEq)] |
292 | pub struct Static { | 327 | pub struct Static { |
293 | pub name: Name, | 328 | pub name: Name, |
294 | pub visibility: RawVisibility, | 329 | pub visibility: RawVisibility, |
@@ -296,7 +331,7 @@ pub struct Static { | |||
296 | pub ast_id: FileAstId<ast::StaticDef>, | 331 | pub ast_id: FileAstId<ast::StaticDef>, |
297 | } | 332 | } |
298 | 333 | ||
299 | #[derive(Debug, Eq, PartialEq)] | 334 | #[derive(Debug, Clone, Eq, PartialEq)] |
300 | pub struct Trait { | 335 | pub struct Trait { |
301 | pub name: Name, | 336 | pub name: Name, |
302 | pub visibility: RawVisibility, | 337 | pub visibility: RawVisibility, |
@@ -306,7 +341,7 @@ pub struct Trait { | |||
306 | pub ast_id: FileAstId<ast::TraitDef>, | 341 | pub ast_id: FileAstId<ast::TraitDef>, |
307 | } | 342 | } |
308 | 343 | ||
309 | #[derive(Debug, Eq, PartialEq)] | 344 | #[derive(Debug, Clone, Eq, PartialEq)] |
310 | pub struct Impl { | 345 | pub struct Impl { |
311 | pub generic_params: GenericParams, | 346 | pub generic_params: GenericParams, |
312 | pub target_trait: Option<TypeRef>, | 347 | pub target_trait: Option<TypeRef>, |
@@ -325,7 +360,7 @@ pub struct TypeAlias { | |||
325 | pub ast_id: FileAstId<ast::TypeAliasDef>, | 360 | pub ast_id: FileAstId<ast::TypeAliasDef>, |
326 | } | 361 | } |
327 | 362 | ||
328 | #[derive(Debug, Eq, PartialEq)] | 363 | #[derive(Debug, Clone, Eq, PartialEq)] |
329 | pub struct Mod { | 364 | pub struct Mod { |
330 | pub name: Name, | 365 | pub name: Name, |
331 | pub visibility: RawVisibility, | 366 | pub visibility: RawVisibility, |
@@ -333,7 +368,7 @@ pub struct Mod { | |||
333 | pub ast_id: FileAstId<ast::Module>, | 368 | pub ast_id: FileAstId<ast::Module>, |
334 | } | 369 | } |
335 | 370 | ||
336 | #[derive(Debug, Eq, PartialEq)] | 371 | #[derive(Debug, Clone, Eq, PartialEq)] |
337 | pub enum ModKind { | 372 | pub enum ModKind { |
338 | /// `mod m { ... }` | 373 | /// `mod m { ... }` |
339 | Inline { items: Vec<ModItem> }, | 374 | Inline { items: Vec<ModItem> }, |
@@ -342,7 +377,7 @@ pub enum ModKind { | |||
342 | Outline {}, | 377 | Outline {}, |
343 | } | 378 | } |
344 | 379 | ||
345 | #[derive(Debug, Eq, PartialEq)] | 380 | #[derive(Debug, Clone, Eq, PartialEq)] |
346 | pub struct MacroCall { | 381 | pub struct MacroCall { |
347 | /// For `macro_rules!` declarations, this is the name of the declared macro. | 382 | /// For `macro_rules!` declarations, this is the name of the declared macro. |
348 | pub name: Option<Name>, | 383 | pub name: Option<Name>, |
@@ -359,7 +394,7 @@ pub struct MacroCall { | |||
359 | 394 | ||
360 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array | 395 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array |
361 | // lengths, but we don't do much with them yet. | 396 | // lengths, but we don't do much with them yet. |
362 | #[derive(Debug, Eq, PartialEq)] | 397 | #[derive(Debug, Clone, Eq, PartialEq)] |
363 | pub struct Expr; | 398 | pub struct Expr; |
364 | 399 | ||
365 | macro_rules! impl_froms { | 400 | macro_rules! impl_froms { |
@@ -390,6 +425,25 @@ pub enum ModItem { | |||
390 | MacroCall(FileItemTreeId<MacroCall>), | 425 | MacroCall(FileItemTreeId<MacroCall>), |
391 | } | 426 | } |
392 | 427 | ||
428 | impl ModItem { | ||
429 | pub fn as_assoc_item(&self) -> Option<AssocItem> { | ||
430 | match self { | ||
431 | ModItem::Import(_) | ||
432 | | ModItem::Struct(_) | ||
433 | | ModItem::Union(_) | ||
434 | | ModItem::Enum(_) | ||
435 | | ModItem::Static(_) | ||
436 | | ModItem::Trait(_) | ||
437 | | ModItem::Impl(_) | ||
438 | | ModItem::Mod(_) => None, | ||
439 | ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), | ||
440 | ModItem::Const(konst) => Some(AssocItem::Const(*konst)), | ||
441 | ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), | ||
442 | ModItem::Function(func) => Some(AssocItem::Function(*func)), | ||
443 | } | ||
444 | } | ||
445 | } | ||
446 | |||
393 | impl_froms!(ModItem { | 447 | impl_froms!(ModItem { |
394 | Import(FileItemTreeId<Import>), | 448 | Import(FileItemTreeId<Import>), |
395 | Function(FileItemTreeId<Function>), | 449 | Function(FileItemTreeId<Function>), |
@@ -405,7 +459,7 @@ impl_froms!(ModItem { | |||
405 | MacroCall(FileItemTreeId<MacroCall>), | 459 | MacroCall(FileItemTreeId<MacroCall>), |
406 | }); | 460 | }); |
407 | 461 | ||
408 | #[derive(Debug, Eq, PartialEq)] | 462 | #[derive(Debug, Copy, Clone, Eq, PartialEq)] |
409 | pub enum AssocItem { | 463 | pub enum AssocItem { |
410 | Function(FileItemTreeId<Function>), | 464 | Function(FileItemTreeId<Function>), |
411 | TypeAlias(FileItemTreeId<TypeAlias>), | 465 | TypeAlias(FileItemTreeId<TypeAlias>), |