From 9d27771f862ef97733318094a1a9686e49a84d7f Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 12 Sep 2018 18:27:46 +0300 Subject: [PATCH] Fix instance parameter type of inherited declaration in reflection Both for callables obtained via reflection API (KClass.members etc) and for callables obtained via ::-references, the instance parameter is now the class which was used to construct the type at the left-hand side of the reference, NOT the class where the callable is originally declared as is known at compile-time. The reason is to reduce the difference in behavior of KCallable.call vs FunctionN.invoke: the latter always required the subclass instance for a fake override, and it's reasonable that the former would require it as well. Note that in Java reflection, behavior could differ in a similar case. For a simple fake override, Class.getMethod would return the method declared in the base class and that method will accept instances of the base class in invoke. However, it's difficult to rely on this behavior because if there's a bridge for a fake override in the derived class (e.g. when overridden members have different signatures), the returned Method object is accepting the derived class as the receiver. This just confirms the fact that Java reflection operates on a different level of abstraction, namely JVM methods in .class files, which is not applicable to our use cases directly. Another reason not to replicate Java reflection's behavior is the uncertainty as to which member is returned in case there are several in the hierarchy for a given fake override: see the "otherwise one of the methods is chosen arbitrarily" note in javadoc on Class.getMethod. #KT-24170 Fixed --- .../fakeOverrideEqualsHashCode.kt | 25 ++++++++++++++ .../methodsFromAny/fakeOverrideToString.kt | 27 +++++++++++++++ .../methodsFromAny/fakeOverrideToString2.kt | 33 +++++++++++++++++++ .../instanceParameterOfFakeOverride.kt | 31 +++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 20 +++++++++++ .../LightAnalysisModeTestGenerated.java | 20 +++++++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 20 +++++++++++ .../reflect/jvm/internal/KCallableImpl.kt | 14 +++++--- .../kotlin/reflect/jvm/internal/KClassImpl.kt | 3 ++ .../reflect/jvm/internal/KParameterImpl.kt | 20 +++++++++-- .../jvm/internal/ReflectionObjectRenderer.kt | 2 +- .../src/kotlin/reflect/jvm/internal/util.kt | 5 +++ .../IrJsCodegenBoxTestGenerated.java | 20 +++++++++++ .../semantics/JsCodegenBoxTestGenerated.java | 20 +++++++++++ 14 files changed, 251 insertions(+), 9 deletions(-) create mode 100644 compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt create mode 100644 compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt create mode 100644 compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt create mode 100644 compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt diff --git a/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt b/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt new file mode 100644 index 00000000000..d6b78b8c0ce --- /dev/null +++ b/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt @@ -0,0 +1,25 @@ +// IGNORE_BACKEND: JS_IR, JS, NATIVE +// WITH_REFLECT + +import kotlin.test.assertNotEquals + +open class A { + fun foo(t: T) {} +} + +open class B : A() + +class C : B() + +fun box(): String { + val afoo = A::class.members.single { it.name == "foo" } + val bfoo = B::class.members.single { it.name == "foo" } + val cfoo = C::class.members.single { it.name == "foo" } + + assertNotEquals(afoo, bfoo) + assertNotEquals(afoo.hashCode(), bfoo.hashCode()) + assertNotEquals(bfoo, cfoo) + assertNotEquals(bfoo.hashCode(), cfoo.hashCode()) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt b/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt new file mode 100644 index 00000000000..910716c5343 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt @@ -0,0 +1,27 @@ +// IGNORE_BACKEND: JVM_IR, JS_IR, JS, NATIVE +// WITH_REFLECT + +import kotlin.test.assertEquals + +open class A { + fun foo(t: T) {} +} + +open class B : A() + +class C : B() + +fun box(): String { + assertEquals("fun A.foo(T): kotlin.Unit", A::foo.toString()) + assertEquals("fun B.foo(U): kotlin.Unit", B::foo.toString()) + assertEquals("fun C.foo(kotlin.String): kotlin.Unit", C::foo.toString()) + + val afoo = A::class.members.single { it.name == "foo" } + assertEquals("fun A.foo(T): kotlin.Unit", afoo.toString()) + val bfoo = B::class.members.single { it.name == "foo" } + assertEquals("fun B.foo(U): kotlin.Unit", bfoo.toString()) + val cfoo = C::class.members.single { it.name == "foo" } + assertEquals("fun C.foo(kotlin.String): kotlin.Unit", cfoo.toString()) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt b/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt new file mode 100644 index 00000000000..045d9963772 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt @@ -0,0 +1,33 @@ +// IGNORE_BACKEND: JVM_IR, JS_IR, JS, NATIVE +// WITH_REFLECT + +import kotlin.test.assertEquals + +interface I1 { + fun f() + val x: Int +} + +interface I2 { + fun f() + val x: Int +} + +interface I3 { + fun f() + val x: Int +} + +interface I : I2, I1, I3 + +fun box(): String { + assertEquals("fun I.f(): kotlin.Unit", I::f.toString()) + assertEquals("val I.x: kotlin.Int", I::x.toString()) + + val f = I::class.members.single { it.name == "f" } + assertEquals("fun I.f(): kotlin.Unit", f.toString()) + val x = I::class.members.single { it.name == "x" } + assertEquals("val I.x: kotlin.Int", x.toString()) + + return "OK" +} diff --git a/compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt b/compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt new file mode 100644 index 00000000000..81605f77295 --- /dev/null +++ b/compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt @@ -0,0 +1,31 @@ +// IGNORE_BACKEND: JS, NATIVE, JS_IR, JVM_IR +// WITH_REFLECT + +import kotlin.reflect.full.instanceParameter +import kotlin.reflect.jvm.jvmErasure +import kotlin.reflect.jvm.javaType +import kotlin.test.assertEquals + +open class A { + val property = "OK" + + fun function() {} +} + +class B : A() + +fun box(): String { + assertEquals(B::class, B::property.instanceParameter!!.type.jvmErasure) + assertEquals(B::class.java, B::property.instanceParameter!!.type.javaType) + assertEquals(B::class, B::function.instanceParameter!!.type.jvmErasure) + assertEquals(B::class.java, B::function.instanceParameter!!.type.javaType) + + val property = B::class.members.single { it.name == "property" } + val function = B::class.members.single { it.name == "function" } + assertEquals(B::class, property.instanceParameter!!.type.jvmErasure) + assertEquals(B::class.java, property.instanceParameter!!.type.javaType) + assertEquals(B::class, function.instanceParameter!!.type.jvmErasure) + assertEquals(B::class.java, function.instanceParameter!!.type.javaType) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 4084bd2d48b..8a4d1d032aa 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -19097,6 +19097,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/reflection/methodsFromAny/extensionPropertyReceiverToString.kt"); } + @TestMetadata("fakeOverrideEqualsHashCode.kt") + public void testFakeOverrideEqualsHashCode() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt"); + } + + @TestMetadata("fakeOverrideToString.kt") + public void testFakeOverrideToString() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt"); + } + + @TestMetadata("fakeOverrideToString2.kt") + public void testFakeOverrideToString2() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt"); + } + @TestMetadata("functionEqualsHashCode.kt") public void testFunctionEqualsHashCode() throws Exception { runTest("compiler/testData/codegen/box/reflection/methodsFromAny/functionEqualsHashCode.kt"); @@ -19377,6 +19392,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/reflection/parameters/instanceExtensionReceiverAndValueParameters.kt"); } + @TestMetadata("instanceParameterOfFakeOverride.kt") + public void testInstanceParameterOfFakeOverride() throws Exception { + runTest("compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt"); + } + @TestMetadata("isMarkedNullable.kt") public void testIsMarkedNullable() throws Exception { runTest("compiler/testData/codegen/box/reflection/parameters/isMarkedNullable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 4cd86b59388..99d4d22a4ae 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -19097,6 +19097,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/reflection/methodsFromAny/extensionPropertyReceiverToString.kt"); } + @TestMetadata("fakeOverrideEqualsHashCode.kt") + public void testFakeOverrideEqualsHashCode() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt"); + } + + @TestMetadata("fakeOverrideToString.kt") + public void testFakeOverrideToString() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt"); + } + + @TestMetadata("fakeOverrideToString2.kt") + public void testFakeOverrideToString2() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt"); + } + @TestMetadata("functionEqualsHashCode.kt") public void testFunctionEqualsHashCode() throws Exception { runTest("compiler/testData/codegen/box/reflection/methodsFromAny/functionEqualsHashCode.kt"); @@ -19377,6 +19392,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes runTest("compiler/testData/codegen/box/reflection/parameters/instanceExtensionReceiverAndValueParameters.kt"); } + @TestMetadata("instanceParameterOfFakeOverride.kt") + public void testInstanceParameterOfFakeOverride() throws Exception { + runTest("compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt"); + } + @TestMetadata("isMarkedNullable.kt") public void testIsMarkedNullable() throws Exception { runTest("compiler/testData/codegen/box/reflection/parameters/isMarkedNullable.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index d58420169b5..ba5a8521fc0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -19102,6 +19102,21 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/reflection/methodsFromAny/extensionPropertyReceiverToString.kt"); } + @TestMetadata("fakeOverrideEqualsHashCode.kt") + public void testFakeOverrideEqualsHashCode() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt"); + } + + @TestMetadata("fakeOverrideToString.kt") + public void testFakeOverrideToString() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt"); + } + + @TestMetadata("fakeOverrideToString2.kt") + public void testFakeOverrideToString2() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt"); + } + @TestMetadata("functionEqualsHashCode.kt") public void testFunctionEqualsHashCode() throws Exception { runTest("compiler/testData/codegen/box/reflection/methodsFromAny/functionEqualsHashCode.kt"); @@ -19382,6 +19397,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/reflection/parameters/instanceExtensionReceiverAndValueParameters.kt"); } + @TestMetadata("instanceParameterOfFakeOverride.kt") + public void testInstanceParameterOfFakeOverride() throws Exception { + runTest("compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt"); + } + @TestMetadata("isMarkedNullable.kt") public void testIsMarkedNullable() throws Exception { runTest("compiler/testData/codegen/box/reflection/parameters/isMarkedNullable.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt index 23e227c00dc..243a530d1a1 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KCallableImpl.kt @@ -40,12 +40,16 @@ internal abstract class KCallableImpl : KCallable { val result = ArrayList() var index = 0 - if (descriptor.dispatchReceiverParameter != null && !isBound) { - result.add(KParameterImpl(this, index++, KParameter.Kind.INSTANCE) { descriptor.dispatchReceiverParameter!! }) - } + if (!isBound) { + val instanceReceiver = descriptor.instanceReceiverParameter + if (instanceReceiver != null) { + result.add(KParameterImpl(this, index++, KParameter.Kind.INSTANCE) { instanceReceiver }) + } - if (descriptor.extensionReceiverParameter != null && !isBound) { - result.add(KParameterImpl(this, index++, KParameter.Kind.EXTENSION_RECEIVER) { descriptor.extensionReceiverParameter!! }) + val extensionReceiver = descriptor.extensionReceiverParameter + if (extensionReceiver != null) { + result.add(KParameterImpl(this, index++, KParameter.Kind.EXTENSION_RECEIVER) { extensionReceiver }) + } } for (i in descriptor.valueParameters.indices) { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt index 7c70d799c42..1c5e104fc78 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt @@ -182,6 +182,9 @@ internal class KClassImpl(override val jClass: Class) : KDeclaration private val classId: ClassId get() = RuntimeTypeMapper.mapJvmClassToKotlinClassId(jClass) + // Note that we load members from the container's default type, which might be confusing. For example, a function declared in a + // generic class "A" would have "A" as the receiver parameter even if a concrete type like "A" was specified + // in the function reference. Another, maybe slightly less confusing, approach would be to use the star-projected type ("A<*>"). internal val memberScope: MemberScope get() = descriptor.defaultType.memberScope internal val staticScope: MemberScope get() = descriptor.staticScope diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KParameterImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KParameterImpl.kt index 1c821868a95..337c8018e02 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KParameterImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KParameterImpl.kt @@ -16,8 +16,7 @@ package kotlin.reflect.jvm.internal -import org.jetbrains.kotlin.descriptors.ParameterDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.resolve.descriptorUtil.declaresOrInheritsDefaultValue import kotlin.reflect.KParameter import kotlin.reflect.KType @@ -41,7 +40,22 @@ internal class KParameterImpl( } override val type: KType - get() = KTypeImpl(descriptor.type) { callable.caller.parameterTypes[index] } + get() = KTypeImpl(descriptor.type) { + val descriptor = descriptor + + if (descriptor is ReceiverParameterDescriptor && + callable.descriptor.instanceReceiverParameter == descriptor && + callable.descriptor.kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE + ) { + // In case of fake overrides, dispatch receiver type should be computed manually because Caller.parameterTypes returns + // types from Java reflection where receiver is always the declaring class of the original declaration + // (not the class where the fake override is generated, which is returned by KParameter.type) + (callable.descriptor.containingDeclaration as ClassDescriptor).toJavaClass() + ?: throw KotlinReflectionInternalError("Cannot determine receiver Java type of inherited declaration: $descriptor") + } else { + callable.caller.parameterTypes[index] + } + } override val isOptional: Boolean get() = (descriptor as? ValueParameterDescriptor)?.declaresOrInheritsDefaultValue() ?: false diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionObjectRenderer.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionObjectRenderer.kt index 7f7f3aae57d..7151726738c 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionObjectRenderer.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/ReflectionObjectRenderer.kt @@ -33,7 +33,7 @@ internal object ReflectionObjectRenderer { } private fun StringBuilder.appendReceivers(callable: CallableDescriptor) { - val dispatchReceiver = callable.dispatchReceiverParameter + val dispatchReceiver = callable.instanceReceiverParameter val extensionReceiver = callable.extensionReceiverParameter appendReceiverType(dispatchReceiver) diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt index 5c0733d46cf..3a7fdbd831b 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt @@ -182,6 +182,11 @@ internal val CallableMemberDescriptor.isPublicInBytecode: Boolean return (visibility == Visibilities.PUBLIC || visibility == Visibilities.INTERNAL) && !isEffectivelyInlineOnly() } +internal val CallableDescriptor.instanceReceiverParameter: ReceiverParameterDescriptor? + get() = + if (dispatchReceiverParameter != null) (containingDeclaration as ClassDescriptor).thisAsReceiverParameter + else null + internal fun deserializeToDescriptor( moduleAnchor: Class<*>, proto: M, diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java index 154484f23fa..a81115323a2 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/IrJsCodegenBoxTestGenerated.java @@ -17187,6 +17187,21 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/reflection/methodsFromAny/extensionPropertyReceiverToString.kt"); } + @TestMetadata("fakeOverrideEqualsHashCode.kt") + public void testFakeOverrideEqualsHashCode() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt"); + } + + @TestMetadata("fakeOverrideToString.kt") + public void testFakeOverrideToString() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt"); + } + + @TestMetadata("fakeOverrideToString2.kt") + public void testFakeOverrideToString2() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt"); + } + @TestMetadata("functionEqualsHashCode.kt") public void testFunctionEqualsHashCode() throws Exception { runTest("compiler/testData/codegen/box/reflection/methodsFromAny/functionEqualsHashCode.kt"); @@ -17467,6 +17482,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { runTest("compiler/testData/codegen/box/reflection/parameters/instanceExtensionReceiverAndValueParameters.kt"); } + @TestMetadata("instanceParameterOfFakeOverride.kt") + public void testInstanceParameterOfFakeOverride() throws Exception { + runTest("compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt"); + } + @TestMetadata("isMarkedNullable.kt") public void testIsMarkedNullable() throws Exception { runTest("compiler/testData/codegen/box/reflection/parameters/isMarkedNullable.kt"); diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index b14f299b864..eec6d56d513 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -18247,6 +18247,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/reflection/methodsFromAny/extensionPropertyReceiverToString.kt"); } + @TestMetadata("fakeOverrideEqualsHashCode.kt") + public void testFakeOverrideEqualsHashCode() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideEqualsHashCode.kt"); + } + + @TestMetadata("fakeOverrideToString.kt") + public void testFakeOverrideToString() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString.kt"); + } + + @TestMetadata("fakeOverrideToString2.kt") + public void testFakeOverrideToString2() throws Exception { + runTest("compiler/testData/codegen/box/reflection/methodsFromAny/fakeOverrideToString2.kt"); + } + @TestMetadata("functionEqualsHashCode.kt") public void testFunctionEqualsHashCode() throws Exception { runTest("compiler/testData/codegen/box/reflection/methodsFromAny/functionEqualsHashCode.kt"); @@ -18527,6 +18542,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { runTest("compiler/testData/codegen/box/reflection/parameters/instanceExtensionReceiverAndValueParameters.kt"); } + @TestMetadata("instanceParameterOfFakeOverride.kt") + public void testInstanceParameterOfFakeOverride() throws Exception { + runTest("compiler/testData/codegen/box/reflection/parameters/instanceParameterOfFakeOverride.kt"); + } + @TestMetadata("isMarkedNullable.kt") public void testIsMarkedNullable() throws Exception { runTest("compiler/testData/codegen/box/reflection/parameters/isMarkedNullable.kt");