Skip to content

Commit ecbc9d0

Browse files
committed
SI-8549 Honour the @serialversionuid annotatation
In PR scala#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.
1 parent fc4602a commit ecbc9d0

File tree

3 files changed

+24
-10
lines changed

3 files changed

+24
-10
lines changed

src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,13 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
238238
cd.impl.body collect { case dd: DefDef => dd.symbol }
239239
}
240240

241+
/*
242+
* must-single-thread
243+
*/
244+
def serialVUID(csym: Symbol): Option[Long] = csym getAnnotation definitions.SerialVersionUIDAttr collect {
245+
case AnnotationInfo(_, _, (_, LiteralAnnotArg(const)) :: Nil) => const.longValue
246+
}
247+
241248
/*
242249
* Populates the InnerClasses JVM attribute with `refedInnerClasses`.
243250
* In addition to inner classes mentioned somewhere in `jclass` (where `jclass` is a class file being emitted)
@@ -880,13 +887,6 @@ abstract class BCodeHelpers extends BCodeTypes with BytecodeWriters {
880887
// The particular value in use for `MIN_SWITCH_DENSITY` reflects a heuristic.
881888
val MIN_SWITCH_DENSITY = 0.7
882889

883-
/*
884-
* must-single-thread
885-
*/
886-
def serialVUID(csym: Symbol): Option[Long] = csym getAnnotation definitions.SerialVersionUIDAttr collect {
887-
case AnnotationInfo(_, Literal(const) :: _, _) => const.longValue
888-
}
889-
890890
/*
891891
* Add public static final field serialVersionUID with value `id`
892892
*

src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,9 +1142,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
11421142

11431143
def isParcelableClass = isAndroidParcelableClass(clasz.symbol)
11441144

1145-
def serialVUID: Option[Long] = clasz.symbol getAnnotation SerialVersionUIDAttr collect {
1146-
case AnnotationInfo(_, Literal(const) :: _, _) => const.longValue
1147-
}
1145+
def serialVUID: Option[Long] = genBCode.serialVUID(clasz.symbol)
11481146

11491147
private def getSuperInterfaces(c: IClass): Array[String] = {
11501148

test/files/run/t8549b.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
@SerialVersionUID(42)
3+
class C
4+
5+
@SerialVersionUID(43 - 1)
6+
class D
7+
8+
9+
object Test extends App {
10+
def checkId(cls: Class[_]) {
11+
val id = cls.getDeclaredField("serialVersionUID").get(null)
12+
assert(id == 42, (cls, id))
13+
}
14+
checkId(classOf[C])
15+
checkId(classOf[D])
16+
}

0 commit comments

Comments
 (0)