@@ -164,6 +164,9 @@ type typeDecl struct {
164
164
memberDeclarations []ast.Declaration
165
165
nestedTypes []* typeDecl
166
166
hasConstructor bool
167
+
168
+ // used in simpleType generation
169
+ conformances []* sema.InterfaceType
167
170
}
168
171
169
172
type generator struct {
@@ -429,9 +432,40 @@ func (g *generator) addConstructorDocStringDeclaration(
429
432
)
430
433
}
431
434
432
- func (g * generator ) VisitCompositeDeclaration (decl * ast.CompositeDeclaration ) (_ struct {}) {
435
+ func (g * generator ) VisitCompositeOrInterfaceDeclaration (decl ast.ConformingDeclaration ) (_ struct {}) {
436
+ var compositeKind common.CompositeKind
437
+ var typeName string
438
+ var typeDec * typeDecl
439
+ var members []ast.Declaration
440
+ var conformances []* ast.NominalType
441
+ var isInterfaceType bool
442
+
443
+ switch actualDecl := decl .(type ) {
444
+ case * ast.CompositeDeclaration :
445
+ compositeKind = actualDecl .Kind ()
446
+ typeName = actualDecl .Identifier .Identifier
447
+ typeDec = & typeDecl {
448
+ typeName : typeName ,
449
+ fullTypeName : g .newFullTypeName (typeName ),
450
+ compositeKind : compositeKind ,
451
+ }
452
+ members = actualDecl .Members .Declarations ()
453
+ conformances = actualDecl .Conformances
454
+ isInterfaceType = false
455
+ case * ast.InterfaceDeclaration :
456
+ compositeKind = actualDecl .Kind ()
457
+ typeName = actualDecl .Identifier .Identifier
458
+ typeDec = & typeDecl {
459
+ typeName : typeName ,
460
+ fullTypeName : g .newFullTypeName (typeName ),
461
+ compositeKind : compositeKind ,
462
+ }
463
+ members = actualDecl .Members .Declarations ()
464
+ isInterfaceType = true
465
+ default :
466
+ panic ("Expected composite or interface declaration" )
467
+ }
433
468
434
- compositeKind := decl .CompositeKind
435
469
switch compositeKind {
436
470
case common .CompositeKindStructure ,
437
471
common .CompositeKindResource ,
@@ -441,25 +475,17 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
441
475
panic (fmt .Sprintf ("%s declarations are not supported" , compositeKind .Name ()))
442
476
}
443
477
444
- typeName := decl .Identifier .Identifier
445
-
446
- typeDecl := & typeDecl {
447
- typeName : typeName ,
448
- fullTypeName : g .newFullTypeName (typeName ),
449
- compositeKind : compositeKind ,
450
- }
451
-
452
478
if len (g .typeStack ) > 0 {
453
479
parentType := g .typeStack [len (g .typeStack )- 1 ]
454
480
parentType .nestedTypes = append (
455
481
parentType .nestedTypes ,
456
- typeDecl ,
482
+ typeDec ,
457
483
)
458
484
}
459
485
460
486
g .typeStack = append (
461
487
g .typeStack ,
462
- typeDecl ,
488
+ typeDec ,
463
489
)
464
490
defer func () {
465
491
// Pop
@@ -473,6 +499,8 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
473
499
// Check if the declaration is explicitly marked to be generated as a composite type.
474
500
if _ , ok := g .leadingPragma ["compositeType" ]; ok {
475
501
generateSimpleType = false
502
+ } else if isInterfaceType {
503
+ generateSimpleType = false
476
504
} else {
477
505
// If not, decide what to generate depending on the type.
478
506
@@ -492,13 +520,13 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
492
520
}
493
521
}
494
522
495
- for _ , memberDeclaration := range decl . Members . Declarations () {
523
+ for _ , memberDeclaration := range members {
496
524
generateDeclaration (g , memberDeclaration )
497
525
498
526
// Visiting unsupported declarations panics,
499
527
// so only supported member declarations are added
500
- typeDecl .memberDeclarations = append (
501
- typeDecl .memberDeclarations ,
528
+ typeDec .memberDeclarations = append (
529
+ typeDec .memberDeclarations ,
502
530
memberDeclaration ,
503
531
)
504
532
@@ -514,7 +542,7 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
514
542
}
515
543
}
516
544
517
- for _ , conformance := range decl . Conformances {
545
+ for _ , conformance := range conformances {
518
546
switch conformance .Identifier .Identifier {
519
547
case "Storable" :
520
548
if ! generateSimpleType {
@@ -523,7 +551,7 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
523
551
g .currentTypeID (),
524
552
))
525
553
}
526
- typeDecl .storable = true
554
+ typeDec .storable = true
527
555
528
556
case "Primitive" :
529
557
if ! generateSimpleType {
@@ -532,7 +560,7 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
532
560
g .currentTypeID (),
533
561
))
534
562
}
535
- typeDecl .primitive = true
563
+ typeDec .primitive = true
536
564
537
565
case "Equatable" :
538
566
if ! generateSimpleType {
@@ -541,7 +569,7 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
541
569
g .currentTypeID (),
542
570
))
543
571
}
544
- typeDecl .equatable = true
572
+ typeDec .equatable = true
545
573
546
574
case "Comparable" :
547
575
if ! generateSimpleType {
@@ -550,7 +578,7 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
550
578
g .currentTypeID (),
551
579
))
552
580
}
553
- typeDecl .comparable = true
581
+ typeDec .comparable = true
554
582
555
583
case "Exportable" :
556
584
if ! generateSimpleType {
@@ -559,10 +587,10 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
559
587
g .currentTypeID (),
560
588
))
561
589
}
562
- typeDecl .exportable = true
590
+ typeDec .exportable = true
563
591
564
592
case "Importable" :
565
- typeDecl .importable = true
593
+ typeDec .importable = true
566
594
567
595
case "ContainFields" :
568
596
if ! generateSimpleType {
@@ -571,18 +599,20 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
571
599
g .currentTypeID (),
572
600
))
573
601
}
574
- typeDecl .memberAccessible = true
602
+ typeDec .memberAccessible = true
603
+ case "StructStringer" :
604
+ typeDec .conformances = append (typeDec .conformances , sema .StructStringerType )
575
605
}
576
606
}
577
607
578
608
var typeVarDecl dst.Expr
579
609
if generateSimpleType {
580
- typeVarDecl = simpleTypeLiteral (typeDecl )
610
+ typeVarDecl = simpleTypeLiteral (typeDec )
581
611
} else {
582
- typeVarDecl = compositeTypeExpr ( typeDecl )
612
+ typeVarDecl = compositeOrInterfaceTypeExpr ( typeDec , isInterfaceType )
583
613
}
584
614
585
- fullTypeName := typeDecl .fullTypeName
615
+ fullTypeName := typeDec .fullTypeName
586
616
587
617
tyVarName := typeVarName (fullTypeName )
588
618
@@ -597,7 +627,7 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
597
627
),
598
628
)
599
629
600
- memberDeclarations := typeDecl .memberDeclarations
630
+ memberDeclarations := typeDec .memberDeclarations
601
631
602
632
if len (memberDeclarations ) > 0 {
603
633
@@ -700,7 +730,7 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
700
730
},
701
731
}
702
732
703
- if typeDecl .hasConstructor {
733
+ if typeDec .hasConstructor {
704
734
stmts = append (
705
735
stmts ,
706
736
& dst.AssignStmt {
@@ -736,8 +766,12 @@ func (g *generator) VisitCompositeDeclaration(decl *ast.CompositeDeclaration) (_
736
766
return
737
767
}
738
768
739
- func (* generator ) VisitInterfaceDeclaration (_ * ast.InterfaceDeclaration ) struct {} {
740
- panic ("interface declarations are not supported" )
769
+ func (g * generator ) VisitCompositeDeclaration (decl * ast.CompositeDeclaration ) (_ struct {}) {
770
+ return g .VisitCompositeOrInterfaceDeclaration (decl )
771
+ }
772
+
773
+ func (g * generator ) VisitInterfaceDeclaration (decl * ast.InterfaceDeclaration ) (_ struct {}) {
774
+ return g .VisitCompositeOrInterfaceDeclaration (decl )
741
775
}
742
776
743
777
func (* generator ) VisitAttachmentDeclaration (_ * ast.AttachmentDeclaration ) struct {} {
@@ -1591,6 +1625,9 @@ func simpleTypeLiteral(ty *typeDecl) dst.Expr {
1591
1625
// Comparable: false,
1592
1626
// Exportable: false,
1593
1627
// Importable: false,
1628
+ // comformances: []*InterfaceType {
1629
+ // StructStringerType,
1630
+ // }
1594
1631
//}
1595
1632
1596
1633
isResource := ty .compositeKind == common .CompositeKindResource
@@ -1609,6 +1646,33 @@ func simpleTypeLiteral(ty *typeDecl) dst.Expr {
1609
1646
goKeyValue ("ContainFields" , goBoolLit (ty .memberAccessible )),
1610
1647
}
1611
1648
1649
+ if len (ty .conformances ) > 0 {
1650
+ var elts = []dst.Expr {}
1651
+ for _ , conformance := range ty .conformances {
1652
+ var name = ""
1653
+ switch conformance {
1654
+ case sema .StructStringerType :
1655
+ name = "StructStringerType"
1656
+ default :
1657
+ panic ("Unsupported conformance typeID" )
1658
+ }
1659
+ elts = append (elts , & dst.Ident {
1660
+ Name : name ,
1661
+ Path : semaPath ,
1662
+ })
1663
+ }
1664
+ elements = append (elements , goKeyValue ("conformances" , & dst.CompositeLit {
1665
+ Type : & dst.ArrayType {
1666
+ Elt : & dst.StarExpr {
1667
+ X : & dst.Ident {
1668
+ Name : "InterfaceType" ,
1669
+ },
1670
+ },
1671
+ },
1672
+ Elts : elts ,
1673
+ }))
1674
+ }
1675
+
1612
1676
return & dst.UnaryExpr {
1613
1677
Op : token .AND ,
1614
1678
X : & dst.CompositeLit {
@@ -1971,10 +2035,10 @@ func stringMemberResolverMapType() *dst.MapType {
1971
2035
}
1972
2036
}
1973
2037
1974
- func compositeTypeExpr (ty * typeDecl ) dst.Expr {
2038
+ func compositeOrInterfaceTypeExpr (ty * typeDecl , isInterfaceType bool ) dst.Expr {
1975
2039
1976
2040
// func() *CompositeType {
1977
- // var t = &CompositeType{
2041
+ // var t = &CompositeType {
1978
2042
// Identifier: FooTypeName,
1979
2043
// Kind: common.CompositeKindStructure,
1980
2044
// ImportableBuiltin: false,
@@ -1985,13 +2049,23 @@ func compositeTypeExpr(ty *typeDecl) dst.Expr {
1985
2049
// return t
1986
2050
// }()
1987
2051
2052
+ // func() *InterfaceType {
2053
+ // var t = &InterfaceType{
2054
+ // Identifier: FooTypeName,
2055
+ // CompositeKind: common.CompositeKindStructure,
2056
+ // }
2057
+ //
2058
+ // t.SetNestedType(FooBarTypeName, FooBarType)
2059
+ // return t
2060
+ // }()
2061
+
1988
2062
const typeVarName = "t"
1989
2063
1990
2064
statements := []dst.Stmt {
1991
2065
& dst.DeclStmt {
1992
2066
Decl : goVarDecl (
1993
2067
typeVarName ,
1994
- compositeTypeLiteral (ty ),
2068
+ compositeOrInterfaceTypeLiteral (ty , isInterfaceType ),
1995
2069
),
1996
2070
},
1997
2071
}
@@ -2023,6 +2097,11 @@ func compositeTypeExpr(ty *typeDecl) dst.Expr {
2023
2097
},
2024
2098
)
2025
2099
2100
+ name := "CompositeType"
2101
+ if isInterfaceType {
2102
+ name = "InterfaceType"
2103
+ }
2104
+
2026
2105
return & dst.CallExpr {
2027
2106
Fun : & dst.FuncLit {
2028
2107
Type : & dst.FuncType {
@@ -2032,7 +2111,7 @@ func compositeTypeExpr(ty *typeDecl) dst.Expr {
2032
2111
{
2033
2112
Type : & dst.StarExpr {
2034
2113
X : & dst.Ident {
2035
- Name : "CompositeType" ,
2114
+ Name : name ,
2036
2115
Path : semaPath ,
2037
2116
},
2038
2117
},
@@ -2047,21 +2126,30 @@ func compositeTypeExpr(ty *typeDecl) dst.Expr {
2047
2126
}
2048
2127
}
2049
2128
2050
- func compositeTypeLiteral (ty * typeDecl ) dst.Expr {
2129
+ func compositeOrInterfaceTypeLiteral (ty * typeDecl , isInterfaceType bool ) dst.Expr {
2051
2130
kind := compositeKindExpr (ty .compositeKind )
2052
2131
2053
2132
elements := []dst.Expr {
2054
2133
goKeyValue ("Identifier" , typeNameVarIdent (ty .fullTypeName )),
2055
- goKeyValue ("Kind" , kind ),
2056
- goKeyValue ("ImportableBuiltin" , goBoolLit (ty .importable )),
2057
- goKeyValue ("HasComputedMembers" , goBoolLit (true )),
2134
+ }
2135
+
2136
+ name := "InterfaceType"
2137
+ if isInterfaceType {
2138
+ elements = append (elements ,
2139
+ goKeyValue ("CompositeKind" , kind ))
2140
+ } else {
2141
+ name = "CompositeType"
2142
+ elements = append (elements ,
2143
+ goKeyValue ("Kind" , kind ),
2144
+ goKeyValue ("ImportableBuiltin" , goBoolLit (ty .importable )),
2145
+ goKeyValue ("HasComputedMembers" , goBoolLit (true )))
2058
2146
}
2059
2147
2060
2148
return & dst.UnaryExpr {
2061
2149
Op : token .AND ,
2062
2150
X : & dst.CompositeLit {
2063
2151
Type : & dst.Ident {
2064
- Name : "CompositeType" ,
2152
+ Name : name ,
2065
2153
Path : semaPath ,
2066
2154
},
2067
2155
Elts : elements ,
0 commit comments