diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt index 0fd29c08794..265b152801e 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/FunctionCodegen.kt @@ -115,7 +115,11 @@ open class FunctionCodegen( irFunction.origin == IrDeclarationOrigin.BRIDGE_SPECIAL ) Opcodes.ACC_BRIDGE else 0 val modalityFlag = when ((irFunction as? IrSimpleFunction)?.modality) { - Modality.FINAL -> if (!classCodegen.irClass.isAnnotationClass || irFunction.isStatic) Opcodes.ACC_FINAL else Opcodes.ACC_ABSTRACT + Modality.FINAL -> when { + classCodegen.irClass.isInterface && irFunction.body != null -> 0 + !classCodegen.irClass.isAnnotationClass || irFunction.isStatic -> Opcodes.ACC_FINAL + else -> Opcodes.ACC_ABSTRACT + } Modality.ABSTRACT -> Opcodes.ACC_ABSTRACT else -> if (classCodegen.irClass.isJvmInterface && irFunction.body == null) Opcodes.ACC_ABSTRACT else 0 //TODO transform interface modality on lowering to DefaultImpls } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt index cd8086a4e49..2b29ba4efb1 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/MethodSignatureMapper.kt @@ -310,7 +310,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) { val invokeOpcode = when { callee.dispatchReceiverParameter == null -> Opcodes.INVOKESTATIC isSuperCall -> Opcodes.INVOKESPECIAL - isInterface -> Opcodes.INVOKEINTERFACE + isInterface && !Visibilities.isPrivate(callee.visibility) -> Opcodes.INVOKEINTERFACE Visibilities.isPrivate(callee.visibility) && !callee.isSuspend -> Opcodes.INVOKESPECIAL else -> Opcodes.INVOKEVIRTUAL } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index 764cee8f5ea..79a34051628 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -109,10 +109,10 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran } /** - * 3) Private methods, default parameter dispatchers (without @JvmDefault) + * 3) Private methods (without @JvmDefault), default parameter dispatchers (without @JvmDefault) * and $annotation methods are always moved without bridges */ - Visibilities.isPrivate(function.visibility) + (Visibilities.isPrivate(function.visibility) && !function.hasJvmDefault()) || (function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER && !function.hasJvmDefault()) || function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS -> { val defaultImpl = createDefaultImpl(function) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt index 17147db5710..96001357bbf 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/SyntheticAccessorLowering.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator +import org.jetbrains.kotlin.backend.jvm.ir.hasJvmDefault import org.jetbrains.kotlin.backend.jvm.ir.isLambda import org.jetbrains.kotlin.backend.jvm.ir.shouldBeHidden import org.jetbrains.kotlin.descriptors.Modality @@ -447,8 +448,10 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle private fun IrFunction.accessorName(superQualifier: IrClassSymbol?): Name { val jvmName = context.methodSignatureMapper.mapFunctionName(this) val suffix = when { - // The only function accessors placed on interfaces are for JvmDefault implementations - parent.safeAs()?.isJvmInterface == true -> "\$jd" + // The only function accessors placed on interfaces are for private functions and JvmDefault implementations. + // The two cannot clash. + parentAsClass.isJvmInterface && Visibilities.isPrivate(visibility) -> "" + parentAsClass.isJvmInterface && hasJvmDefault() -> "\$jd" // Accessor for _s_uper-qualified call superQualifier != null -> "\$s" + superQualifier.descriptor.name.asString().hashCode() diff --git a/compiler/testData/codegen/box/jvm8/defaults/kt11969.kt b/compiler/testData/codegen/box/jvm8/defaults/kt11969.kt index 02af69b72e8..b443e426417 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/kt11969.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/kt11969.kt @@ -1,6 +1,5 @@ // !JVM_DEFAULT_MODE: enable // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_RUNTIME diff --git a/compiler/testData/writeFlags/jvm8/defaults/privateAccessorNaming.kt b/compiler/testData/writeFlags/jvm8/defaults/privateAccessorNaming.kt new file mode 100644 index 00000000000..bf91e2ce564 --- /dev/null +++ b/compiler/testData/writeFlags/jvm8/defaults/privateAccessorNaming.kt @@ -0,0 +1,18 @@ +// IGNORE_BACKEND_FIR: JVM_IR +// TARGET_BACKEND: JVM +// !JVM_DEFAULT_MODE: enable +// JVM_TARGET: 1.8 +// WITH_RUNTIME +interface I { + + @JvmDefault + private fun foo() = 4 + + fun bar() = { foo() + 5 }() + +} + + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: I, access$foo +// FLAGS: ACC_PUBLIC, ACC_STATIC, ACC_SYNTHETIC \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java index 136767d797b..3fa81fc60b7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/flags/WriteFlagsTestGenerated.java @@ -776,6 +776,11 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { runTest("compiler/testData/writeFlags/jvm8/defaults/onlyJvmDefaultsOnInterface.kt"); } + @TestMetadata("privateAccessorNaming.kt") + public void testPrivateAccessorNaming() throws Exception { + runTest("compiler/testData/writeFlags/jvm8/defaults/privateAccessorNaming.kt"); + } + @TestMetadata("propertyAnnotation.kt") public void testPropertyAnnotation() throws Exception { runTest("compiler/testData/writeFlags/jvm8/defaults/propertyAnnotation.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrWriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrWriteFlagsTestGenerated.java index f9d2335d438..7d44674a22b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrWriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrWriteFlagsTestGenerated.java @@ -776,6 +776,11 @@ public class IrWriteFlagsTestGenerated extends AbstractIrWriteFlagsTest { runTest("compiler/testData/writeFlags/jvm8/defaults/onlyJvmDefaultsOnInterface.kt"); } + @TestMetadata("privateAccessorNaming.kt") + public void testPrivateAccessorNaming() throws Exception { + runTest("compiler/testData/writeFlags/jvm8/defaults/privateAccessorNaming.kt"); + } + @TestMetadata("propertyAnnotation.kt") public void testPropertyAnnotation() throws Exception { runTest("compiler/testData/writeFlags/jvm8/defaults/propertyAnnotation.kt");