Skip to content

Commit 6c8b4b5

Browse files
authored
Merge pull request #7331 from dotty-staging/serialvuid
Fix #7319: Properly support @serialversionuid
2 parents 4695546 + fc6a5af commit 6c8b4b5

File tree

5 files changed

+38
-3
lines changed

5 files changed

+38
-3
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ trait BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
421421
def addSerialVUID(id: Long, jclass: asm.ClassVisitor): Unit = {
422422
// add static serialVersionUID field if `clasz` annotated with `@SerialVersionUID(uid: Long)`
423423
jclass.visitField(
424-
GenBCodeOps.PublicStaticFinal,
424+
GenBCodeOps.PrivateStaticFinal,
425425
"serialVersionUID",
426426
"J",
427427
null, // no java-generic-signature

compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,8 +791,14 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
791791
}
792792
def methodSymbols: List[Symbol] =
793793
for (f <- toDenot(sym).info.decls.toList if f.isMethod && f.isTerm && !f.isModule) yield f
794-
def serialVUID: Option[Long] = None
795-
794+
def serialVUID: Option[Long] =
795+
sym.getAnnotation(defn.SerialVersionUIDAnnot).flatMap { annot =>
796+
val vuid = annot.argumentConstant(0).map(_.longValue)
797+
if (vuid.isEmpty)
798+
ctx.error("The argument passed to @SerialVersionUID must be a constant",
799+
annot.argument(0).getOrElse(annot.tree).sourcePos)
800+
vuid
801+
}
796802

797803
def freshLocal(cunit: CompilationUnit, name: String, tpe: Type, pos: Position, flags: Flags): Symbol = {
798804
ctx.newSymbol(sym, name.toTermName, termFlagSet(flags), tpe, NoSymbol, pos)

compiler/src/dotty/tools/backend/jvm/GenBCodeOps.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@ class GenBCodeOps {
1111

1212
final val PublicStatic = asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_STATIC
1313
final val PublicStaticFinal = asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_FINAL
14+
final val PrivateStaticFinal = asm.Opcodes.ACC_PRIVATE | asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_FINAL
1415
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@SerialVersionUID(13l.toLong) class C1 extends Serializable // error
2+
@SerialVersionUID(13l) class C2 extends Serializable // OK
3+
@SerialVersionUID(13.asInstanceOf[Long]) class C3 extends Serializable // error
4+
@SerialVersionUID(Test.bippy) class C4 extends Serializable // error
5+
6+
object Test {
7+
val bippy = 13L
8+
}

tests/run/t8549b.scala

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import java.lang.reflect.Modifier._
2+
3+
@SerialVersionUID(42)
4+
class C extends Serializable
5+
6+
@SerialVersionUID(43 - 1)
7+
class D extends Serializable
8+
9+
10+
object Test extends App {
11+
def checkId(cls: Class[_]): Unit = {
12+
val field = cls.getDeclaredField("serialVersionUID")
13+
assert(isPrivate(field.getModifiers))
14+
field.setAccessible(true)
15+
val id = field.get(null).asInstanceOf[Long]
16+
assert(id == 42, (cls, id))
17+
}
18+
checkId(classOf[C])
19+
checkId(classOf[D])
20+
}

0 commit comments

Comments
 (0)