diff options
author | Lukas Rytz <lukas.rytz@typesafe.com> | 2014-07-15 18:37:04 +0200 |
---|---|---|
committer | Lukas Rytz <lukas.rytz@typesafe.com> | 2014-07-15 18:37:04 +0200 |
commit | 174cf45735cd5ca54223b2a353a92e472aeb2324 (patch) | |
tree | 4d1b2bd5f46b4708deb2ee48368a398d4f3e680e /src/reflect | |
parent | 41491b081421989e15d7bbfb7a97c0e7669ad1d9 (diff) | |
parent | f15a289ec5c192ced30970bd9ab23cbf38ead92e (diff) | |
download | scala-174cf45735cd5ca54223b2a353a92e472aeb2324.tar.gz scala-174cf45735cd5ca54223b2a353a92e472aeb2324.tar.bz2 scala-174cf45735cd5ca54223b2a353a92e472aeb2324.zip |
Merge pull request #3817 from phaller/topic/typetags
SI-5919 TypeTags and Exprs should be serializable
Diffstat (limited to 'src/reflect')
-rw-r--r-- | src/reflect/scala/reflect/api/Exprs.scala | 23 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/TreeCreator.scala | 6 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/TypeCreator.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/api/TypeTags.scala | 39 |
4 files changed, 42 insertions, 28 deletions
diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/reflect/scala/reflect/api/Exprs.scala index 5b6ff2325c..3230fdbc67 100644 --- a/src/reflect/scala/reflect/api/Exprs.scala +++ b/src/reflect/scala/reflect/api/Exprs.scala @@ -9,6 +9,7 @@ package api import scala.reflect.runtime.{universe => ru} import scala.annotation.compileTimeOnly +import java.io.ObjectStreamException /** * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span> @@ -157,23 +158,23 @@ trait Exprs { self: Universe => |if you want to get a value of the underlying expression, add scala-compiler.jar to the classpath, |import `scala.tools.reflect.Eval` and call `<your expr>.eval` instead.""".trim.stripMargin) + @throws(classOf[ObjectStreamException]) private def writeReplace(): AnyRef = new SerializedExpr(treec, implicitly[WeakTypeTag[T]].in(ru.rootMirror)) } } +@SerialVersionUID(1L) private[scala] class SerializedExpr(var treec: TreeCreator, var tag: ru.WeakTypeTag[_]) extends Serializable { - private def writeObject(out: java.io.ObjectOutputStream): Unit = { - out.writeObject(treec) - out.writeObject(tag) - } - - private def readObject(in: java.io.ObjectInputStream): Unit = { - treec = in.readObject().asInstanceOf[TreeCreator] - tag = in.readObject().asInstanceOf[ru.WeakTypeTag[_]] - } + import scala.reflect.runtime.universe.{Expr, runtimeMirror} + @throws(classOf[ObjectStreamException]) private def readResolve(): AnyRef = { - import ru._ - Expr(rootMirror, treec)(tag) + val loader: ClassLoader = try { + Thread.currentThread().getContextClassLoader() + } catch { + case se: SecurityException => null + } + val m = runtimeMirror(loader) + Expr(m, treec)(tag.in(m)) } } diff --git a/src/reflect/scala/reflect/api/TreeCreator.scala b/src/reflect/scala/reflect/api/TreeCreator.scala index 027c840955..000eaa1aa6 100644 --- a/src/reflect/scala/reflect/api/TreeCreator.scala +++ b/src/reflect/scala/reflect/api/TreeCreator.scala @@ -2,12 +2,12 @@ package scala package reflect package api -/** This is an internal implementation class. +/** A mirror-aware factory for trees. * * This class is used internally by Scala Reflection, and is not recommended for use in client code. * - * @group ReflectionAPI + * @group ReflectionAPI */ -abstract class TreeCreator { +abstract class TreeCreator extends Serializable { def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Tree } diff --git a/src/reflect/scala/reflect/api/TypeCreator.scala b/src/reflect/scala/reflect/api/TypeCreator.scala index 37fff90b43..cbd55b9428 100644 --- a/src/reflect/scala/reflect/api/TypeCreator.scala +++ b/src/reflect/scala/reflect/api/TypeCreator.scala @@ -8,6 +8,6 @@ package api * * @group ReflectionAPI */ -abstract class TypeCreator { +abstract class TypeCreator extends Serializable { def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Type } diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala index 1dfc84be69..7db375ca61 100644 --- a/src/reflect/scala/reflect/api/TypeTags.scala +++ b/src/reflect/scala/reflect/api/TypeTags.scala @@ -9,6 +9,7 @@ package api import java.lang.{ Class => jClass } import scala.language.implicitConversions +import java.io.ObjectStreamException /** * A `TypeTag[T]` encapsulates the runtime type representation of some type `T`. @@ -233,6 +234,7 @@ trait TypeTags { self: Universe => val otherMirror1 = otherMirror.asInstanceOf[scala.reflect.api.Mirror[otherMirror.universe.type]] otherMirror.universe.WeakTypeTag[T](otherMirror1, tpec) } + @throws(classOf[ObjectStreamException]) private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = false) } @@ -293,10 +295,13 @@ trait TypeTags { self: Universe => val otherMirror1 = otherMirror.asInstanceOf[scala.reflect.api.Mirror[otherMirror.universe.type]] otherMirror.universe.TypeTag[T](otherMirror1, tpec) } + @throws(classOf[ObjectStreamException]) private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true) } /* @group TypeTags */ + // This class only exists to silence MIMA complaining about a binary incompatibility. + // Only the top-level class (api.PredefTypeCreator) should be used. private class PredefTypeCreator[T](copyIn: Universe => Universe#TypeTag[T]) extends TypeCreator { def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Type = { copyIn(m.universe).asInstanceOf[U # TypeTag[T]].tpe @@ -304,8 +309,9 @@ trait TypeTags { self: Universe => } /* @group TypeTags */ - private class PredefTypeTag[T](_tpe: Type, copyIn: Universe => Universe#TypeTag[T]) extends TypeTagImpl[T](rootMirror, new PredefTypeCreator(copyIn)) { + private class PredefTypeTag[T](_tpe: Type, copyIn: Universe => Universe#TypeTag[T]) extends TypeTagImpl[T](rootMirror, new api.PredefTypeCreator(copyIn)) { override lazy val tpe: Type = _tpe + @throws(classOf[ObjectStreamException]) private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true) } @@ -341,20 +347,27 @@ trait TypeTags { self: Universe => def symbolOf[T: WeakTypeTag]: TypeSymbol } +// This class should be final, but we can't do that in Scala 2.11.x without breaking +// binary incompatibility. +@SerialVersionUID(1L) private[scala] class SerializedTypeTag(var tpec: TypeCreator, var concrete: Boolean) extends Serializable { - private def writeObject(out: java.io.ObjectOutputStream): Unit = { - out.writeObject(tpec) - out.writeBoolean(concrete) - } - - private def readObject(in: java.io.ObjectInputStream): Unit = { - tpec = in.readObject().asInstanceOf[TypeCreator] - concrete = in.readBoolean() + import scala.reflect.runtime.universe.{TypeTag, WeakTypeTag, runtimeMirror} + @throws(classOf[ObjectStreamException]) + private def readResolve(): AnyRef = { + val loader: ClassLoader = try { + Thread.currentThread().getContextClassLoader() + } catch { + case se: SecurityException => null + } + val m = runtimeMirror(loader) + if (concrete) TypeTag(m, tpec) + else WeakTypeTag(m, tpec) } +} - private def readResolve(): AnyRef = { - import scala.reflect.runtime.universe._ - if (concrete) TypeTag(rootMirror, tpec) - else WeakTypeTag(rootMirror, tpec) +/* @group TypeTags */ +private class PredefTypeCreator[T](copyIn: Universe => Universe#TypeTag[T]) extends TypeCreator { + def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Type = { + copyIn(m.universe).asInstanceOf[U # TypeTag[T]].tpe } } |