La function en línea de Kotlin no funciona correctamente

Mientras trabajaba en un proyecto con QtJambi como el juego de herramientas GUI, intentaba codificar una biblioteca para facilitar la connection de señales y ranuras. Encontré el siguiente problema.

Aquí está mi código:

inline fun QSignalEmitter.Signal0.connect( inlineOptions(InlineOption.ONLY_LOCAL_RETURN) action: () -> Unit) { connect(object { fun execute() { action() } }, "execute()") } inline fun <reified A> QSignalEmitter.Signal1<A>.connect( inlineOptions(InlineOption.ONLY_LOCAL_RETURN) action: (A) -> Unit) { connect(object { fun execute(a: A) { action(a) } }, "execute(" + javaClass<A>().getCanonicalName() + ")") } 

Esto funciona para la primera function de connection cuando no se esperan parameters generics. Pero para la segunda function de connection cuando hago algo como:

 QCheckBox().toggled.connect({ print(it) }) 

Obtuve el siguiente error:

 Exception in thread "main" com.trolltech.qt.QNoSuchSlotException: Could not find slot with signature: execute(java.lang.Boolean) Possible matching methods: com.TestPackage$Test$f1214d02$main$$inlined$connect$1.execute(java.lang.Object) at com.trolltech.qt.QSignalEmitter$AbstractSignal.connect(QSignalEmitter.java:72) at com.trolltech.qt.QSignalEmitter$AbstractSignal.connect(QSignalEmitter.java:132) at com.TestPackage$Test$f1214d02.main(Test.kt:9) at com.TestPackage.main(Test.kt:1) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:483) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134) 

¿Cuál es la causa posible y cómo puedo evitarlo?

Editar: ejemplo de uso

 inline fun <reified A> QSignalEmitter.Signal1<A>.connect(noinline action: (A) -> Unit) { connect(action, "invoke(${javaClass<A>()})") } fun main(args: Array<String>) { QApplication.initialize(args) val widget = QWidget() val button = QPushButton("Say Hello") button.clicked.connect { println("Hello World") } val layout = QFormLayout(widget) layout.addWidget(button) widget.show() QApplication.execStatic() } 

