1
+ import reflect .Selectable .reflectiveSelectable
2
+ import deriving .Mirror
3
+
1
4
enum Color :
2
5
case Red , Green , Blue
3
6
4
7
enum Tag [T ]:
5
8
case Int extends Tag [Int ]
9
+ case OfClass [T ]()(using val tag : reflect.ClassTag [T ]) extends Tag [T ] // mix order of class and value
6
10
case String extends Tag [String ]
7
- case OfClass [T ]()(using val tag : reflect.ClassTag [T ]) extends Tag [T ]
8
11
9
12
enum Expr [- T >: Null ]:
10
13
case EmptyTree extends Expr [Null ]
@@ -16,18 +19,55 @@ enum ListLike[+T]:
16
19
17
20
enum TypeCtorsK [F [_]]:
18
21
case List extends TypeCtorsK [List ]
22
+ case Const [T ]() extends TypeCtorsK [[U ] =>> T ] // mix order of class and value
19
23
case Option extends TypeCtorsK [Option ]
20
- case Const [T ]() extends TypeCtorsK [[U ] =>> T ]
21
24
22
25
enum MixedParams [F [_], G [X ,Y ] <: collection.Map [X ,Y ], T ]:
23
26
case Foo extends MixedParams [List , collection.mutable.LinkedHashMap , Unit ]
24
27
28
+ enum ClassOnly : // this should still generate the `ordinal` and `fromOrdinal` companion methods
29
+ case BranchProd (i : Int )
30
+
25
31
@ main def Test : Unit =
26
- import Color ._ , Tag ._ , Expr ._ , ListLike ._ , TypeCtorsK ._ , MixedParams ._
27
- import reflect .Selectable .reflectiveSelectable
32
+ import Color ._ , Tag ._ , Expr ._ , ListLike ._ , TypeCtorsK ._ , MixedParams ._ , ClassOnly ._
33
+
34
+ type FromOrdinal [T <: AnyRef ] = {
35
+ def fromOrdinal (ordinal : Int ): T
36
+ }
37
+
38
+ type ValueOf [T <: AnyRef ] = {
39
+ def valueOf (s : String ): T
40
+ }
28
41
29
42
extension [A ](t : A ) def show = runtime.ScalaRunTime .stringOf(t)
30
43
44
+ def fetchFromOrdinal [T <: AnyRef & reflect.Enum ](companion : FromOrdinal [T ], compare : T * ): Unit =
45
+ for c <- compare do
46
+ assert(companion.fromOrdinal(c.ordinal) eq c,
47
+ s " $c does not `eq` companion.fromOrdinal( ${c.ordinal}), got ${companion.fromOrdinal(c.ordinal)}" )
48
+
49
+ def notFromOrdinal [T <: AnyRef & reflect.Enum ](companion : FromOrdinal [T ], compare : T ): Unit =
50
+ try
51
+ companion.fromOrdinal(compare.ordinal)
52
+ assertFail(s " $companion.fromOrdinal( ${compare.ordinal}) did not fail " )
53
+ catch
54
+ case e : java.lang.reflect.InvocationTargetException => // TODO: maybe reflect.Selectable should catch this?
55
+ assert(e.getCause.isInstanceOf [java.util.NoSuchElementException ]
56
+ && e.getCause.getMessage == compare.ordinal.toString)
57
+
58
+ fetchFromOrdinal(companion = Color , compare = Red , Green , Blue )
59
+ fetchFromOrdinal(companion = Tag , compare = Int , String )
60
+ fetchFromOrdinal(companion = Expr , compare = EmptyTree , AnyTree )
61
+ fetchFromOrdinal(companion = ListLike , compare = EmptyListLike )
62
+ fetchFromOrdinal(companion = TypeCtorsK , compare = List , Option )
63
+ fetchFromOrdinal(companion = MixedParams , compare = Foo )
64
+
65
+ notFromOrdinal(companion = Tag , compare = OfClass [String ]())
66
+ notFromOrdinal(companion = TypeCtorsK , compare = Const [String ]())
67
+ notFromOrdinal(companion = ClassOnly , compare = BranchProd (1 )) // ClassOnly has the `fromOrdinal` method
68
+
69
+ assert(summon[Mirror .SumOf [ClassOnly ]].ordinal(BranchProd (1 )) == 0 )
70
+
31
71
val colors : Array [Color ] = Color .values
32
72
val tags : Array [Tag [? ]] = Tag .values
33
73
val exprs : Array [Expr [? >: Null ]] = Expr .values
@@ -46,7 +86,7 @@ enum MixedParams[F[_], G[X,Y] <: collection.Map[X,Y], T]:
46
86
sameAs(typeCtorsK, List , Option )
47
87
sameAs(mixedParams, Foo )
48
88
49
- def singleton [E <: AnyRef ](value : E , name : String , companion : { def valueOf ( s : String ) : E } ) =
89
+ def singleton [E <: AnyRef ](value : E , name : String , companion : ValueOf [ E ] ) =
50
90
val lookup = companion.valueOf(name)
51
91
assert(value eq lookup, s " ${value.show} is not identical to ${lookup.show}" )
52
92
0 commit comments