Skip to content

Commit 3e08142

Browse files
Merge pull request #8008 from dotty-staging/fix-7991
Fix #7991: don't set JavaDefined for Dotty Enum module class
2 parents 1cff48f + e05e2b7 commit 3e08142

20 files changed

+86
-11
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ class Compiler {
5858
new CheckReentrant, // Internal use only: Check that compiled program has no data races involving global vars
5959
new ElimPackagePrefixes, // Eliminate references to package prefixes in Select nodes
6060
new CookComments, // Cook the comments: expand variables, doc, etc.
61-
new CompleteJavaEnums) :: // Fill in constructors for Java enums
62-
List(new CheckStatic, // Check restrictions that apply to @static members
61+
new CheckStatic) :: // Check restrictions that apply to @static members
62+
List(new CompleteJavaEnums, // Fill in constructors for Java enums
6363
new ElimRepeated, // Rewrite vararg parameters and arguments
6464
new ExpandSAMs, // Expand single abstract method closures to anonymous classes
6565
new ProtectedAccessors, // Add accessors for protected members

compiler/src/dotty/tools/dotc/core/classfile/ClassfileConstants.scala

+1
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,7 @@ object ClassfileConstants {
343343
case JAVA_ACC_FINAL => Final
344344
case JAVA_ACC_SYNTHETIC => Synthetic
345345
case JAVA_ACC_STATIC => JavaStatic
346+
case JAVA_ACC_ENUM => Enum
346347
case JAVA_ACC_ABSTRACT => if (isClass) Abstract else Deferred
347348
case JAVA_ACC_INTERFACE => PureInterfaceCreationFlags | JavaDefined
348349
case _ => EmptyFlags

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

+1-3
Original file line numberDiff line numberDiff line change
@@ -200,12 +200,10 @@ class ClassfileParser(
200200
sym.markAbsent()
201201
}
202202

203-
// eager load java enum definitions for exhaustivity check of pattern match
203+
// eager load enum definitions for exhaustivity check of pattern match
204204
if (isEnum) {
205205
instanceScope.toList.map(_.ensureCompleted())
206206
staticScope.toList.map(_.ensureCompleted())
207-
classRoot.setFlag(Flags.JavaEnumTrait)
208-
moduleRoot.setFlag(Flags.JavaEnumTrait)
209207
}
210208

211209
result

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

+16-6
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,20 @@ class CompleteJavaEnums extends MiniPhase with InfoTransformer { thisPhase =>
110110
else tree
111111
}
112112

113-
override def transformValDef(tree: ValDef)(implicit ctx: Context): ValDef = {
114-
val sym = tree.symbol
115-
if ((sym.isAllOf(EnumValue) || sym.name == nme.DOLLAR_VALUES) && sym.owner.linkedClass.derivesFromJavaEnum)
116-
sym.addAnnotation(Annotations.Annotation(defn.ScalaStaticAnnot))
117-
tree
113+
/** Return a list of forwarders for enum values defined in the companion object
114+
* for java interop.
115+
*/
116+
private def addedEnumForwarders(clazz: Symbol)(implicit ctx: Context): List[ValDef] = {
117+
val moduleCls = clazz.companionClass
118+
val moduleRef = ref(clazz.companionModule)
119+
120+
val enums = moduleCls.info.decls.filter(member => member.isAllOf(EnumValue))
121+
for { enumValue <- enums }
122+
yield {
123+
val fieldSym = ctx.newSymbol(clazz, enumValue.name.asTermName, EnumValue | JavaStatic, enumValue.info)
124+
fieldSym.addAnnotation(Annotations.Annotation(defn.ScalaStaticAnnot))
125+
ValDef(fieldSym, moduleRef.select(enumValue))
126+
}
118127
}
119128

120129
/** 1. If this is an enum class, add $name and $ordinal parameters to its
@@ -143,9 +152,10 @@ class CompleteJavaEnums extends MiniPhase with InfoTransformer { thisPhase =>
143152
val (params, rest) = decomposeTemplateBody(templ.body)
144153
val addedDefs = addedParams(cls, ParamAccessor)
145154
val addedSyms = addedDefs.map(_.symbol.entered)
155+
val addedForwarders = addedEnumForwarders(cls)
146156
cpy.Template(templ)(
147157
parents = addEnumConstrArgs(defn.JavaEnumClass, templ.parents, addedSyms.map(ref)),
148-
body = params ++ addedDefs ++ rest)
158+
body = params ++ addedDefs ++ addedForwarders ++ rest)
149159
}
150160
else if (cls.isAnonymousClass && cls.owner.isAllOf(EnumCase) && cls.owner.owner.linkedClass.derivesFromJavaEnum) {
151161
def rhsOf(name: TermName) =

compiler/test-resources/repl/i7410

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
scala> enum E { case A, B, C }
2+
// defined class E
3+
scala> E.A
4+
val res0: E = A

tests/run/i6664/Bomb_1.scala

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
enum Bomb
2+
{
3+
case Kaboom
4+
}

tests/run/i6664/Detonator_2.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test
2+
{
3+
def boom: Unit = Bomb.valueOf("Kaboom")
4+
def main(args: Array[String]): Unit = println("ok!")
5+
}

tests/run/i6664b/Bomb_1.scala

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
enum Bomb extends java.lang.Enum[Bomb]
2+
{
3+
case Kaboom
4+
}

tests/run/i6664b/Detonator_2.scala

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
object Test
2+
{
3+
def main(args: Array[String]): Unit = println(Bomb.Kaboom)
4+
}

tests/run/i6677/Enum_1.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
enum Foo[A] {
2+
case Bar extends Foo[Int]
3+
}

tests/run/i6677/Test_2.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
println(Foo.Bar)
4+
}
5+
}

tests/run/i7287/Enum_1.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
enum Color derives Eql {
2+
case Unknown
3+
case Blue(v: Int)
4+
case Red(v: Int)
5+
}

tests/run/i7287/Test_2.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
val testData = Seq(("blah", Color.Unknown), ("red", Color.Red(10)))
4+
println(testData)
5+
}
6+
}

tests/run/i7410/Enum_1.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
enum E {
2+
case A, B, C
3+
}

tests/run/i7410/Test_2.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
val a = E.A
4+
println(a)
5+
}
6+
}

tests/run/i7424/Enum_1.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
enum A {
2+
case A1
3+
}

tests/run/i7424/Test_2.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
println(A.values)
4+
}
5+
}

tests/run/i7991.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
enum Num { case One }
2+
3+
object Test extends App {
4+
Num.One
5+
}

tests/run/i7991/Num_1.scala

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
enum Num { case One }

tests/run/i7991/Test_2.scala

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
object Test extends App {
2+
Num.One
3+
}

0 commit comments

Comments
 (0)