KT-36972 Don't create proxies for companion @JvmStatic $default in host

When creating proxy functions in a host class for @JvmStatic members of
companion object, skip functions for default parameters handling.
This commit is contained in:
Dmitry Petrov
2020-03-18 10:58:08 +03:00
parent 897c48f97e
commit 1c24a97b9e
12 changed files with 159 additions and 20 deletions
@@ -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");
@@ -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) =
@@ -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()
@@ -0,0 +1,9 @@
// TARGET_BACKEND: JVM
// WITH_RUNTIME
object Host {
@JvmStatic
fun foo(s: String = "OK") = s
}
fun box(): String = Host.foo()
@@ -0,0 +1,13 @@
// WITH_RUNTIME
class WithCompanion {
companion object {
@JvmStatic
fun foo(x: Int = 1) {}
}
}
object AnObject {
@JvmStatic
fun foo(x: Int = 1) {}
}
@@ -0,0 +1,26 @@
@kotlin.Metadata
public final class AnObject {
public final static field INSTANCE: AnObject
static method <clinit>(): void
private method <init>(): 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 <init>(): void
public synthetic method <init>(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 <clinit>(): void
public method <init>(): void
public final static @kotlin.jvm.JvmStatic method foo(p0: int): void
}
@@ -0,0 +1,26 @@
@kotlin.Metadata
public final class AnObject {
public final static @org.jetbrains.annotations.NotNull field INSTANCE: AnObject
static method <clinit>(): void
private method <init>(): 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 <init>(): void
public synthetic method <init>(@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 <clinit>(): void
public method <init>(): void
public final static @kotlin.jvm.JvmStatic method foo(p0: int): void
}
@@ -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");
@@ -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");
@@ -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");
@@ -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");
@@ -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");