@@ -10,7 +10,7 @@ use crate::{
1010
1111use super :: {
1212 scope_graph_viz:: ScopeGraphFormatter , Body , Enum , ExprId , Func , FuncParamLabel , IdentId ,
13- IngotId , ItemKind , TopLevelMod , Use , Visibility ,
13+ IngotId , ItemKind , TopLevelMod , Use , VariantKind , Visibility ,
1414} ;
1515
1616/// Represents a scope relation graph in a top-level module.
@@ -82,7 +82,7 @@ pub enum ScopeId {
8282 FuncParam ( ItemKind , usize ) ,
8383
8484 /// A field scope.
85- Field ( ItemKind , usize ) ,
85+ Field ( FieldParent , usize ) ,
8686
8787 /// A variant scope.
8888 Variant ( ItemKind , usize ) ,
@@ -97,7 +97,8 @@ impl ScopeId {
9797 ScopeId :: Item ( item) => item. top_mod ( db) ,
9898 ScopeId :: GenericParam ( item, _) => item. top_mod ( db) ,
9999 ScopeId :: FuncParam ( item, _) => item. top_mod ( db) ,
100- ScopeId :: Field ( item, _) => item. top_mod ( db) ,
100+ ScopeId :: Field ( FieldParent :: Item ( item) , _) => item. top_mod ( db) ,
101+ ScopeId :: Field ( FieldParent :: Variant ( item, _) , _) => item. top_mod ( db) ,
101102 ScopeId :: Variant ( item, _) => item. top_mod ( db) ,
102103 ScopeId :: Block ( body, _) => body. top_mod ( db) ,
103104 }
@@ -122,7 +123,8 @@ impl ScopeId {
122123 ScopeId :: Item ( item) => item,
123124 ScopeId :: GenericParam ( item, _) => item,
124125 ScopeId :: FuncParam ( item, _) => item,
125- ScopeId :: Field ( item, _) => item,
126+ ScopeId :: Field ( FieldParent :: Item ( item) , _) => item,
127+ ScopeId :: Field ( FieldParent :: Variant ( item, _) , _) => item,
126128 ScopeId :: Variant ( item, _) => item,
127129 ScopeId :: Block ( body, _) => body. into ( ) ,
128130 }
@@ -261,11 +263,18 @@ impl ScopeId {
261263 enum_. variants ( db) . data ( db) [ idx] . name . to_opt ( )
262264 }
263265
264- ScopeId :: Field ( parent, idx) => match parent {
266+ ScopeId :: Field ( FieldParent :: Item ( parent) , idx) => match parent {
265267 ItemKind :: Struct ( s) => s. fields ( db) . data ( db) [ idx] . name . to_opt ( ) ,
266268 ItemKind :: Contract ( c) => c. fields ( db) . data ( db) [ idx] . name . to_opt ( ) ,
267269 _ => unreachable ! ( ) ,
268270 } ,
271+ ScopeId :: Field ( FieldParent :: Variant ( parent, vidx) , fidx) => {
272+ let enum_: Enum = parent. try_into ( ) . unwrap ( ) ;
273+ match enum_. variants ( db) . data ( db) [ vidx] . kind {
274+ VariantKind :: Record ( fields) => fields. data ( db) [ fidx] . name . to_opt ( ) ,
275+ _ => unreachable ! ( ) ,
276+ }
277+ }
269278
270279 ScopeId :: FuncParam ( parent, idx) => {
271280 let func: Func = parent. try_into ( ) . unwrap ( ) ;
@@ -297,11 +306,24 @@ impl ScopeId {
297306 Some ( enum_. lazy_span ( ) . variants ( ) . variant ( idx) . name ( ) . into ( ) )
298307 }
299308
300- ScopeId :: Field ( parent, idx) => match parent {
309+ ScopeId :: Field ( FieldParent :: Item ( parent) , idx) => match parent {
301310 ItemKind :: Struct ( s) => Some ( s. lazy_span ( ) . fields ( ) . field ( idx) . name ( ) . into ( ) ) ,
302311 ItemKind :: Contract ( c) => Some ( c. lazy_span ( ) . fields ( ) . field ( idx) . name ( ) . into ( ) ) ,
303312 _ => unreachable ! ( ) ,
304313 } ,
314+ ScopeId :: Field ( FieldParent :: Variant ( parent, vidx) , fidx) => {
315+ let enum_: Enum = parent. try_into ( ) . unwrap ( ) ;
316+ Some (
317+ enum_
318+ . lazy_span ( )
319+ . variants ( )
320+ . variant ( vidx)
321+ . fields ( )
322+ . field ( fidx)
323+ . name ( )
324+ . into ( ) ,
325+ )
326+ }
305327
306328 ScopeId :: FuncParam ( parent, idx) => {
307329 let func: Func = parent. try_into ( ) . unwrap ( ) ;
@@ -353,6 +375,12 @@ impl ScopeId {
353375 }
354376}
355377
378+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
379+ pub enum FieldParent {
380+ Item ( ItemKind ) ,
381+ Variant ( ItemKind , usize ) ,
382+ }
383+
356384struct ScopeGraphItemIterDfs < ' a > {
357385 db : & ' a dyn HirDb ,
358386 graph : & ' a ScopeGraph ,
@@ -542,7 +570,13 @@ pub struct AnonEdge();
542570#[ cfg( test) ]
543571mod tests {
544572
545- use crate :: { hir_def:: ItemKind , test_db:: TestDb } ;
573+ use crate :: {
574+ hir_def:: {
575+ scope_graph:: { FieldParent , ScopeId } ,
576+ ItemKind ,
577+ } ,
578+ test_db:: TestDb ,
579+ } ;
546580
547581 #[ test]
548582 fn item_tree ( ) {
@@ -555,7 +589,7 @@ mod tests {
555589 fn baz()
556590 }
557591 }
558-
592+
559593 enum MyEnum {}
560594
561595 mod baz {
@@ -581,4 +615,30 @@ mod tests {
581615 }
582616 }
583617 }
618+
619+ #[ test]
620+ fn enum_record_fields ( ) {
621+ let mut db = TestDb :: default ( ) ;
622+
623+ let text = r#"
624+ enum Foo {
625+ X { a: i8, b: i8 },
626+ }
627+ "# ;
628+
629+ let file = db. standalone_file ( text) ;
630+ let scope_graph = db. parse_source ( file) ;
631+ let root = scope_graph. top_mod . scope ( ) ;
632+ let enum_ = scope_graph. children ( root) . next ( ) . unwrap ( ) ;
633+ assert ! ( matches!( enum_. item( ) , ItemKind :: Enum ( _) ) ) ;
634+
635+ let variant = scope_graph. children ( enum_) . next ( ) . unwrap ( ) ;
636+ assert ! ( matches!( variant, ScopeId :: Variant ( _, _) ) ) ;
637+
638+ let field = scope_graph. children ( variant) . next ( ) . unwrap ( ) ;
639+ assert ! ( matches!(
640+ field,
641+ ScopeId :: Field ( FieldParent :: Variant ( _, _) , _)
642+ ) ) ;
643+ }
584644}
0 commit comments