Skip to content

Commit dfe36a5

Browse files
committed
Set ACC_FINAL access flag to final variable accessors
1 parent 67f11ff commit dfe36a5

File tree

2 files changed

+25
-0
lines changed

2 files changed

+25
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,12 +754,14 @@ trait BCodeSkelBuilder extends BCodeHelpers {
754754

755755
val isNative = methSymbol.hasAnnotation(NativeAttr)
756756
val isAbstractMethod = (methSymbol.is(Deferred) || (methSymbol.owner.isInterface && ((methSymbol.is(Deferred)) || methSymbol.isClassConstructor)))
757+
val isFinal = methSymbol.is(Final)
757758
val flags =
758759
import GenBCodeOps.addFlagIf
759760
javaFlags(methSymbol)
760761
.addFlagIf(isAbstractMethod, asm.Opcodes.ACC_ABSTRACT)
761762
.addFlagIf(false /*methSymbol.isStrictFP*/, asm.Opcodes.ACC_STRICT)
762763
.addFlagIf(isNative, asm.Opcodes.ACC_NATIVE) // native methods of objects are generated in mirror classes
764+
.addFlagIf(isFinal, asm.Opcodes.ACC_FINAL)
763765

764766
// TODO needed? for(ann <- m.symbol.annotations) { ann.symbol.initialize }
765767
val paramSyms = params.map(_.symbol)

compiler/test/dotty/tools/backend/jvm/DottyBytecodeTests.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,29 @@ class DottyBytecodeTests extends DottyBytecodeTest {
15571557
}
15581558
}
15591559

1560+
/** Check that final mutable var accessors are final */
1561+
@Test def i10835 = {
1562+
val source =
1563+
s"""class A {
1564+
| final var x = 1
1565+
|}
1566+
|""".stripMargin
1567+
checkBCode(source){dir =>
1568+
val clsIn = dir.lookupName("A.class", directory = false).input
1569+
val clsNode = loadClassNode(clsIn)
1570+
def isFinal(access: Int) = (access & Opcodes.ACC_FINAL) != 0
1571+
1572+
val field = clsNode.fields.asScala.find(_.name == "x").map(_.access)
1573+
assertTrue("field is not final", field.exists(!isFinal(_)))
1574+
assertTrue("field is private", field.exists(acc => (acc & Opcodes.ACC_PRIVATE) != 0))
1575+
1576+
val methods = clsNode.methods.asScala
1577+
def methodAccess(name: String) = methods.find(_.name == name).map(_.access)
1578+
assertTrue("getter is final", methodAccess("x").exists(isFinal))
1579+
assertTrue("setter is final", methodAccess("x_$eq").exists(isFinal))
1580+
}
1581+
}
1582+
15601583
/** Check that erasure if `Int | Nothing` is `int` */
15611584
@Test def i14970 = {
15621585
val source =

0 commit comments

Comments
 (0)