Skip to content

Commit

Permalink
Merge pull request #2635 from retronym/ticket/7151
Browse files Browse the repository at this point in the history
SI-7151 Emit final in bytecode for final inner classes.
  • Loading branch information
gkossakowski committed Jun 19, 2013
2 parents 16ea58b + b49b6cf commit f467940
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {

val INNER_CLASSES_FLAGS =
(asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_PRIVATE | asm.Opcodes.ACC_PROTECTED |
asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_INTERFACE | asm.Opcodes.ACC_ABSTRACT)
asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_INTERFACE | asm.Opcodes.ACC_ABSTRACT | asm.Opcodes.ACC_FINAL)

// -----------------------------------------------------------------------------------------
// factory methods
Expand Down Expand Up @@ -648,11 +648,12 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {

// sort them so inner classes succeed their enclosing class to satisfy the Eclipse Java compiler
for (innerSym <- allInners sortBy (_.name.length)) { // TODO why not sortBy (_.name.toString()) ??
val flags = mkFlags(
val flagsWithFinal: Int = mkFlags(
if (innerSym.rawowner.hasModuleFlag) asm.Opcodes.ACC_STATIC else 0,
javaFlags(innerSym),
if(isDeprecated(innerSym)) asm.Opcodes.ACC_DEPRECATED else 0 // ASM pseudo-access flag
) & (INNER_CLASSES_FLAGS | asm.Opcodes.ACC_DEPRECATED)
val flags = if (innerSym.isModuleClass) flagsWithFinal & ~asm.Opcodes.ACC_FINAL else flagsWithFinal // For SI-5676, object overriding.
val jname = javaName(innerSym) // never null
val oname = outerName(innerSym) // null when method-enclosed
val iname = innerName(innerSym) // null for anonymous inner class
Expand Down
6 changes: 6 additions & 0 deletions test/files/run/t7151.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
class Test$InnerObject$ isFinal = false
class Test$InnerCase isFinal = true
class Test$InnerNonCase isFinal = true
class TopLevelObject$ isFinal = true
class TopLevelCase isFinal = true
class TopLevelNonCase isFinal = true
24 changes: 24 additions & 0 deletions test/files/run/t7151.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import java.lang.reflect.Modifier.isFinal

object Test {
object InnerObject
final case class InnerCase()
final class InnerNonCase()

def main(args: Array[String]) {
def checkFinal(clazz: Class[_]) =
println(s"${clazz} isFinal = ${isFinal(clazz.getModifiers())}")

checkFinal(InnerObject.getClass)
checkFinal(classOf[InnerCase])
checkFinal(classOf[InnerNonCase])

checkFinal(TopLevelObject.getClass)
checkFinal(classOf[TopLevelCase])
checkFinal(classOf[TopLevelNonCase])
}
}

object TopLevelObject
final case class TopLevelCase()
final case class TopLevelNonCase()

0 comments on commit f467940

Please sign in to comment.