Skip to content

Commit c6e053a

Browse files
Method stabs for enums at SyntheticMethods
1 parent db92338 commit c6e053a

File tree

7 files changed

+43
-22
lines changed

7 files changed

+43
-22
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ object desugar {
544544
yield syntheticProperty(nme.selectorName(i), caseParams(i).tpt,
545545
Select(This(EmptyTypeIdent), caseParams(i).name))
546546
}
547-
def enumTagMeths = if (isEnumCase) enumTagMeth(CaseKind.Class)._1 :: Nil else Nil
547+
def ordinalMeths = if (isEnumCase) ordinalMeth(CaseKind.Class)._1 :: Nil else Nil
548548
def copyMeths = {
549549
val hasRepeatedParam = constrVparamss.exists(_.exists {
550550
case ValDef(_, tpt, _) => isRepeated(tpt)
@@ -581,7 +581,7 @@ object desugar {
581581
}
582582

583583
if (isCaseClass)
584-
productElemNameMeth :: copyMeths ::: enumTagMeths ::: productElemMeths
584+
productElemNameMeth :: copyMeths ::: ordinalMeths ::: productElemMeths
585585
else Nil
586586
}
587587

compiler/src/dotty/tools/dotc/ast/DesugarEnums.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,21 +102,21 @@ object DesugarEnums {
102102
/** A creation method for a value of enum type `E`, which is defined as follows:
103103
*
104104
* private def $new(tag: Int, name: String) = new E {
105-
* def enumTag = tag
105+
* def ordinal = tag
106106
* override def toString = name
107107
* $values.register(this)
108108
* }
109109
*/
110110
private def enumValueCreator(implicit ctx: Context) = {
111111
def param(name: TermName, typ: Type) =
112112
ValDef(name, TypeTree(typ), EmptyTree).withFlags(Param)
113-
val enumTagDef =
114-
DefDef(nme.enumTag, Nil, Nil, TypeTree(), Ident(nme.tag))
113+
val ordinalDef =
114+
DefDef(nme.ordinal, Nil, Nil, TypeTree(), Ident(nme.tag))
115115
val toStringDef =
116116
DefDef(nme.toString_, Nil, Nil, TypeTree(), Ident(nme.name))
117117
.withFlags(Override)
118118
def creator = New(Template(emptyConstructor, enumClassRef :: Nil, Nil, EmptyValDef,
119-
List(enumTagDef, toStringDef) ++ registerCall))
119+
List(ordinalDef, toStringDef) ++ registerCall))
120120
DefDef(nme.DOLLAR_NEW, Nil,
121121
List(List(param(nme.tag, defn.IntType), param(nme.name, defn.StringType))),
122122
TypeTree(), creator)
@@ -242,9 +242,9 @@ object DesugarEnums {
242242
* - a method returning the next enum tag
243243
* - scaffolding as defined in `nextEnumTag`
244244
*/
245-
def enumTagMeth(kind: CaseKind.Value)(implicit ctx: Context): (DefDef, List[Tree]) = {
245+
def ordinalMeth(kind: CaseKind.Value)(implicit ctx: Context): (DefDef, List[Tree]) = {
246246
val (tag, scaffolding) = nextEnumTag(kind)
247-
(DefDef(nme.enumTag, Nil, Nil, TypeTree(), Literal(Constant(tag))), scaffolding)
247+
(DefDef(nme.ordinal, Nil, Nil, TypeTree(), Literal(Constant(tag))), scaffolding)
248248
}
249249

250250
/** Expand a module definition representing a parameterless enum case */
@@ -257,7 +257,7 @@ object DesugarEnums {
257257
def toStringMeth =
258258
DefDef(nme.toString_, Nil, Nil, TypeTree(defn.StringType), Literal(Constant(name.toString)))
259259
.withFlags(Override)
260-
val (tagMeth, scaffolding) = enumTagMeth(CaseKind.Object)
260+
val (tagMeth, scaffolding) = ordinalMeth(CaseKind.Object)
261261
val impl1 = cpy.Template(impl)(body = List(tagMeth, toStringMeth) ++ registerCall)
262262
val vdef = ValDef(name, TypeTree(), New(impl1)).withMods(mods | Final)
263263
flatTree(scaffolding ::: vdef :: Nil).withSpan(span)
@@ -279,7 +279,7 @@ object DesugarEnums {
279279
def toStringMeth =
280280
DefDef(nme.toString_, Nil, Nil, TypeTree(defn.StringType), Literal(Constant(name.toString)))
281281
.withFlags(Override)
282-
val (tagMeth, scaffolding) = enumTagMeth(CaseKind.Object)
282+
val (tagMeth, scaffolding) = ordinalMeth(CaseKind.Object)
283283
val impl = Template(emptyConstructor, enumClassRef :: Nil, Nil, EmptyValDef,
284284
body = List(tagMeth, toStringMeth) ++ registerCall)
285285
val vdef = ValDef(name, TypeTree(), New(impl)).withMods(mods | Final)

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,6 @@ class Definitions {
597597
lazy val JavaSerializableClass: ClassSymbol = ctx.requiredClass("java.io.Serializable")
598598

599599
lazy val ComparableClass: ClassSymbol = ctx.requiredClass("java.lang.Comparable")
600-
601600
lazy val SystemClass: ClassSymbol = ctx.requiredClass("java.lang.System")
602601
lazy val SystemModule: Symbol = SystemClass.linkedClass
603602

@@ -670,6 +669,15 @@ class Definitions {
670669
def NoneClass(implicit ctx: Context): ClassSymbol = NoneModuleRef.symbol.moduleClass.asClass
671670
lazy val EnumType: TypeRef = ctx.requiredClassRef("scala.Enum")
672671
def EnumClass(implicit ctx: Context): ClassSymbol = EnumType.symbol.asClass
672+
lazy val Enum_nameR: TermRef = EnumClass.requiredMethodRef(nme.name)
673+
def Enum_name(implicit ctx: Context): Symbol = Enum_nameR.symbol
674+
lazy val Enum_getDeclaringClassR: TermRef = EnumClass.requiredMethodRef(nme.getDeclaringClass)
675+
def Enum_getDeclaringClass(implicit ctx: Context): Symbol = Enum_getDeclaringClassR.symbol
676+
lazy val Enum_ordinalR: TermRef = EnumClass.requiredMethodRef(nme.ordinal)
677+
def Enum_ordinal(implicit ctx: Context): Symbol = Enum_ordinalR.symbol
678+
lazy val Enum_compareToR: TermRef = EnumClass.requiredMethodRef(nme.compareTo)
679+
def Enum_compareTo(implicit ctx: Context): Symbol = Enum_compareToR.symbol
680+
673681
lazy val EnumValuesType: TypeRef = ctx.requiredClassRef("scala.runtime.EnumValues")
674682
def EnumValuesClass(implicit ctx: Context): ClassSymbol = EnumValuesType.symbol.asClass
675683
lazy val ProductType: TypeRef = ctx.requiredClassRef("scala.Product")

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,7 @@ object StdNames {
398398
val classOf: N = "classOf"
399399
val clone_ : N = "clone"
400400
val common: N = "common"
401+
val compareTo: N = "compareTo"
401402
val conforms_ : N = "$conforms"
402403
val copy: N = "copy"
403404
val currentMirror: N = "currentMirror"
@@ -412,7 +413,6 @@ object StdNames {
412413
val elem: N = "elem"
413414
val emptyValDef: N = "emptyValDef"
414415
val ensureAccessible : N = "ensureAccessible"
415-
val enumTag: N = "enumTag"
416416
val eq: N = "eq"
417417
val eqInstance: N = "eqInstance"
418418
val equalsNumChar : N = "equalsNumChar"
@@ -436,6 +436,7 @@ object StdNames {
436436
val genericClass: N = "genericClass"
437437
val get: N = "get"
438438
val getClass_ : N = "getClass"
439+
val getDeclaringClass: N = "getDeclaringClass"
439440
val getOrElse: N = "getOrElse"
440441
val hasNext: N = "hasNext"
441442
val hashCode_ : N = "hashCode"

compiler/src/dotty/tools/dotc/transform/SyntheticMethods.scala

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,18 +38,23 @@ class SyntheticMethods(thisPhase: DenotTransformer) {
3838
private[this] var myValueSymbols: List[Symbol] = Nil
3939
private[this] var myCaseSymbols: List[Symbol] = Nil
4040
private[this] var myCaseModuleSymbols: List[Symbol] = Nil
41+
private[this] var mySimpleEnumCaseSymbols: List[Symbol] = Nil
42+
4143

4244
private def initSymbols(implicit ctx: Context) =
4345
if (myValueSymbols.isEmpty) {
4446
myValueSymbols = List(defn.Any_hashCode, defn.Any_equals)
45-
myCaseSymbols = myValueSymbols ++ List(defn.Any_toString, defn.Product_canEqual,
47+
mySimpleEnumCaseSymbols = List(
48+
defn.Enum_name, defn.Enum_ordinal, defn.Enum_compareTo, defn.Enum_getDeclaringClass)
49+
myCaseSymbols = myValueSymbols ++ mySimpleEnumCaseSymbols ++ List(defn.Any_toString, defn.Product_canEqual,
4650
defn.Product_productArity, defn.Product_productPrefix, defn.Product_productElement)
4751
myCaseModuleSymbols = myCaseSymbols.filter(_ ne defn.Any_equals)
4852
}
4953

5054
def valueSymbols(implicit ctx: Context): List[Symbol] = { initSymbols; myValueSymbols }
5155
def caseSymbols(implicit ctx: Context): List[Symbol] = { initSymbols; myCaseSymbols }
5256
def caseModuleSymbols(implicit ctx: Context): List[Symbol] = { initSymbols; myCaseModuleSymbols }
57+
def simpleEnumCaseSymbols(implicit ctx: Context): List[Symbol] = { initSymbols; mySimpleEnumCaseSymbols }
5358

5459
/** If this is a case or value class, return the appropriate additional methods,
5560
* otherwise return nothing.
@@ -65,6 +70,7 @@ class SyntheticMethods(thisPhase: DenotTransformer) {
6570
if (clazz.is(Module)) caseModuleSymbols
6671
else caseSymbols
6772
}
73+
else if (clazz.owner.is(EnumCase)) simpleEnumCaseSymbols
6874
else if (isDerivedValueClass(clazz)) valueSymbols
6975
else Nil
7076

@@ -95,6 +101,12 @@ class SyntheticMethods(thisPhase: DenotTransformer) {
95101
case nme.productArity => vrefss => Literal(Constant(accessors.length))
96102
case nme.productPrefix => ownName
97103
case nme.productElement => vrefss => productElementBody(accessors.length, vrefss.head.head)
104+
105+
// Enum Methods
106+
case nme.name => _ => Literal(Constant("Hello World"))
107+
case nme.ordinal => _ => Literal(Constant(0))
108+
case nme.compareTo => _ => Literal(Constant(0))
109+
case nme.getDeclaringClass => _ => Literal(Constant(null))
98110
}
99111
ctx.log(s"adding $synthetic to $clazz at ${ctx.phase}")
100112
DefDef(synthetic, syntheticRHS(ctx.withOwner(synthetic))).withSpan(ctx.owner.span.focus)
@@ -293,5 +305,4 @@ class SyntheticMethods(thisPhase: DenotTransformer) {
293305
val clazz = ctx.owner.asClass
294306
cpy.Template(impl)(body = serializableObjectMethod(clazz) ::: caseAndValueMethods(clazz) ::: impl.body)
295307
}
296-
297308
}

library/src/scala/Enum.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package scala
22

33
/** A base trait of all enum classes */
4-
trait Enum {// extends Comparable[Enum] {
5-
// def getDeclaringClass: Class[_]
6-
// def name: String
7-
4+
trait Enum {
5+
def getDeclaringClass: Class[_]
6+
def name: String
7+
def ordinal: Int
8+
def compareTo(that: Enum): Int
89
/** A number uniquely identifying a case of an enum */
9-
def enumTag: Int
10-
// def ordinal: Int
10+
// def enumTag: Int
11+
// def name: String
1112
}

library/src/scala/runtime/EnumValues.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ class EnumValues[E <: Enum] {
77
private[this] var fromNameCache: Map[String, E] = null
88

99
def register(v: E) = {
10-
require(!myMap.contains(v.enumTag))
11-
myMap = myMap.updated(v.enumTag, v)
10+
require(!myMap.contains(v.ordinal))
11+
myMap = myMap.updated(v.ordinal, v)
1212
fromNameCache = null
1313
}
1414

0 commit comments

Comments
 (0)