[JVM IR] Leave private @JvmDefault methods on interface
Like the old backend, always leave private @JvmDefault annotated interface members (properties, methods) on the interface, just like the old backend. Fix naming, and introduce test to document the naming scheme.
This commit is contained in:
committed by
max-kammerer
parent
6f8682c950
commit
18e8896c08
+5
-1
@@ -115,7 +115,11 @@ open class FunctionCodegen(
|
|||||||
irFunction.origin == IrDeclarationOrigin.BRIDGE_SPECIAL
|
irFunction.origin == IrDeclarationOrigin.BRIDGE_SPECIAL
|
||||||
) Opcodes.ACC_BRIDGE else 0
|
) Opcodes.ACC_BRIDGE else 0
|
||||||
val modalityFlag = when ((irFunction as? IrSimpleFunction)?.modality) {
|
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
|
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
|
else -> if (classCodegen.irClass.isJvmInterface && irFunction.body == null) Opcodes.ACC_ABSTRACT else 0 //TODO transform interface modality on lowering to DefaultImpls
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -310,7 +310,7 @@ class MethodSignatureMapper(private val context: JvmBackendContext) {
|
|||||||
val invokeOpcode = when {
|
val invokeOpcode = when {
|
||||||
callee.dispatchReceiverParameter == null -> Opcodes.INVOKESTATIC
|
callee.dispatchReceiverParameter == null -> Opcodes.INVOKESTATIC
|
||||||
isSuperCall -> Opcodes.INVOKESPECIAL
|
isSuperCall -> Opcodes.INVOKESPECIAL
|
||||||
isInterface -> Opcodes.INVOKEINTERFACE
|
isInterface && !Visibilities.isPrivate(callee.visibility) -> Opcodes.INVOKEINTERFACE
|
||||||
Visibilities.isPrivate(callee.visibility) && !callee.isSuspend -> Opcodes.INVOKESPECIAL
|
Visibilities.isPrivate(callee.visibility) && !callee.isSuspend -> Opcodes.INVOKESPECIAL
|
||||||
else -> Opcodes.INVOKEVIRTUAL
|
else -> Opcodes.INVOKEVIRTUAL
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -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
|
* 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 == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER && !function.hasJvmDefault())
|
||||||
|| function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS -> {
|
|| function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS -> {
|
||||||
val defaultImpl = createDefaultImpl(function)
|
val defaultImpl = createDefaultImpl(function)
|
||||||
|
|||||||
+5
-2
@@ -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.codegen.isJvmInterface
|
||||||
import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs
|
import org.jetbrains.kotlin.backend.jvm.intrinsics.receiverAndArgs
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.IrInlineReferenceLocator
|
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.isLambda
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.shouldBeHidden
|
import org.jetbrains.kotlin.backend.jvm.ir.shouldBeHidden
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
@@ -447,8 +448,10 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : IrEle
|
|||||||
private fun IrFunction.accessorName(superQualifier: IrClassSymbol?): Name {
|
private fun IrFunction.accessorName(superQualifier: IrClassSymbol?): Name {
|
||||||
val jvmName = context.methodSignatureMapper.mapFunctionName(this)
|
val jvmName = context.methodSignatureMapper.mapFunctionName(this)
|
||||||
val suffix = when {
|
val suffix = when {
|
||||||
// The only function accessors placed on interfaces are for JvmDefault implementations
|
// The only function accessors placed on interfaces are for private functions and JvmDefault implementations.
|
||||||
parent.safeAs<IrClass>()?.isJvmInterface == true -> "\$jd"
|
// The two cannot clash.
|
||||||
|
parentAsClass.isJvmInterface && Visibilities.isPrivate(visibility) -> ""
|
||||||
|
parentAsClass.isJvmInterface && hasJvmDefault() -> "\$jd"
|
||||||
|
|
||||||
// Accessor for _s_uper-qualified call
|
// Accessor for _s_uper-qualified call
|
||||||
superQualifier != null -> "\$s" + superQualifier.descriptor.name.asString().hashCode()
|
superQualifier != null -> "\$s" + superQualifier.descriptor.name.asString().hashCode()
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
@@ -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
|
||||||
+5
@@ -776,6 +776,11 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest {
|
|||||||
runTest("compiler/testData/writeFlags/jvm8/defaults/onlyJvmDefaultsOnInterface.kt");
|
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")
|
@TestMetadata("propertyAnnotation.kt")
|
||||||
public void testPropertyAnnotation() throws Exception {
|
public void testPropertyAnnotation() throws Exception {
|
||||||
runTest("compiler/testData/writeFlags/jvm8/defaults/propertyAnnotation.kt");
|
runTest("compiler/testData/writeFlags/jvm8/defaults/propertyAnnotation.kt");
|
||||||
|
|||||||
+5
@@ -776,6 +776,11 @@ public class IrWriteFlagsTestGenerated extends AbstractIrWriteFlagsTest {
|
|||||||
runTest("compiler/testData/writeFlags/jvm8/defaults/onlyJvmDefaultsOnInterface.kt");
|
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")
|
@TestMetadata("propertyAnnotation.kt")
|
||||||
public void testPropertyAnnotation() throws Exception {
|
public void testPropertyAnnotation() throws Exception {
|
||||||
runTest("compiler/testData/writeFlags/jvm8/defaults/propertyAnnotation.kt");
|
runTest("compiler/testData/writeFlags/jvm8/defaults/propertyAnnotation.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user