diff --git a/compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt b/compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt index b4251bc1ab5..e19d65c69b4 100644 --- a/compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt +++ b/compiler/testData/codegen/box/reflection/callBy/inlineClassFunctionsAndConstructors.kt @@ -14,33 +14,32 @@ class C { fun topLevel(c: S, d: S = S("d")): S = c + d -/* TODO: support constructors with inline class types in the signature (KT-26765) class D(e: S, f: S = S("f")) { val result = e + f } -*/ fun S.extension(h: S = S("h")): S = this + h fun box(): String { assertEquals(S("ab"), C().member(S("a"))) - assertEquals(S("ab"), C::member.callBy(C::member.parameters.filter { it.name != "b" }.associate { - it to (if (it.name == "a") S("a") else C()) - })) + assertEquals( + S("ab"), + C::member.callBy(C::member.parameters.filter { it.name != "b" }.associateWith { (if (it.name == "a") S("a") else C()) }) + ) assertEquals(S("cd"), topLevel(S("c"))) - assertEquals(S("cd"), ::topLevel.callBy(::topLevel.parameters.filter { it.name != "d" }.associate { it to S("c") })) + assertEquals(S("cd"), ::topLevel.callBy(::topLevel.parameters.filter { it.name != "d" }.associateWith { S("c") })) - // assertEquals(S("ef"), ::D.callBy(::D.parameters.filter { it.name != "f" }.associate { it to S("e") }).result) + assertEquals(S("ef"), ::D.callBy(::D.parameters.filter { it.name != "f" }.associateWith { S("e") }).result) assertEquals(S("gh"), S("g").extension()) - assertEquals(S("gh"), S::extension.callBy(S::extension.parameters.filter { it.name != "h" }.associate { it to S("g") })) + assertEquals(S("gh"), S::extension.callBy(S::extension.parameters.filter { it.name != "h" }.associateWith { S("g") })) val boundMember = C()::member - assertEquals(S("ab"), boundMember.callBy(boundMember.parameters.associate { it to S(it.name!!) })) + assertEquals(S("ab"), boundMember.callBy(boundMember.parameters.associateWith { S(it.name!!) })) val boundExtension = S("g")::extension - assertEquals(S("gh"), boundExtension.callBy(boundExtension.parameters.associate { it to S(it.name!!) })) + assertEquals(S("gh"), boundExtension.callBy(boundExtension.parameters.associateWith { S(it.name!!) })) return "OK" } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt index e33d9a3ec1c..d4e77398145 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KDeclarationContainerImpl.kt @@ -236,7 +236,15 @@ internal abstract class KDeclarationContainerImpl : ClassBasedDeclarationContain repeat((valueParameters.size + Integer.SIZE - 1) / Integer.SIZE) { result.add(Integer.TYPE) } - result.add(if (isConstructor) DEFAULT_CONSTRUCTOR_MARKER else Any::class.java) + + if (isConstructor) { + // Constructors that include the value class as an argument will include DEFAULT_CONSTRUCTOR_MARKER as an argument, + // regardless of whether there is a default argument. + // On the other hand, when searching for the default constructor, + // DEFAULT_CONSTRUCTOR_MARKER needs to be present only at the end, so it is removed here. + result.remove(DEFAULT_CONSTRUCTOR_MARKER) + result.add(DEFAULT_CONSTRUCTOR_MARKER) + } else result.add(Any::class.java) } private fun loadParameterTypes(desc: String): List> { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt index 4b67866b3bd..a8308479c44 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KFunctionImpl.kt @@ -76,7 +76,7 @@ internal class KFunctionImpl private constructor( when (member) { is Constructor<*> -> - createConstructorCaller(member, descriptor) + createConstructorCaller(member, descriptor, false) is Method -> when { !Modifier.isStatic(member.modifiers) -> createInstanceMethodCaller(member) @@ -112,7 +112,7 @@ internal class KFunctionImpl private constructor( when (member) { is Constructor<*> -> - createConstructorCaller(member, descriptor) + createConstructorCaller(member, descriptor, true) is Method -> when { // Note that static $default methods for @JvmStatic functions are generated differently in objects and companion objects. // In objects, $default's signature does _not_ contain the additional object instance parameter, @@ -140,8 +140,10 @@ internal class KFunctionImpl private constructor( private fun createInstanceMethodCaller(member: Method) = if (isBound) CallerImpl.Method.BoundInstance(member, boundReceiver) else CallerImpl.Method.Instance(member) - private fun createConstructorCaller(member: Constructor<*>, descriptor: FunctionDescriptor): CallerImpl> { - return if (shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor)) { + private fun createConstructorCaller( + member: Constructor<*>, descriptor: FunctionDescriptor, isDefault: Boolean + ): CallerImpl> { + return if (!isDefault && shouldHideConstructorDueToInlineClassTypeValueParameters(descriptor)) { if (isBound) CallerImpl.AccessorForHiddenBoundConstructor(member, boundReceiver) else