Skip to content

Commit

Permalink
Merge pull request scala#3711 from retronym/ticket/8549-2
Browse files Browse the repository at this point in the history
SI-8549 Serialization: fix regression with @serialversionuid / start enforcing backwards compatibility
  • Loading branch information
retronym committed May 8, 2014
2 parents e8ed2d2 + 2dbd269 commit a4e56ef
Show file tree
Hide file tree
Showing 10 changed files with 231 additions and 10 deletions.
14 changes: 7 additions & 7 deletions src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,13 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
cd.impl.body collect { case dd: DefDef => dd.symbol }
}

/*
* 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)
Expand Down Expand Up @@ -880,13 +887,6 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
// The particular value in use for `MIN_SWITCH_DENSITY` reflects a heuristic.
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`
*
Expand Down
4 changes: 1 addition & 3 deletions src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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] = {

Expand Down
3 changes: 3 additions & 0 deletions src/library/scala/reflect/Manifest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ trait Manifest[T] extends ClassManifest[T] with Equals {

// TODO undeprecated until Scala reflection becomes non-experimental
// @deprecated("Use type tags and manually check the corresponding class or type instead", "2.10.0")
@SerialVersionUID(1L)
abstract class AnyValManifest[T <: AnyVal](override val toString: String) extends Manifest[T] with Equals {
override def <:<(that: ClassManifest[_]): Boolean =
(that eq this) || (that eq Manifest.Any) || (that eq Manifest.AnyVal)
Expand All @@ -72,6 +73,7 @@ abstract class AnyValManifest[T <: AnyVal](override val toString: String) extend
case _ => false
}
override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
@transient
override val hashCode = System.identityHashCode(this)
}

Expand Down Expand Up @@ -228,6 +230,7 @@ object ManifestFactory {
private abstract class PhantomManifest[T](_runtimeClass: Predef.Class[_],
override val toString: String) extends ClassTypeManifest[T](None, _runtimeClass, Nil) {
override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
@transient
override val hashCode = System.identityHashCode(this)
}

Expand Down
7 changes: 7 additions & 0 deletions test/files/neg/t6988.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
t6988.scala:3: error: annotation argument needs to be a constant; found: 13.asInstanceOf[Long]
@SerialVersionUID(13.asInstanceOf[Long]) case class IdentifyMessage1(userName: String, user: User, code: Int)
^
t6988.scala:8: error: annotation argument needs to be a constant; found: O.SerialUID
@SerialVersionUID(O.SerialUID) case class IdentifyMessage3(userName: String, user: User, code: Int)
^
two errors found
10 changes: 10 additions & 0 deletions test/files/neg/t6988.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
case class User()

@SerialVersionUID(13.asInstanceOf[Long]) case class IdentifyMessage1(userName: String, user: User, code: Int)
@SerialVersionUID(13l) case class IdentifyMessage2(userName: String, user: User, code: Int)
object O {
val SerialUID = "13".toLong
}
@SerialVersionUID(O.SerialUID) case class IdentifyMessage3(userName: String, user: User, code: Int)


2 changes: 2 additions & 0 deletions test/files/run/t6988.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#1 13
#2 13
9 changes: 9 additions & 0 deletions test/files/run/t6988.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
case class User()

@SerialVersionUID(13l) case class IdentifyMessage1(userName: String, user: User, code: Int)
@SerialVersionUID(10l + 3l) case class IdentifyMessage2(userName: String, user: User, code: Int)

object Test extends App {
println("#1 " + java.io.ObjectStreamClass.lookup(IdentifyMessage1("hei", User(), 8).getClass).getSerialVersionUID)
println("#2 " + java.io.ObjectStreamClass.lookup(IdentifyMessage2("hei", User(), 8).getClass).getSerialVersionUID)
}
1 change: 1 addition & 0 deletions test/files/run/t8549.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
warning: there were 2 deprecation warning(s); re-run with -deprecation for details
175 changes: 175 additions & 0 deletions test/files/run/t8549.scala

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions test/files/run/t8549b.scala
Original file line number Diff line number Diff line change
@@ -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])
}

0 comments on commit a4e56ef

Please sign in to comment.