Kotlin Bytecode

 // ================_DefaultPackage$QtExtensions$7d5c0ac6.class ================= // class version 50.0 (50) // access flags 0x11 public final class _DefaultPackage$QtExtensions$7d5c0ac6 { // access flags 0x19 // signature <A:Ljava/lang/Object;>(Lcom/trolltech/qt/QSignalEmitter$Signal1<TA;>;Lkotlin/jvm/functions/Function1<-TA;+Lkotlin/Unit;>;)V // declaration: void connect<A>(com.trolltech.qt.QSignalEmitter$Signal1<A>, kotlin.jvm.functions.Function1<? super A, ? extends kotlin.Unit>) public final static connect(Lcom/trolltech/qt/QSignalEmitter$Signal1;Lkotlin/jvm/functions/Function1;)V @Lkotlin/inline;() // invisible @Ljet/runtime/typeinfo/JetValueParameter;(name="$receiver") // parameter 0 @Ljet/runtime/typeinfo/JetValueParameter;(name="action") // parameter 1 @Lkotlin/noinline;() // invisible, parameter 1 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 L1 ALOAD 0 LDC "$receiver" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V ALOAD 1 LDC "action" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L2 LINENUMBER 9 L2 ALOAD 0 ALOAD 1 NEW java/lang/StringBuilder DUP INVOKESPECIAL java/lang/StringBuilder.<init> ()V LDC "invoke(" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; LDC "A" INVOKESTATIC kotlin/jvm/internal/Intrinsics.reifyJavaClass (Ljava/lang/String;)V LDC Ljava/lang/Object;.class INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/Object;)Ljava/lang/StringBuilder; LDC ")" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String; INVOKEVIRTUAL com/trolltech/qt/QSignalEmitter$Signal1.connect (Ljava/lang/Object;Ljava/lang/String;)V L3 LINENUMBER 10 L3 RETURN L4 LOCALVARIABLE $receiver Lcom/trolltech/qt/QSignalEmitter$Signal1; L0 L4 0 LOCALVARIABLE action Lkotlin/jvm/functions/Function1; L0 L4 1 MAXSTACK = 4 MAXLOCALS = 2 // access flags 0x19 public final static main([Ljava/lang/String;)V @Ljet/runtime/typeinfo/JetValueParameter;(name="args") // parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 L1 ALOAD 0 LDC "args" INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkParameterIsNotNull (Ljava/lang/Object;Ljava/lang/String;)V L2 LINENUMBER 13 L2 ALOAD 0 INVOKESTATIC com/trolltech/qt/gui/QApplication.initialize ([Ljava/lang/String;)V L3 LINENUMBER 15 L3 NEW com/trolltech/qt/gui/QWidget DUP INVOKESPECIAL com/trolltech/qt/gui/QWidget.<init> ()V ASTORE 1 L4 L5 LINENUMBER 16 L5 NEW com/trolltech/qt/gui/QPushButton DUP LDC "Say Hello" INVOKESPECIAL com/trolltech/qt/gui/QPushButton.<init> (Ljava/lang/String;)V ASTORE 2 L6 L7 LINENUMBER 17 L7 ALOAD 2 CHECKCAST com/trolltech/qt/gui/QAbstractButton GETFIELD com/trolltech/qt/gui/QAbstractButton.clicked : Lcom/trolltech/qt/QSignalEmitter$Signal1; ASTORE 3 GETSTATIC _DefaultPackage$QtExtensions$7d5c0ac6$main$1.INSTANCE$ : L_DefaultPackage$QtExtensions$7d5c0ac6$main$1; CHECKCAST kotlin/jvm/functions/Function1 ASTORE 4 NOP L8 L9 L10 LINENUMBER 9 L10 ALOAD 3 ALOAD 4 NEW java/lang/StringBuilder DUP INVOKESPECIAL java/lang/StringBuilder.<init> ()V LDC "invoke(" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; LDC Ljava/lang/Boolean;.class INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/Object;)Ljava/lang/StringBuilder; LDC ")" INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder; INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String; INVOKEVIRTUAL com/trolltech/qt/QSignalEmitter$Signal1.connect (Ljava/lang/Object;Ljava/lang/String;)V L11 LINENUMBER 10 L11 L12 L13 L14 LINENUMBER 20 L14 NEW com/trolltech/qt/gui/QFormLayout DUP ALOAD 1 INVOKESPECIAL com/trolltech/qt/gui/QFormLayout.<init> (Lcom/trolltech/qt/gui/QWidget;)V ASTORE 3 L15 L16 LINENUMBER 21 L16 ALOAD 3 ALOAD 2 CHECKCAST com/trolltech/qt/gui/QWidget INVOKEVIRTUAL com/trolltech/qt/gui/QFormLayout.addWidget (Lcom/trolltech/qt/gui/QWidget;)V L17 LINENUMBER 23 L17 ALOAD 1 INVOKEVIRTUAL com/trolltech/qt/gui/QWidget.show ()V L18 LINENUMBER 24 L18 INVOKESTATIC com/trolltech/qt/gui/QApplication.execStatic ()I POP L19 LINENUMBER 25 L19 RETURN L20 LOCALVARIABLE $receiver Lcom/trolltech/qt/QSignalEmitter$Signal1; L8 L12 3 LOCALVARIABLE action Lkotlin/jvm/functions/Function1; L8 L12 4 LOCALVARIABLE layout Lcom/trolltech/qt/gui/QFormLayout; L15 L20 3 LOCALVARIABLE button Lcom/trolltech/qt/gui/QPushButton; L6 L20 2 LOCALVARIABLE widget Lcom/trolltech/qt/gui/QWidget; L4 L20 1 LOCALVARIABLE args [Ljava/lang/String; L0 L20 0 MAXSTACK = 4 MAXLOCALS = 5 @Lkotlin/jvm/internal/KotlinSyntheticClass;(abiVersion=23, kind=Lkotlin/jvm/internal/KotlinSyntheticClass$Kind;.PACKAGE_PART) // access flags 0x19 public final static INNERCLASS _DefaultPackage$QtExtensions$7d5c0ac6$main$1 null null // compiled from: QtExtensions.kt // debug info: SMAP QtExtensions.kt Kotlin *S Kotlin *F + 1 QtExtensions.kt _DefaultPackage *L 1#1,25:1 *E } // ================_DefaultPackage$QtExtensions$7d5c0ac6$main$1.class ================= // class version 50.0 (50) // access flags 0x30 // signature Lkotlin/jvm/internal/Lambda;Lkotlin/jvm/functions/Function1<Ljava/lang/Boolean;Lkotlin/Unit;>; // declaration: _DefaultPackage$QtExtensions$7d5c0ac6$main$1 extends kotlin.jvm.internal.Lambda implements kotlin.jvm.functions.Function1<java.lang.Boolean, kotlin.Unit> final class _DefaultPackage$QtExtensions$7d5c0ac6$main$1 extends kotlin/jvm/internal/Lambda implements kotlin/jvm/functions/Function1 { // access flags 0x41 public bridge invoke(Ljava/lang/Object;)Ljava/lang/Object; ALOAD 0 ALOAD 1 CHECKCAST java/lang/Boolean INVOKEVIRTUAL _DefaultPackage$QtExtensions$7d5c0ac6$main$1.invoke (Ljava/lang/Boolean;)V GETSTATIC kotlin/Unit.INSTANCE$ : Lkotlin/Unit; ARETURN MAXSTACK = 2 MAXLOCALS = 2 // access flags 0x11 public final invoke(Ljava/lang/Boolean;)V @Ljet/runtime/typeinfo/JetValueParameter;(name="it") // parameter 0 L0 L1 L2 LINENUMBER 18 L2 LDC "Hello World" INVOKESTATIC kotlin/io/IoPackage.println (Ljava/lang/Object;)V L3 RETURN L4 LOCALVARIABLE this L_DefaultPackage$QtExtensions$7d5c0ac6$main$1; L0 L4 0 LOCALVARIABLE it Ljava/lang/Boolean; L0 L4 1 MAXSTACK = 1 MAXLOCALS = 2 // access flags 0x0 <init>()V ALOAD 0 ICONST_1 INVOKESPECIAL kotlin/jvm/internal/Lambda.<init> (I)V RETURN MAXSTACK = 2 MAXLOCALS = 1 // access flags 0x1008 static synthetic <clinit>()V NEW _DefaultPackage$QtExtensions$7d5c0ac6$main$1 DUP INVOKESPECIAL _DefaultPackage$QtExtensions$7d5c0ac6$main$1.<init> ()V PUTSTATIC _DefaultPackage$QtExtensions$7d5c0ac6$main$1.INSTANCE$ : L_DefaultPackage$QtExtensions$7d5c0ac6$main$1; RETURN MAXSTACK = 2 MAXLOCALS = 0 // access flags 0x19 public final static L_DefaultPackage$QtExtensions$7d5c0ac6$main$1; INSTANCE$ @Lkotlin/jvm/internal/KotlinSyntheticClass;(abiVersion=23, kind=Lkotlin/jvm/internal/KotlinSyntheticClass$Kind;.ANONYMOUS_FUNCTION) OUTERCLASS _DefaultPackage$QtExtensions$7d5c0ac6 main ([Ljava/lang/String;)V // access flags 0x19 public final static INNERCLASS _DefaultPackage$QtExtensions$7d5c0ac6$main$1 null null // compiled from: QtExtensions.kt } // ================_DefaultPackage.class ================= // class version 50.0 (50) // access flags 0x11 public final class _DefaultPackage { // access flags 0x8 static <clinit>()V LDC L_DefaultPackage;.class INVOKESTATIC kotlin/jvm/internal/Reflection.createKotlinPackage (Ljava/lang/Class;)Lkotlin/reflect/KPackage; PUTSTATIC _DefaultPackage.$kotlinPackage : Lkotlin/reflect/KPackage; RETURN MAXSTACK = 1 MAXLOCALS = 0 // access flags 0x1019 public final static synthetic Lkotlin/reflect/KPackage; $kotlinPackage // access flags 0x19 public final static main([Ljava/lang/String;)V @Ljet/runtime/typeinfo/JetValueParameter;(name="args") // parameter 0 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0 L0 L1 LINENUMBER 1 L1 ALOAD 0 INVOKESTATIC _DefaultPackage$QtExtensions$7d5c0ac6.main ([Ljava/lang/String;)V RETURN L2 LOCALVARIABLE args [Ljava/lang/String; L0 L2 0 MAXSTACK = 1 MAXLOCALS = 1 // access flags 0x19 // signature <A:Ljava/lang/Object;>(Lcom/trolltech/qt/QSignalEmitter$Signal1<TA;>;Lkotlin/jvm/functions/Function1<-TA;+Lkotlin/Unit;>;)V // declaration: void connect<A>(com.trolltech.qt.QSignalEmitter$Signal1<A>, kotlin.jvm.functions.Function1<? super A, ? extends kotlin.Unit>) public final static connect(Lcom/trolltech/qt/QSignalEmitter$Signal1;Lkotlin/jvm/functions/Function1;)V @Lkotlin/inline;() // invisible @Ljet/runtime/typeinfo/JetValueParameter;(name="$receiver") // parameter 0 @Ljet/runtime/typeinfo/JetValueParameter;(name="action") // parameter 1 @Lkotlin/noinline;() // invisible, parameter 1 @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1 L0 L1 LINENUMBER 1 L1 ALOAD 0 ALOAD 1 INVOKESTATIC _DefaultPackage$QtExtensions$7d5c0ac6.connect (Lcom/trolltech/qt/QSignalEmitter$Signal1;Lkotlin/jvm/functions/Function1;)V RETURN L2 LOCALVARIABLE $receiver Lcom/trolltech/qt/QSignalEmitter$Signal1; L0 L2 0 LOCALVARIABLE action Lkotlin/jvm/functions/Function1; L0 L2 1 MAXSTACK = 2 MAXLOCALS = 2 @Lkotlin/jvm/internal/KotlinPackage;(abiVersion=23, data={"V\u0004)!Q.Y5o\u0015\u0011\u0009'oZ:\u000b\u000b\u0005\u0013(/Y=\u000b\r-|G\u000f\\5o\u0015\u0019\u0019FO]5oO*!QK\\5u\u0015\u0011Q\u0017M^1\u000b\u00091\u000cgn\u001a\u0006&?\u0012+gY;miB\u000b7m[1hK\u0012\nF/\u0012=uK:\u001c\u0018n\u001c8tI]\"Wg\u0019\u0019bGZR\u0011!\u0011\u0006\u0004\u0003:L(bB*jO:\u000cG.\r\u0006\u000f#NKwM\\1m\u000b6LG\u000f^3s\u0015\r\u0019w.\u001c\u0006\niJ|G\u000e\u001c;fG\"T!!\u001d;\u000b\u000f\r|gN\\3di*1\u0011m\u0019;j_:T\u0011BR;oGRLwN\\\u0019\u000b-E\u001b\u0016n\u001a8bY\u0016k\u0017\u000e\u001e;fe\u0012\u001a\u0016n\u001a8bYFR1A\u001b<n\u0015%1WO\\2uS>t7\u000f\u001e\u0006\u0003!\rQa\u0001\u0003\u0001\u0011\u0005a\u0001!B\u0002\u0005\u0001!\u0011A\u0002A\u0003\u0004\u0009\u0001A)\u0001\u0004\u0001\u0006\u0003!\u0019QA\u0001\u0003\u0003\u0011\u000f)!\u0001\"\u0002\u0009\u0005\u0015\u0019A\u0001\u0001\u0005\u0006\u0019\u0001)\u0011\u0001#\u0004\u0006\u0005\u0011!\u0001bB\u0003\u0003\u0009\u0013Ay!B\u0002\u0005\u000b!1A\u0002A\u0003\u0004\u0009\u0017AY\u0001\u0004\u0001\u0006\u0007\u0011\u0001\u0001\"\u0003\u0007\u0001\u000b\u0009!Q\u0001c\u0005\u0006\u0005\u0011\u0001\u0001BC\u0003\u0003\u0009\u001fA)\"\u0002\u0002\u0005\u0011!IQ1\u0007\u0003\u00011\u0001i*\u0002\u0002\u0001\u0009\u000251Q!\u0001E\u0001\u0013\rI!!B\u0001\u0009\u0003A\u001b\u0001!\u0009\u0002\u0006\u0003!\r\u0011k\u0001\u0004\u0005\u0001%\u0009A\u0001A\u0007\u0003\u0011\ra\u0009\u0001W\u0002\u0005\u000b?\"\u0009!E\u0004\u0005\u0001!%A\u0012A\u000b\u0004\u000b\u0005A9\u0001$\u0001\u0016\u000f\u0015\u0009\u0001BB\u0005\u0005\u0013\r)!\u0001\"\u0001\u0009\u0001aAQt\u0004C\u0001\u0011#i1\"B\u0001\u0009\u000e%!\u0011bA\u0003\u0003\u0009\u0003A\u0001!C\u0002\n\u0005\u0015\u0009\u00012\u0001)\u0004\u0002\u0005\u0012Q!\u0001E\u0002#\u000e9A\u0001C\u0005\u0002\u0009\u0001i\u0011\u0001C\u0004\u000e\u0003!E\u0001l\u0001\u0003"}) // compiled from: QtExtensions.kt } 

Las classs dentro de la function en línea no se especializan, por lo que la execute de su object en bytecode tiene la siguiente execute(java.lang.Object) firma execute(java.lang.Object) . Pero javaClass<A>() especializa y en connect usted proporciona otra firma: execute(java.lang.Boolean) .

Intenta escribir

 fun <A> QSignalEmitter.Signal1<A>.connect(action: (A) -> Unit) { connect(action, "invoke(java.lang.Object)") } 

solución 2:

 inline fun <reified A> S<A>.connect(noinline action: (A) -> Unit) { connect(action, "invoke(${javaClass<A>()})") }