diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java index ac5ed4a19c8..fd453cbf249 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/codegen/ir/FirBlackBoxCodegenTestGenerated.java @@ -8272,6 +8272,16 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt"); } + @TestMetadata("kt36972_companion.kt") + public void testKt36972_companion() throws Exception { + runTest("compiler/testData/codegen/box/defaultArguments/kt36972_companion.kt"); + } + + @TestMetadata("kt36972_object.kt") + public void testKt36972_object() throws Exception { + runTest("compiler/testData/codegen/box/defaultArguments/kt36972_object.kt"); + } + @TestMetadata("kt6382.kt") public void testKt6382() throws Exception { runTest("compiler/testData/codegen/box/defaultArguments/kt6382.kt"); diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt index 6321fe540f3..7665615362c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/JvmStaticAnnotationLowering.kt @@ -59,29 +59,33 @@ private class CompanionObjectJvmStaticLowering(val context: JvmBackendContext) : override fun lower(irClass: IrClass) { val companion = irClass.declarations.find { it is IrClass && it.isCompanion - } as IrClass? + } as? IrClass ?: return - companion?.declarations?.filter(::isJvmStaticFunction)?.forEach { declaration -> - val jvmStaticFunction = declaration as IrSimpleFunction - if (jvmStaticFunction.isExternal) { - // We move external functions to the enclosing class and potentially add accessors there. - // The JVM backend also adds accessors in the companion object, but these are superfluous. - val staticExternal = irClass.addFunction { - updateFrom(jvmStaticFunction) - name = jvmStaticFunction.name - returnType = jvmStaticFunction.returnType - }.apply { - copyTypeParametersFrom(jvmStaticFunction) - extensionReceiverParameter = jvmStaticFunction.extensionReceiverParameter?.copyTo(this) - valueParameters = jvmStaticFunction.valueParameters.map { it.copyTo(this) } - annotations = jvmStaticFunction.annotations.map { it.deepCopyWithSymbols() } + companion.declarations + // In case of companion objects, proxy functions for '$default' methods for @JvmStatic functions with default parameters + // are not created in the host class. + .filter { isJvmStaticFunction(it) && it.origin != IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER } + .forEach { declaration -> + val jvmStaticFunction = declaration as IrSimpleFunction + if (jvmStaticFunction.isExternal) { + // We move external functions to the enclosing class and potentially add accessors there. + // The JVM backend also adds accessors in the companion object, but these are superfluous. + val staticExternal = irClass.addFunction { + updateFrom(jvmStaticFunction) + name = jvmStaticFunction.name + returnType = jvmStaticFunction.returnType + }.apply { + copyTypeParametersFrom(jvmStaticFunction) + extensionReceiverParameter = jvmStaticFunction.extensionReceiverParameter?.copyTo(this) + valueParameters = jvmStaticFunction.valueParameters.map { it.copyTo(this) } + annotations = jvmStaticFunction.annotations.map { it.deepCopyWithSymbols() } + } + companion.declarations.remove(jvmStaticFunction) + companion.addProxy(staticExternal, companion, isStatic = false) + } else { + irClass.addProxy(jvmStaticFunction, companion) } - companion.declarations.remove(jvmStaticFunction) - companion.addProxy(staticExternal, companion, isStatic = false) - } else { - irClass.addProxy(jvmStaticFunction, companion) } - } } private fun IrClass.addProxy(target: IrSimpleFunction, companion: IrClass, isStatic: Boolean = true) = diff --git a/compiler/testData/codegen/box/defaultArguments/kt36972_companion.kt b/compiler/testData/codegen/box/defaultArguments/kt36972_companion.kt new file mode 100644 index 00000000000..991d6a866ca --- /dev/null +++ b/compiler/testData/codegen/box/defaultArguments/kt36972_companion.kt @@ -0,0 +1,11 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME + +class Host { + companion object { + @JvmStatic + fun foo(s: String = "OK") = s + } +} + +fun box(): String = Host.foo() \ No newline at end of file diff --git a/compiler/testData/codegen/box/defaultArguments/kt36972_object.kt b/compiler/testData/codegen/box/defaultArguments/kt36972_object.kt new file mode 100644 index 00000000000..4d0d2baaef8 --- /dev/null +++ b/compiler/testData/codegen/box/defaultArguments/kt36972_object.kt @@ -0,0 +1,9 @@ +// TARGET_BACKEND: JVM +// WITH_RUNTIME + +object Host { + @JvmStatic + fun foo(s: String = "OK") = s +} + +fun box(): String = Host.foo() \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.kt b/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.kt new file mode 100644 index 00000000000..9c0fa21cd62 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.kt @@ -0,0 +1,13 @@ +// WITH_RUNTIME + +class WithCompanion { + companion object { + @JvmStatic + fun foo(x: Int = 1) {} + } +} + +object AnObject { + @JvmStatic + fun foo(x: Int = 1) {} +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.txt b/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.txt new file mode 100644 index 00000000000..00336aa8801 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.txt @@ -0,0 +1,26 @@ +@kotlin.Metadata +public final class AnObject { + public final static field INSTANCE: AnObject + static method (): void + private method (): void + public synthetic static method foo$default(p0: int, p1: int, p2: java.lang.Object): void + public final static @kotlin.jvm.JvmStatic method foo(p0: int): void +} + +@kotlin.Metadata +public final class WithCompanion$Companion { + inner class WithCompanion$Companion + private method (): void + public synthetic method (p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic static method foo$default(p0: WithCompanion$Companion, p1: int, p2: int, p3: java.lang.Object): void + public final @kotlin.jvm.JvmStatic method foo(p0: int): void +} + +@kotlin.Metadata +public final class WithCompanion { + public final static field Companion: WithCompanion$Companion + inner class WithCompanion$Companion + static method (): void + public method (): void + public final static @kotlin.jvm.JvmStatic method foo(p0: int): void +} diff --git a/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters_ir.txt b/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters_ir.txt new file mode 100644 index 00000000000..efd8a024e0e --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters_ir.txt @@ -0,0 +1,26 @@ +@kotlin.Metadata +public final class AnObject { + public final static @org.jetbrains.annotations.NotNull field INSTANCE: AnObject + static method (): void + private method (): void + public synthetic static method foo$default(p0: int, p1: int, p2: java.lang.Object): void + public final static @kotlin.jvm.JvmStatic method foo(p0: int): void +} + +@kotlin.Metadata +public final class WithCompanion$Companion { + inner class WithCompanion$Companion + private method (): void + public synthetic method (@org.jetbrains.annotations.NotNull p0: kotlin.jvm.internal.DefaultConstructorMarker): void + public synthetic static method foo$default(p0: WithCompanion$Companion, p1: int, p2: int, p3: java.lang.Object): void + public final @kotlin.jvm.JvmStatic method foo(p0: int): void +} + +@kotlin.Metadata +public final class WithCompanion { + public final static @org.jetbrains.annotations.NotNull field Companion: WithCompanion$Companion + inner class WithCompanion$Companion + static method (): void + public method (): void + public final static @kotlin.jvm.JvmStatic method foo(p0: int): void +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index f00aee24429..590c092b6f8 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -9417,6 +9417,16 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt"); } + @TestMetadata("kt36972_companion.kt") + public void testKt36972_companion() throws Exception { + runTest("compiler/testData/codegen/box/defaultArguments/kt36972_companion.kt"); + } + + @TestMetadata("kt36972_object.kt") + public void testKt36972_object() throws Exception { + runTest("compiler/testData/codegen/box/defaultArguments/kt36972_object.kt"); + } + @TestMetadata("kt6382.kt") public void testKt6382() throws Exception { runTest("compiler/testData/codegen/box/defaultArguments/kt6382.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index 983b2b85fad..e234b18fd14 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -69,6 +69,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/jvmOverloadsAndParametersAnnotations.kt"); } + @TestMetadata("jvmStaticWithDefaultParameters.kt") + public void testJvmStaticWithDefaultParameters() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.kt"); + } + @TestMetadata("noCollectionStubMethodsInInterface.kt") public void testNoCollectionStubMethodsInInterface() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/noCollectionStubMethodsInInterface.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index fef5386da40..7a1cedd5738 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -9417,6 +9417,16 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt"); } + @TestMetadata("kt36972_companion.kt") + public void testKt36972_companion() throws Exception { + runTest("compiler/testData/codegen/box/defaultArguments/kt36972_companion.kt"); + } + + @TestMetadata("kt36972_object.kt") + public void testKt36972_object() throws Exception { + runTest("compiler/testData/codegen/box/defaultArguments/kt36972_object.kt"); + } + @TestMetadata("kt6382.kt") public void testKt6382() throws Exception { runTest("compiler/testData/codegen/box/defaultArguments/kt6382.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 2ef32804aa7..d8d8f31da17 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -8272,6 +8272,16 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/defaultArguments/inheritedFromInterfaceViaAbstractSuperclass.kt"); } + @TestMetadata("kt36972_companion.kt") + public void testKt36972_companion() throws Exception { + runTest("compiler/testData/codegen/box/defaultArguments/kt36972_companion.kt"); + } + + @TestMetadata("kt36972_object.kt") + public void testKt36972_object() throws Exception { + runTest("compiler/testData/codegen/box/defaultArguments/kt36972_object.kt"); + } + @TestMetadata("kt6382.kt") public void testKt6382() throws Exception { runTest("compiler/testData/codegen/box/defaultArguments/kt6382.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index eb9a7d4f020..72ecc9a7eef 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -69,6 +69,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/jvmOverloadsAndParametersAnnotations.kt"); } + @TestMetadata("jvmStaticWithDefaultParameters.kt") + public void testJvmStaticWithDefaultParameters() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/jvmStaticWithDefaultParameters.kt"); + } + @TestMetadata("noCollectionStubMethodsInInterface.kt") public void testNoCollectionStubMethodsInInterface() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/noCollectionStubMethodsInInterface.kt");