@@ -34,7 +34,8 @@ object DesugarEnums {
34
34
}
35
35
36
36
/** Type parameters reconstituted from the constructor
37
- * of the `enum' class corresponding to an enum case
37
+ * of the `enum' class corresponding to an enum case.
38
+ * The variance is the same as the corresponding type parameter of the enum class.
38
39
*/
39
40
def reconstitutedEnumTypeParams (pos : Position )(implicit ctx : Context ) = {
40
41
val tparams = enumClass.primaryConstructor.info match {
@@ -43,11 +44,11 @@ object DesugarEnums {
43
44
case _ =>
44
45
Nil
45
46
}
46
- for (tparam <- tparams) yield {
47
+ (tparams, enumClass.typeParams).zipped.map { (tparam, ecTparam) =>
47
48
val tbounds = new DerivedFromParamTree
48
49
tbounds.pushAttachment(OriginalSymbol , tparam)
49
50
TypeDef (tparam.name, tbounds)
50
- .withFlags(Param | PrivateLocal ).withPos(pos)
51
+ .withFlags(Param | PrivateLocal | ecTparam.flags & VarianceFlags ).withPos(pos)
51
52
}
52
53
}
53
54
@@ -64,7 +65,8 @@ object DesugarEnums {
64
65
/** The following lists of definitions for an enum type E:
65
66
*
66
67
* private val $values = new EnumValues[E]
67
- * def valueOf: Int => E = $values
68
+ * def valueOf = $values.fromInt
69
+ * def withName = $values.fromName
68
70
* def values = $values.values
69
71
*
70
72
* private def $new(tag: Int, name: String) = new E {
@@ -74,32 +76,32 @@ object DesugarEnums {
74
76
* }
75
77
*/
76
78
private def enumScaffolding (implicit ctx : Context ): List [Tree ] = {
77
- val valsRef = Ident (nme.DOLLAR_VALUES )
79
+ def valuesDot (name : String ) = Select (Ident (nme.DOLLAR_VALUES ), name.toTermName)
80
+ def enumDefDef (name : String , select : String ) =
81
+ DefDef (name.toTermName, Nil , Nil , TypeTree (), valuesDot(select))
78
82
def param (name : TermName , typ : Type ) =
79
83
ValDef (name, TypeTree (typ), EmptyTree ).withFlags(Param )
80
84
val privateValuesDef =
81
85
ValDef (nme.DOLLAR_VALUES , TypeTree (),
82
86
New (TypeTree (defn.EnumValuesType .appliedTo(enumClass.typeRef :: Nil )), ListOfNil ))
83
87
.withFlags(Private )
84
- val valueOfDef =
85
- DefDef (nme.valueOf, Nil , Nil ,
86
- TypeTree (defn.FunctionOf (defn.IntType :: Nil , enumClass.typeRef)), valsRef)
87
- val valuesDef =
88
- DefDef (nme.values, Nil , Nil , TypeTree (), Select (valsRef, nme.values))
88
+ val valueOfDef = enumDefDef(" valueOf" , " fromInt" )
89
+ val withNameDef = enumDefDef(" withName" , " fromName" )
90
+ val valuesDef = enumDefDef(" values" , " values" )
89
91
val enumTagDef =
90
92
DefDef (nme.enumTag, Nil , Nil , TypeTree (), Ident (nme.tag))
91
93
val toStringDef =
92
94
DefDef (nme.toString_, Nil , Nil , TypeTree (), Ident (nme.name))
93
95
.withFlags(Override )
94
96
val registerStat =
95
- Apply (Select (valsRef, nme. register), This (EmptyTypeIdent ) :: Nil )
97
+ Apply (valuesDot( " register" ), This (EmptyTypeIdent ) :: Nil )
96
98
def creator = New (Template (emptyConstructor, enumClassRef :: Nil , EmptyValDef ,
97
99
List (enumTagDef, toStringDef, registerStat)))
98
100
val newDef =
99
101
DefDef (nme.DOLLAR_NEW , Nil ,
100
102
List (List (param(nme.tag, defn.IntType ), param(nme.name, defn.StringType ))),
101
103
TypeTree (), creator)
102
- List (privateValuesDef, valueOfDef, valuesDef, newDef)
104
+ List (privateValuesDef, valueOfDef, withNameDef, valuesDef, newDef)
103
105
}
104
106
105
107
def expandEnumModule (name : TermName , impl : Template , mods : Modifiers , pos : Position )(implicit ctx : Context ): Tree = {
0 commit comments