Support 'is/as FunctionN<...>' and 'invoke' for KFunction instances
This commit is contained in:
@@ -0,0 +1,36 @@
|
|||||||
|
// WITH_REFLECT
|
||||||
|
// FILE: FromJava.java
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable;
|
||||||
|
import kotlin.jvm.functions.Function1;
|
||||||
|
import kotlin.jvm.functions.Function2;
|
||||||
|
import kotlin.jvm.functions.Function3;
|
||||||
|
|
||||||
|
public class FromJava {
|
||||||
|
public static String test(KCallable<?> x) {
|
||||||
|
if (!(x instanceof Function1)) return "Fail 6";
|
||||||
|
if (!(x instanceof Function2)) return "Fail 7";
|
||||||
|
if (!(x instanceof Function3)) return "Fail 8";
|
||||||
|
return "OK";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// FILE: test.kt
|
||||||
|
|
||||||
|
class Foo {
|
||||||
|
fun bar(x: Int): Int = x + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val bar = Foo::class.members.single { it.name == "bar" }
|
||||||
|
|
||||||
|
if (bar is Function1<*, *>) return "Fail 1"
|
||||||
|
if (bar !is Function2<*, *, *>) return "Fail 2"
|
||||||
|
if (bar is Function3<*, *, *, *>) return "Fail 3"
|
||||||
|
|
||||||
|
bar as? Function2<Foo, Int, Int> ?: return "Fail 4"
|
||||||
|
|
||||||
|
if (bar(Foo(), 42) != 43) return "Fail 5"
|
||||||
|
|
||||||
|
return FromJava.test(bar)
|
||||||
|
}
|
||||||
@@ -12270,6 +12270,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("instanceOfFunction.kt")
|
||||||
|
public void testInstanceOfFunction() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/instanceOfFunction.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("javaClassGetFunctions.kt")
|
@TestMetadata("javaClassGetFunctions.kt")
|
||||||
public void testJavaClassGetFunctions() throws Exception {
|
public void testJavaClassGetFunctions() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/javaClassGetFunctions.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/reflection/functions/javaClassGetFunctions.kt");
|
||||||
|
|||||||
@@ -29,15 +29,18 @@ internal abstract class FunctionCaller<out M : Member>(
|
|||||||
internal val instanceClass: Class<*>?,
|
internal val instanceClass: Class<*>?,
|
||||||
valueParameterTypes: Array<Type>
|
valueParameterTypes: Array<Type>
|
||||||
) {
|
) {
|
||||||
internal val parameterTypes: List<Type> =
|
val parameterTypes: List<Type> =
|
||||||
instanceClass?.let { listOf(it, *valueParameterTypes) } ?:
|
instanceClass?.let { listOf(it, *valueParameterTypes) } ?:
|
||||||
valueParameterTypes.toList()
|
valueParameterTypes.toList()
|
||||||
|
|
||||||
|
val arity: Int
|
||||||
|
get() = parameterTypes.size
|
||||||
|
|
||||||
abstract fun call(args: Array<*>): Any?
|
abstract fun call(args: Array<*>): Any?
|
||||||
|
|
||||||
protected open fun checkArguments(args: Array<*>) {
|
protected open fun checkArguments(args: Array<*>) {
|
||||||
if (parameterTypes.size != args.size) {
|
if (arity != args.size) {
|
||||||
throw IllegalArgumentException("Callable expects ${parameterTypes.size} arguments, but ${args.size} were provided.")
|
throw IllegalArgumentException("Callable expects $arity arguments, but ${args.size} were provided.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package kotlin.reflect.jvm.internal
|
||||||
|
|
||||||
|
import kotlin.reflect.KCallable
|
||||||
|
|
||||||
|
internal interface FunctionWithAllInvokes :
|
||||||
|
// (0..22).forEach { n -> println("Function$n<" + (0..n).joinToString { "Any?" } + ">,") }
|
||||||
|
Function0<Any?>,
|
||||||
|
Function1<Any?, Any?>,
|
||||||
|
Function2<Any?, Any?, Any?>,
|
||||||
|
Function3<Any?, Any?, Any?, Any?>,
|
||||||
|
Function4<Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function5<Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function6<Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function7<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function8<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function9<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function10<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function11<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function12<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function13<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function14<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function15<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function16<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function17<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function18<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function19<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function20<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function21<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
Function22<Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?, Any?>,
|
||||||
|
KCallable<Any?>
|
||||||
|
{
|
||||||
|
// (0..22).forEach { n -> println("override fun invoke(" + (1..n).joinToString { "p$it: Any?" } + "): Any? = call(" + (1..n).joinToString { "p$it" } + ")") }
|
||||||
|
override fun invoke(): Any? = call()
|
||||||
|
override fun invoke(p1: Any?): Any? = call(p1)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?): Any? = call(p1, p2)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?): Any? = call(p1, p2, p3)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?): Any? = call(p1, p2, p3, p4)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?): Any? = call(p1, p2, p3, p4, p5)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?): Any? = call(p1, p2, p3, p4, p5, p6)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?, p21: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21)
|
||||||
|
override fun invoke(p1: Any?, p2: Any?, p3: Any?, p4: Any?, p5: Any?, p6: Any?, p7: Any?, p8: Any?, p9: Any?, p10: Any?, p11: Any?, p12: Any?, p13: Any?, p14: Any?, p15: Any?, p16: Any?, p17: Any?, p18: Any?, p19: Any?, p20: Any?, p21: Any?, p22: Any?): Any? = call(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22)
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ internal class KFunctionImpl private constructor(
|
|||||||
name: String,
|
name: String,
|
||||||
private val signature: String,
|
private val signature: String,
|
||||||
descriptorInitialValue: FunctionDescriptor?
|
descriptorInitialValue: FunctionDescriptor?
|
||||||
) : KFunction<Any?>, KCallableImpl<Any?>, FunctionImpl {
|
) : KFunction<Any?>, KCallableImpl<Any?>, FunctionImpl, FunctionWithAllInvokes {
|
||||||
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : this(container, name, signature, null)
|
constructor(container: KDeclarationContainerImpl, name: String, signature: String) : this(container, name, signature, null)
|
||||||
|
|
||||||
constructor(container: KDeclarationContainerImpl, descriptor: FunctionDescriptor) : this(
|
constructor(container: KDeclarationContainerImpl, descriptor: FunctionDescriptor) : this(
|
||||||
@@ -103,11 +103,7 @@ internal class KFunctionImpl private constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getArity(): Int {
|
override fun getArity() = caller.arity
|
||||||
return descriptor.valueParameters.size +
|
|
||||||
(if (descriptor.dispatchReceiverParameter != null) 1 else 0) +
|
|
||||||
(if (descriptor.extensionReceiverParameter != null) 1 else 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
override val isInline: Boolean
|
override val isInline: Boolean
|
||||||
get() = descriptor.isInline
|
get() = descriptor.isInline
|
||||||
|
|||||||
Reference in New Issue
Block a user