summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-05-05 11:32:43 +0200
committerJason Zaugg <jzaugg@gmail.com>2014-05-05 12:29:41 +0200
commitecbc9d02153e9ad3a710c7c2c0f385797b1ba3a6 (patch)
tree71addf3344b1fdfaeee21cfd5d3d5e5cd0b9ae58
parentfc4602a1415066f897530b6995299de1f3d9830f (diff)
downloadscala-ecbc9d02153e9ad3a710c7c2c0f385797b1ba3a6.tar.gz
scala-ecbc9d02153e9ad3a710c7c2c0f385797b1ba3a6.tar.bz2
scala-ecbc9d02153e9ad3a710c7c2c0f385797b1ba3a6.zip
SI-8549 Honour the @SerialVersionUID annotatation
In PR #1673 / 4267444, the annotation `SerialVersionId` was changed from a `StaticAnnotation` to `ClassFileAnnotation` in order to avoid silently ignoring non-literal UIDs like: @SerialVersionUID(0 - 12345L) class C And to flag non-constant UIDs: @SerialVersionUID("!!!".length) While this indeed was fold constants, the change was incomplete. The compiler API for reading the argument from a `ClassFileAnnoation` is different, on must look for a `LiteralAnnotArg`, rather than a `Literal`. This commit: - amends the backend accordingly - removes relevant duplication between `GenASM` and `GenBCode` - tests that the static field is generated accordingly This will mean that we will break deserialization of objects from Scalal 2.11.0 that use this annotation.
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala14
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala4
-rw-r--r--test/files/run/t8549b.scala16
3 files changed, 24 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index 359e5d6c29..f800dbf9cd 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -239,6 +239,13 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
}
/*
+ * must-single-thread
+ */
+ def serialVUID(csym: Symbol): Option[Long] = csym getAnnotation definitions.SerialVersionUIDAttr collect {
+ case AnnotationInfo(_, _, (_, LiteralAnnotArg(const)) :: Nil) => const.longValue
+ }
+
+ /*
* Populates the InnerClasses JVM attribute with `refedInnerClasses`.
* In addition to inner classes mentioned somewhere in `jclass` (where `jclass` is a class file being emitted)
* `refedInnerClasses` should contain those inner classes defined as direct member classes of `jclass`
@@ -881,13 +888,6 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
val MIN_SWITCH_DENSITY = 0.7
/*
- * must-single-thread
- */
- def serialVUID(csym: Symbol): Option[Long] = csym getAnnotation definitions.SerialVersionUIDAttr collect {
- case AnnotationInfo(_, Literal(const) :: _, _) => const.longValue
- }
-
- /*
* Add public static final field serialVersionUID with value `id`
*
* can-multi-thread
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index a389816caf..b7f9b30e19 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -1142,9 +1142,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
def isParcelableClass = isAndroidParcelableClass(clasz.symbol)
- def serialVUID: Option[Long] = clasz.symbol getAnnotation SerialVersionUIDAttr collect {
- case AnnotationInfo(_, Literal(const) :: _, _) => const.longValue
- }
+ def serialVUID: Option[Long] = genBCode.serialVUID(clasz.symbol)
private def getSuperInterfaces(c: IClass): Array[String] = {
diff --git a/test/files/run/t8549b.scala b/test/files/run/t8549b.scala
new file mode 100644
index 0000000000..1e1bf2c0bc
--- /dev/null
+++ b/test/files/run/t8549b.scala
@@ -0,0 +1,16 @@
+
+@SerialVersionUID(42)
+class C
+
+@SerialVersionUID(43 - 1)
+class D
+
+
+object Test extends App {
+ def checkId(cls: Class[_]) {
+ val id = cls.getDeclaredField("serialVersionUID").get(null)
+ assert(id == 42, (cls, id))
+ }
+ checkId(classOf[C])
+ checkId(classOf[D])
+}