summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Burmako <xeno.by@gmail.com>2012-07-31 14:14:01 +0200
committerEugene Burmako <xeno.by@gmail.com>2012-08-02 15:51:30 +0200
commita354ec2a77f83f57680c576758ddfa9234083b9e (patch)
treec0090d6f6ab663b8c3845838f3a9e96f25168f29
parenta19f0e83bf18a435bac9c984781f66ac3d94822c (diff)
downloadscala-a354ec2a77f83f57680c576758ddfa9234083b9e.tar.gz
scala-a354ec2a77f83f57680c576758ddfa9234083b9e.tar.bz2
scala-a354ec2a77f83f57680c576758ddfa9234083b9e.zip
first stab at serialization of exprs and tags
Instead of trying to serialize the entire universe and failing miserably (which happens now), exprs and type tags will now serialize their creators and deserialize into scala.reflect.basis. Since creators produced by reification are not serializable right now, serialization will crash. That's a small improvement over state of the art functionality-wise, but it's a step forward robustness-wise. Next step in this direction is generation of serialization code for creators. Related issues: SI-5919 and SI-5908. Also see the discussion at scala-internals http://groups.google.com/group/scala-internals/browse_thread/thread/ef63f8b5bd194c7c
-rw-r--r--src/library/scala/reflect/base/Exprs.scala19
-rw-r--r--src/library/scala/reflect/base/TypeTags.scala32
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala1
-rw-r--r--test/files/run/abstypetags_serialize.check2
-rw-r--r--test/files/run/abstypetags_serialize.scala32
-rw-r--r--test/files/run/exprs_serialize.check2
-rw-r--r--test/files/run/exprs_serialize.scala28
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled.check5
-rw-r--r--test/files/run/macro-typecheck-macrosdisabled2.check5
-rw-r--r--test/files/run/toolbox_typecheck_macrosdisabled.check5
-rw-r--r--test/files/run/toolbox_typecheck_macrosdisabled2.check5
-rw-r--r--test/files/run/typetags_serialize.check2
-rw-r--r--test/files/run/typetags_serialize.scala28
13 files changed, 141 insertions, 25 deletions
diff --git a/src/library/scala/reflect/base/Exprs.scala b/src/library/scala/reflect/base/Exprs.scala
index a92860f558..8e429afb21 100644
--- a/src/library/scala/reflect/base/Exprs.scala
+++ b/src/library/scala/reflect/base/Exprs.scala
@@ -56,5 +56,24 @@ trait Exprs { self: Universe =>
|if you want to splice the underlying expression, use `<your expr>.splice`.
|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)
+
+ private def writeReplace(): AnyRef = new SerializedExpr(treec, implicitly[AbsTypeTag[T]].in(scala.reflect.basis.rootMirror))
+ }
+}
+
+private[scala] class SerializedExpr(var treec: TreeCreator, var tag: scala.reflect.basis.AbsTypeTag[_]) 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[scala.reflect.basis.AbsTypeTag[_]]
+ }
+
+ private def readResolve(): AnyRef = {
+ import scala.reflect.basis._
+ Expr(rootMirror, treec)(tag)
}
} \ No newline at end of file
diff --git a/src/library/scala/reflect/base/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala
index 05b1a079d7..3f7024366e 100644
--- a/src/library/scala/reflect/base/TypeTags.scala
+++ b/src/library/scala/reflect/base/TypeTags.scala
@@ -169,6 +169,7 @@ trait TypeTags { self: Universe =>
val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
otherMirror.universe.AbsTypeTag[T](otherMirror1, tpec)
}
+ private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = false)
}
/**
@@ -233,13 +234,18 @@ trait TypeTags { self: Universe =>
val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
otherMirror.universe.TypeTag[T](otherMirror1, tpec)
}
+ private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true)
}
- private class PredefTypeTag[T](_tpe: Type, copyIn: Universe => Universe # TypeTag[T]) extends TypeTagImpl[T](rootMirror, null) {
+ private class PredefTypeCreator[T](copyIn: Universe => Universe # TypeTag[T]) extends TypeCreator {
+ def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type = {
+ copyIn(m.universe).asInstanceOf[U # TypeTag[T]].tpe
+ }
+ }
+
+ private class PredefTypeTag[T](_tpe: Type, copyIn: Universe => Universe # TypeTag[T]) extends TypeTagImpl[T](rootMirror, new PredefTypeCreator(copyIn)) {
override lazy val tpe: Type = _tpe
- override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] =
- copyIn(otherMirror.universe).asInstanceOf[U # TypeTag[T]]
- private def readResolve() = copyIn(self)
+ private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true)
}
// incantations
@@ -248,3 +254,21 @@ trait TypeTags { self: Universe =>
// big thanks to Viktor Klang for this brilliant idea!
def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
}
+
+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()
+ }
+
+ private def readResolve(): AnyRef = {
+ import scala.reflect.basis._
+ if (concrete) TypeTag(rootMirror, tpec)
+ else AbsTypeTag(rootMirror, tpec)
+ }
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 133b035228..67456cf86b 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -616,7 +616,6 @@ trait StdNames {
val apply: NameType = "apply"
val applyDynamic: NameType = "applyDynamic"
val applyDynamicNamed: NameType = "applyDynamicNamed"
- val applyImpl: NameType = "applyImpl"
val applyOrElse: NameType = "applyOrElse"
val args : NameType = "args"
val argv : NameType = "argv"
diff --git a/test/files/run/abstypetags_serialize.check b/test/files/run/abstypetags_serialize.check
new file mode 100644
index 0000000000..aafb4761ad
--- /dev/null
+++ b/test/files/run/abstypetags_serialize.check
@@ -0,0 +1,2 @@
+java.io.NotSerializableException: Test$$typecreator1$1
+java.io.NotSerializableException: Test$$typecreator2$1
diff --git a/test/files/run/abstypetags_serialize.scala b/test/files/run/abstypetags_serialize.scala
new file mode 100644
index 0000000000..5b9142f6d5
--- /dev/null
+++ b/test/files/run/abstypetags_serialize.scala
@@ -0,0 +1,32 @@
+import java.io._
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ def test(tag: AbsTypeTag[_]) =
+ try {
+ val fout = new ByteArrayOutputStream()
+ val out = new ObjectOutputStream(fout)
+ out.writeObject(tag)
+ out.close()
+ fout.close()
+
+ val fin = new ByteArrayInputStream(fout.toByteArray)
+ val in = new ObjectInputStream(fin)
+ val retag = in.readObject().asInstanceOf[scala.reflect.basis.AbsTypeTag[_]].in(cm)
+ in.close()
+ fin.close()
+
+ println(retag)
+ } catch {
+ case ex: Exception =>
+ println(ex)
+ }
+
+ def qwe[T, U[_]] = {
+ test(implicitly[AbsTypeTag[T]])
+ test(implicitly[AbsTypeTag[U[String]]])
+ }
+
+ qwe
+} \ No newline at end of file
diff --git a/test/files/run/exprs_serialize.check b/test/files/run/exprs_serialize.check
new file mode 100644
index 0000000000..a3bf9ccdc4
--- /dev/null
+++ b/test/files/run/exprs_serialize.check
@@ -0,0 +1,2 @@
+java.io.NotSerializableException: Test$$treecreator1$1
+java.io.NotSerializableException: Test$$treecreator2$1
diff --git a/test/files/run/exprs_serialize.scala b/test/files/run/exprs_serialize.scala
new file mode 100644
index 0000000000..075c902a34
--- /dev/null
+++ b/test/files/run/exprs_serialize.scala
@@ -0,0 +1,28 @@
+import java.io._
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ def test(expr: Expr[_]) =
+ try {
+ val fout = new ByteArrayOutputStream()
+ val out = new ObjectOutputStream(fout)
+ out.writeObject(expr)
+ out.close()
+ fout.close()
+
+ val fin = new ByteArrayInputStream(fout.toByteArray)
+ val in = new ObjectInputStream(fin)
+ val reexpr = in.readObject().asInstanceOf[scala.reflect.basis.Expr[_]].in(cm)
+ in.close()
+ fin.close()
+
+ println(reexpr)
+ } catch {
+ case ex: Exception =>
+ println(ex)
+ }
+
+ test(reify(2))
+ test(reify{def foo = "hello"; foo + "world!"})
+} \ No newline at end of file
diff --git a/test/files/run/macro-typecheck-macrosdisabled.check b/test/files/run/macro-typecheck-macrosdisabled.check
index da1a28bc24..c560b0e4b5 100644
--- a/test/files/run/macro-typecheck-macrosdisabled.check
+++ b/test/files/run/macro-typecheck-macrosdisabled.check
@@ -8,11 +8,6 @@
()
};
def apply[U >: Nothing <: scala.reflect.base.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = {
- val $u: scala.reflect.api.Universe = $m$untyped.universe.asInstanceOf[scala.reflect.api.Universe];
- val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
- $treecreator1.this.applyImpl[$u.type]($m).asInstanceOf[U#Tree]
- };
- private def applyImpl[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): scala.reflect.base.Universe#Tree = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.Literal.apply($u.Constant.apply(2))
diff --git a/test/files/run/macro-typecheck-macrosdisabled2.check b/test/files/run/macro-typecheck-macrosdisabled2.check
index 908fb65bb3..55e7913250 100644
--- a/test/files/run/macro-typecheck-macrosdisabled2.check
+++ b/test/files/run/macro-typecheck-macrosdisabled2.check
@@ -8,11 +8,6 @@
()
};
def apply[U >: Nothing <: scala.reflect.base.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = {
- val $u: scala.reflect.api.Universe = $m$untyped.universe.asInstanceOf[scala.reflect.api.Universe];
- val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
- $treecreator1.this.applyImpl[$u.type]($m).asInstanceOf[U#Tree]
- };
- private def applyImpl[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): scala.reflect.base.Universe#Tree = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.Apply.apply($u.Select.apply($u.Select.apply($u.build.Ident($m.staticPackage("scala")), $u.newTermName("Array")), $u.newTermName("apply")), scala.collection.immutable.List.apply[$u.Literal]($u.Literal.apply($u.Constant.apply(2))))
diff --git a/test/files/run/toolbox_typecheck_macrosdisabled.check b/test/files/run/toolbox_typecheck_macrosdisabled.check
index f4a67e3054..9cf101c69d 100644
--- a/test/files/run/toolbox_typecheck_macrosdisabled.check
+++ b/test/files/run/toolbox_typecheck_macrosdisabled.check
@@ -8,11 +8,6 @@
()
};
def apply[U <: scala.reflect.base.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = {
- val $u: scala.reflect.api.Universe = $m$untyped.universe.asInstanceOf[scala.reflect.api.Universe];
- val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
- $treecreator1.this.applyImpl[$u.type]($m).asInstanceOf[U#Tree]
- };
- private def applyImpl[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): scala.reflect.base.Universe#Tree = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.Literal.apply($u.Constant.apply(2))
diff --git a/test/files/run/toolbox_typecheck_macrosdisabled2.check b/test/files/run/toolbox_typecheck_macrosdisabled2.check
index fa55a09c40..d344e33180 100644
--- a/test/files/run/toolbox_typecheck_macrosdisabled2.check
+++ b/test/files/run/toolbox_typecheck_macrosdisabled2.check
@@ -8,11 +8,6 @@
()
};
def apply[U <: scala.reflect.base.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): U#Tree = {
- val $u: scala.reflect.api.Universe = $m$untyped.universe.asInstanceOf[scala.reflect.api.Universe];
- val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
- $treecreator1.this.applyImpl[$u.type]($m).asInstanceOf[U#Tree]
- };
- private def applyImpl[U <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.base.MirrorOf[U]): scala.reflect.base.Universe#Tree = {
val $u: U = $m$untyped.universe;
val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
$u.Apply.apply($u.Select.apply($u.Select.apply($u.build.Ident($m.staticPackage("scala")), $u.newTermName("Array")), $u.newTermName("apply")), scala.collection.immutable.List.apply[$u.Literal]($u.Literal.apply($u.Constant.apply(2))))
diff --git a/test/files/run/typetags_serialize.check b/test/files/run/typetags_serialize.check
new file mode 100644
index 0000000000..1b898250fb
--- /dev/null
+++ b/test/files/run/typetags_serialize.check
@@ -0,0 +1,2 @@
+java.io.NotSerializableException: scala.reflect.base.TypeTags$PredefTypeCreator
+java.io.NotSerializableException: Test$$typecreator1$1
diff --git a/test/files/run/typetags_serialize.scala b/test/files/run/typetags_serialize.scala
new file mode 100644
index 0000000000..3917b69a93
--- /dev/null
+++ b/test/files/run/typetags_serialize.scala
@@ -0,0 +1,28 @@
+import java.io._
+import scala.reflect.runtime.universe._
+import scala.reflect.runtime.{currentMirror => cm}
+
+object Test extends App {
+ def test(tag: TypeTag[_]) =
+ try {
+ val fout = new ByteArrayOutputStream()
+ val out = new ObjectOutputStream(fout)
+ out.writeObject(tag)
+ out.close()
+ fout.close()
+
+ val fin = new ByteArrayInputStream(fout.toByteArray)
+ val in = new ObjectInputStream(fin)
+ val retag = in.readObject().asInstanceOf[scala.reflect.basis.TypeTag[_]].in(cm)
+ in.close()
+ fin.close()
+
+ println(retag)
+ } catch {
+ case ex: Exception =>
+ println(ex)
+ }
+
+ test(implicitly[TypeTag[Int]])
+ test(implicitly[TypeTag[String]])
+} \ No newline at end of file