New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enumerations Sometimes Fail To Correctly Populate The Name of Values #5147
Comments
Imported From: https://issues.scala-lang.org/browse/SI-5147?orig=1 |
@soc said: This class has been bug-ridden since I started to work with Scala and has a highly disproportional ratio of LOC/bugs. It is not even used in Scala at all except one occurrence in Scala Swing afaik. Most code in the wild doesn't even bother using it and takes the expensive route of abstract class Foo
object Foo1
object Foo2
... instead. I don't have any hopes left that this functionality doesn't keep breaking like it did in the past. Maybe it would be better to tell people to define enums in Java instead (as it is already done for runtime-visible annotations) and deprecate/remove this class? |
@paulp said: Without necessarily disagreeing with the idea that Enumeration should be marked for death:
|
Turing Eret (turingeret) said: @@ -157,10 +157,14 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable {
protected final def Value(i: Int, name: String): Value = new Val(i, name)
private def populateNameMap() {
+ val fields = getClass.getDeclaredFields
+ def isValDef(m: JMethod) = fields exists (fd => fd.getName == m.getName && fd.getType == m.getReturnType)
+
// The list of possible Value methods: 0-args which return a conforming type
val methods = getClass.getMethods filter (m => m.getParameterTypes.isEmpty &&
classOf[Value].isAssignableFrom(m.getReturnType) &&
- m.getDeclaringClass != classOf[Enumeration])
+ m.getDeclaringClass != classOf[Enumeration] &&
+ isValDef(m)) The problem is that isValDef only checks to see if it is a val defined in the current class. If you extends from a class where the actual enumeration value is defined, then it won't find it. The following diff seems to fix this issue: diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala
index 45cb3a6..30bb274 100644
--- a/src/library/scala/Enumeration.scala
+++ b/src/library/scala/Enumeration.scala
@@ -161,7 +161,10 @@ abstract class Enumeration(initial: Int, names: String*) extends Serializable {
protected final def Value(i: Int, name: String): Value = new Val(i, name)
private def populateNameMap() {
- val fields = getClass.getDeclaredFields
+ def getFields(clazz: Class[_]) : Array[JField] = {
+ clazz.getDeclaredFields ++ (if(clazz.getSuperclass != null) getFields(clazz.getSuperclass) else Nil)
+ }
+ val fields = getFields(getClass)
def isValDef(m: JMethod) = fields exists (fd => fd.getName == m.getName && fd.getType == m.getReturnType)
// The list of possible Value methods: 0-args which return a conforming type
diff --git a/test/files/run/t5147.check b/test/files/run/t5147.check
new file mode 100644
index 0000000..f70f10e
--- /dev/null
+++ b/test/files/run/t5147.check
@@ -0,0 +1 @@
+A
diff --git a/test/files/run/t5147.scala b/test/files/run/t5147.scala
new file mode 100644
index 0000000..6261336
--- /dev/null
+++ b/test/files/run/t5147.scala
@@ -0,0 +1,9 @@
+class Test extends Enumeration {
+ val A = Value
+}
+object Test extends Test
+object Test5147 {
+ def main(args: Array[String]): Unit = {
+ println(Test.A)
+ }
+} |
@paulp said: |
Turing Eret (turingeret) said: |
@paulp said: |
Trond Olsen (tolsen77) said: |
If you have a class that extends Enumeration that defines the actual Enumeration and then have a companion object extends from that class, the string values of the enumeration values is improperly handled. For example:
...and then you try to print Foo.A, it'll print "<Invalid enum: no field for #0>" rather than "A".
The text was updated successfully, but these errors were encountered: