diff --git a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java index 626b43d6db6..043d3423b26 100644 --- a/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java +++ b/compiler/fir/fir2ir/tests/org/jetbrains/kotlin/fir/Fir2IrTextTestGenerated.java @@ -66,6 +66,11 @@ public class Fir2IrTextTestGenerated extends AbstractFir2IrTextTest { runTest("compiler/testData/ir/irText/classes/classes.kt"); } + @TestMetadata("cloneable.kt") + public void testCloneable() throws Exception { + runTest("compiler/testData/ir/irText/classes/cloneable.kt"); + } + @TestMetadata("companionObject.kt") public void testCompanionObject() throws Exception { runTest("compiler/testData/ir/irText/classes/companionObject.kt"); diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index bbddfb696d4..905a3921791 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -20,8 +20,10 @@ import org.jetbrains.kotlin.backend.jvm.ir.eraseTypeParameters import org.jetbrains.kotlin.backend.jvm.ir.isFromJava import org.jetbrains.kotlin.backend.jvm.ir.isJvmAbstract import org.jetbrains.kotlin.backend.jvm.lower.inlineclasses.unboxInlineClass +import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.codegen.AsmUtil import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* @@ -407,16 +409,31 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass overriddenSymbols = irFunction.overriddenSymbols.toList() } + private fun getBridgeVisibility(bridge: Bridge): DescriptorVisibility { + // Even though kotlin.Cloneable#clone() is protected, corresponding bridge is 'public' in JVM. + if (bridge.overridden.name.asString() == "clone" && + bridge.overridden.parentAsClass.hasEqualFqName(StandardNames.FqNames.cloneable.toSafe()) + ) { + return DescriptorVisibilities.PUBLIC + } + + val overriddenVisibility = bridge.overridden.visibility + // Internal functions can be overridden by non-internal functions, which changes their names since the names of internal + // functions are mangled. In order to avoid mangling the name twice we reset the visibility for bridges to internal + // functions to public and use the mangled name directly. + return if (overriddenVisibility == DescriptorVisibilities.INTERNAL) + DescriptorVisibilities.PUBLIC + else + overriddenVisibility + } + private fun IrClass.addBridge(bridge: Bridge, target: IrSimpleFunction): IrSimpleFunction = addFunction { startOffset = this@addBridge.startOffset endOffset = this@addBridge.startOffset modality = Modality.OPEN origin = IrDeclarationOrigin.BRIDGE - // Internal functions can be overridden by non-internal functions, which changes their names since the names of internal - // functions are mangled. In order to avoid mangling the name twice we reset the visibility for bridges to internal - // functions to public and use the mangled name directly. - visibility = bridge.overridden.visibility.takeUnless { it == DescriptorVisibilities.INTERNAL } ?: DescriptorVisibilities.PUBLIC + visibility = getBridgeVisibility(bridge) name = Name.identifier(bridge.signature.name) returnType = bridge.overridden.returnType.eraseTypeParameters() isSuspend = bridge.overridden.isSuspend diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt index 85e169f3ac5..795c0545088 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InheritedDefaultMethodsOnClassesLowering.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext +import org.jetbrains.kotlin.backend.common.ir.allOverridden import org.jetbrains.kotlin.backend.common.ir.isMethodOfAny import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom import org.jetbrains.kotlin.backend.common.lower.createIrBuilder @@ -16,19 +17,17 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.ir.* +import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.config.JvmDefaultMode -import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.irBlockBody import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irReturn -import org.jetbrains.kotlin.ir.declarations.IrClass -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrTypeOperator @@ -46,14 +45,45 @@ internal val inheritedDefaultMethodsOnClassesPhase = makeIrFilePhase( private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendContext) : ClassLoweringPass { override fun lower(irClass: IrClass) { if (!irClass.isJvmInterface) { - irClass.declarations.transformInPlace { declaration -> - (declaration as? IrSimpleFunction)?.findInterfaceImplementation(context.state.jvmDefaultMode)?.let { implementation -> - generateDelegationToDefaultImpl(implementation, declaration) - } ?: declaration + irClass.declarations.transformInPlace { + transformMemberDeclaration(it) } } } + private fun transformMemberDeclaration(declaration: IrDeclaration): IrDeclaration { + if (declaration !is IrSimpleFunction) return declaration + + if (declaration.isFakeOverride && declaration.name.asString() == "clone") { + val overriddenFunctions = declaration.allOverridden(false) + val cloneFun = overriddenFunctions.find { it.parentAsClass.hasEqualFqName(StandardNames.FqNames.cloneable.toSafe()) } + if (cloneFun != null && overriddenFunctions.all { it.isFakeOverride || it == cloneFun }) { + return generateCloneImplementation(declaration, cloneFun) + } + } + + val implementation = declaration.findInterfaceImplementation(context.state.jvmDefaultMode) + ?: return declaration + return generateDelegationToDefaultImpl(implementation, declaration) + } + + private fun generateCloneImplementation(fakeOverride: IrSimpleFunction, cloneFun: IrSimpleFunction): IrSimpleFunction { + assert(fakeOverride.isFakeOverride) + val irFunction = context.cachedDeclarations.getDefaultImplsRedirection(fakeOverride) + val irClass = fakeOverride.parentAsClass + val classStartOffset = irClass.startOffset + context.createJvmIrBuilder(irFunction.symbol, classStartOffset, classStartOffset).apply { + irFunction.body = irBlockBody { + +irReturn( + irCall(cloneFun, origin = null, superQualifierSymbol = cloneFun.parentAsClass.symbol).apply { + dispatchReceiver = irGet(irFunction.dispatchReceiverParameter!!) + } + ) + } + } + return irFunction + } + private fun generateDelegationToDefaultImpl( interfaceImplementation: IrSimpleFunction, classOverride: IrSimpleFunction diff --git a/compiler/testData/codegen/bytecodeListing/cloneable.kt b/compiler/testData/codegen/bytecodeListing/cloneable.kt new file mode 100644 index 00000000000..5326350fbb9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/cloneable.kt @@ -0,0 +1,19 @@ +class A : Cloneable + +interface I : Cloneable + +interface I2 : Cloneable { + override fun clone(): Any +} + +class C : I + +class OC : I { + override fun clone(): OC = OC() +} + +abstract class ACC : Cloneable + +abstract class ACI : I + +abstract class ACI2 : I2 \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeListing/cloneable.txt b/compiler/testData/codegen/bytecodeListing/cloneable.txt new file mode 100644 index 00000000000..7f697cf1fb3 --- /dev/null +++ b/compiler/testData/codegen/bytecodeListing/cloneable.txt @@ -0,0 +1,60 @@ +@kotlin.Metadata +public final class A { + // source: 'cloneable.kt' + public method (): void + public @org.jetbrains.annotations.NotNull method clone(): java.lang.Object +} + +@kotlin.Metadata +public abstract class ACC { + // source: 'cloneable.kt' + public method (): void + public @org.jetbrains.annotations.NotNull method clone(): java.lang.Object +} + +@kotlin.Metadata +public abstract class ACI { + // source: 'cloneable.kt' + public method (): void + public @org.jetbrains.annotations.NotNull method clone(): java.lang.Object +} + +@kotlin.Metadata +public abstract class ACI2 { + // source: 'cloneable.kt' + public method (): void +} + +@kotlin.Metadata +public final class C { + // source: 'cloneable.kt' + public method (): void + public @org.jetbrains.annotations.NotNull method clone(): java.lang.Object +} + +@kotlin.Metadata +public final class I$DefaultImpls { + // source: 'cloneable.kt' + public static @org.jetbrains.annotations.NotNull method clone(@org.jetbrains.annotations.NotNull p0: I): java.lang.Object + public final inner class I$DefaultImpls +} + +@kotlin.Metadata +public interface I { + // source: 'cloneable.kt' + public final inner class I$DefaultImpls +} + +@kotlin.Metadata +public interface I2 { + // source: 'cloneable.kt' + public abstract @org.jetbrains.annotations.NotNull method clone(): java.lang.Object +} + +@kotlin.Metadata +public final class OC { + // source: 'cloneable.kt' + public method (): void + public @org.jetbrains.annotations.NotNull method clone(): OC + public synthetic bridge method clone(): java.lang.Object +} diff --git a/compiler/testData/ir/irText/classes/cloneable.fir.txt b/compiler/testData/ir/irText/classes/cloneable.fir.txt new file mode 100644 index 00000000000..1e1f2c778b5 --- /dev/null +++ b/compiler/testData/ir/irText/classes/cloneable.fir.txt @@ -0,0 +1,92 @@ +FILE fqName: fileName:/cloneable.kt + CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Cloneable] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.A + CONSTRUCTOR visibility:public <> () returnType:.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Cloneable]' + FUN FAKE_OVERRIDE name:clone visibility:protected modality:OPEN <> ($this:kotlin.Cloneable) returnType:kotlin.Any [fake_override] + overridden: + protected open fun clone (): kotlin.Any declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Cloneable + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:I modality:ABSTRACT visibility:public superTypes:[kotlin.Cloneable] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.I + FUN FAKE_OVERRIDE name:clone visibility:protected modality:OPEN <> ($this:kotlin.Cloneable) returnType:kotlin.Any [fake_override] + overridden: + protected open fun clone (): kotlin.Any declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Cloneable + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:C modality:FINAL visibility:public superTypes:[.I] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C + CONSTRUCTOR visibility:public <> () returnType:.C [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[.I]' + FUN FAKE_OVERRIDE name:clone visibility:protected modality:OPEN <> ($this:kotlin.Cloneable) returnType:kotlin.Any [fake_override] + overridden: + protected open fun clone (): kotlin.Any declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Cloneable + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:OC modality:FINAL visibility:public superTypes:[.I] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.OC + CONSTRUCTOR visibility:public <> () returnType:.OC [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:OC modality:FINAL visibility:public superTypes:[.I]' + FUN name:clone visibility:protected modality:FINAL <> ($this:.OC) returnType:.OC + overridden: + protected open fun clone (): kotlin.Any declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:.OC + BLOCK_BODY + RETURN type=kotlin.Nothing from='protected final fun clone (): .OC declared in .OC' + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .OC' type=.OC origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [operator] declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String declared in kotlin.Any + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/testData/ir/irText/classes/cloneable.kt b/compiler/testData/ir/irText/classes/cloneable.kt new file mode 100644 index 00000000000..2152a490e6d --- /dev/null +++ b/compiler/testData/ir/irText/classes/cloneable.kt @@ -0,0 +1,9 @@ +class A : Cloneable + +interface I : Cloneable + +class C : I + +class OC : I { + override fun clone(): OC = OC() +} \ No newline at end of file diff --git a/compiler/testData/ir/irText/classes/cloneable.txt b/compiler/testData/ir/irText/classes/cloneable.txt new file mode 100644 index 00000000000..e5a7fd8e16f --- /dev/null +++ b/compiler/testData/ir/irText/classes/cloneable.txt @@ -0,0 +1,92 @@ +FILE fqName: fileName:/cloneable.kt + CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Cloneable] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.A + CONSTRUCTOR visibility:public <> () returnType:.A [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:A modality:FINAL visibility:public superTypes:[kotlin.Cloneable]' + FUN FAKE_OVERRIDE name:clone visibility:protected modality:OPEN <> ($this:kotlin.Cloneable) returnType:kotlin.Any [fake_override] + overridden: + protected open fun clone (): kotlin.Any declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Cloneable + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS INTERFACE name:I modality:ABSTRACT visibility:public superTypes:[kotlin.Cloneable] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.I + FUN FAKE_OVERRIDE name:clone visibility:protected modality:OPEN <> ($this:kotlin.Cloneable) returnType:kotlin.Any [fake_override] + overridden: + protected open fun clone (): kotlin.Any declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Cloneable + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in kotlin.Cloneable + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:C modality:FINAL visibility:public superTypes:[.I] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.C + CONSTRUCTOR visibility:public <> () returnType:.C [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:C modality:FINAL visibility:public superTypes:[.I]' + FUN FAKE_OVERRIDE name:clone visibility:protected modality:OPEN <> ($this:kotlin.Cloneable) returnType:kotlin.Any [fake_override] + overridden: + protected open fun clone (): kotlin.Any [fake_override] declared in .I + $this: VALUE_PARAMETER name: type:kotlin.Cloneable + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .I + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .I + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .I + $this: VALUE_PARAMETER name: type:kotlin.Any + CLASS CLASS name:OC modality:FINAL visibility:public superTypes:[.I] + $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.OC + CONSTRUCTOR visibility:public <> () returnType:.OC [primary] + BLOCK_BODY + DELEGATING_CONSTRUCTOR_CALL 'public constructor () [primary] declared in kotlin.Any' + INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:OC modality:FINAL visibility:public superTypes:[.I]' + FUN name:clone visibility:protected modality:OPEN <> ($this:.OC) returnType:.OC + overridden: + protected open fun clone (): kotlin.Any [fake_override] declared in .I + $this: VALUE_PARAMETER name: type:.OC + BLOCK_BODY + RETURN type=kotlin.Nothing from='protected open fun clone (): .OC declared in .OC' + CONSTRUCTOR_CALL 'public constructor () [primary] declared in .OC' type=.OC origin=null + FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] + overridden: + public open fun equals (other: kotlin.Any?): kotlin.Boolean [fake_override,operator] declared in .I + $this: VALUE_PARAMETER name: type:kotlin.Any + VALUE_PARAMETER name:other index:0 type:kotlin.Any? + FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] + overridden: + public open fun hashCode (): kotlin.Int [fake_override] declared in .I + $this: VALUE_PARAMETER name: type:kotlin.Any + FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] + overridden: + public open fun toString (): kotlin.String [fake_override] declared in .I + $this: VALUE_PARAMETER name: type:kotlin.Any diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java index dd8f24d5a5b..99ce2b1e4f2 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeListingTestGenerated.java @@ -44,6 +44,11 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest { runTest("compiler/testData/codegen/bytecodeListing/callableNameIntrinsic.kt"); } + @TestMetadata("cloneable.kt") + public void testCloneable() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/cloneable.kt"); + } + @TestMetadata("companionObjectVisibility_after.kt") public void testCompanionObjectVisibility_after() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java index ce84db6b03b..e4ff24726b6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBytecodeListingTestGenerated.java @@ -44,6 +44,11 @@ public class IrBytecodeListingTestGenerated extends AbstractIrBytecodeListingTes runTest("compiler/testData/codegen/bytecodeListing/callableNameIntrinsic.kt"); } + @TestMetadata("cloneable.kt") + public void testCloneable() throws Exception { + runTest("compiler/testData/codegen/bytecodeListing/cloneable.kt"); + } + @TestMetadata("companionObjectVisibility_after.kt") public void testCompanionObjectVisibility_after() throws Exception { runTest("compiler/testData/codegen/bytecodeListing/companionObjectVisibility_after.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java index 1d19f9b1e6e..7123dd8f3ee 100644 --- a/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/ir/IrTextTestCaseGenerated.java @@ -65,6 +65,11 @@ public class IrTextTestCaseGenerated extends AbstractIrTextTestCase { runTest("compiler/testData/ir/irText/classes/classes.kt"); } + @TestMetadata("cloneable.kt") + public void testCloneable() throws Exception { + runTest("compiler/testData/ir/irText/classes/cloneable.kt"); + } + @TestMetadata("companionObject.kt") public void testCompanionObject() throws Exception { runTest("compiler/testData/ir/irText/classes/companionObject.kt");