summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-07-01 21:31:21 +0000
committerPaul Phillips <paulp@improving.org>2010-07-01 21:31:21 +0000
commit60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be (patch)
treeb7ec7ae608398cd9b58a364c0417c12f4818c435
parent74eb6b70d58f7f2c3839fb69bc57ffcd00361839 (diff)
downloadscala-60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be.tar.gz
scala-60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be.tar.bz2
scala-60a7e53a5f7abbde3237aa1a1d2a90ff5e0818be.zip
Took a cue from mharrah that we don't need to b...
Took a cue from mharrah that we don't need to build global static data to keep track of something when we know where it's kept. Altered the Enumeration deserialization scheme to use reflection, preserving the singleton property by delivering the MODULE$ singleton. This solves the GC issue and lets us drop synchronization to boot. Also added some graceful failure for malformed Enumerations. All tests look good but a second opinion is in order: closes #2214, review by phaller.
-rw-r--r--src/library/scala/Enumeration.scala29
1 files changed, 7 insertions, 22 deletions
diff --git a/src/library/scala/Enumeration.scala b/src/library/scala/Enumeration.scala
index 333c6354c0..c7c247fed7 100644
--- a/src/library/scala/Enumeration.scala
+++ b/src/library/scala/Enumeration.scala
@@ -6,22 +6,12 @@
** |/ **
\* */
-
-
package scala
import scala.collection.SetLike
import scala.collection.{ mutable, immutable, generic }
import java.lang.reflect.{ Modifier, Method => JMethod, Field => JField }
-
-private object Enumeration {
-
- /* This map is used to cache enumeration instances for
- resolving enumeration _values_ to equal objects (by-reference)
- when values are deserialized. */
- private val emap: mutable.Map[Class[_], Enumeration] = new mutable.HashMap
-
-}
+import java.util.NoSuchElementException
/** <p>
* Defines a finite set of values specific to the enumeration. Typically
@@ -69,14 +59,9 @@ abstract class Enumeration(initial: Int, names: String*) {
def this() = this(0, null)
def this(names: String*) = this(0, names: _*)
- /* Populates emap with this instance */
- readResolve()
-
/* Note that `readResolve` cannot be private, since otherwise
the JVM does not invoke it when deserializing subclasses. */
- protected def readResolve(): AnyRef = Enumeration.synchronized {
- Enumeration.emap.getOrElseUpdate(getClass, this)
- }
+ protected def readResolve(): AnyRef = thisenum.getClass.getField("MODULE$").get()
/** The name of this enumeration.
*/
@@ -246,12 +231,12 @@ abstract class Enumeration(initial: Int, names: String*) {
if (nextId > topId) topId = nextId
def id = i
override def toString() =
- if (name == null) thisenum.nameOf(i)
- else name
+ if (name != null) name
+ else try thisenum.nameOf(i)
+ catch { case _: NoSuchElementException => "<Invalid enum: no field for #" + i + ">" }
+
protected def readResolve(): AnyRef = {
- val enum = Enumeration.synchronized {
- Enumeration.emap.getOrElse(thisenum.getClass, thisenum)
- }
+ val enum = thisenum.readResolve().asInstanceOf[Enumeration]
if (enum.vmap == null) this
else enum.vmap(i)
}