Skip to content

Commit

Permalink
Updated descriptor to use RpcType instead of KType directly (#239)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mr3zee authored Nov 26, 2024
1 parent a653cc1 commit 657cace
Show file tree
Hide file tree
Showing 14 changed files with 133 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ internal class RpcIrContext(
getRpcIrClassSymbol("RpcServiceDescriptor", "descriptor")
}

val rpcType by lazy {
getRpcIrClassSymbol("RpcType", "descriptor")
}

val rpcCallable by lazy {
getRpcIrClassSymbol("RpcCallable", "descriptor")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -976,6 +976,11 @@ internal class RpcStubGenerator(
* Where:
* - `<field-name>` - the name of the field
*/
@Suppress(
"detekt.NestedBlockDepth",
"detekt.LongMethod",
"detekt.CyclomaticComplexMethod",
)
private fun IrClass.generateInvokator(i: Int, callable: ServiceDeclaration.Callable) {
invokators[callable.name] = addProperty {
name = Name.identifier("${callable.name}Invokator")
Expand Down Expand Up @@ -1205,13 +1210,13 @@ internal class RpcStubGenerator(
* ```kotlin
* RpcCallable<MyService>(
* name = "<callable-name>",
* dataType = typeOf<<callable-data-type>>(),
* returnType = typeOf<<callable-return-type>>(),
* dataType = RpcCall(typeOf<<callable-data-type>>()),
* returnType = RpcCall(typeOf<<callable-return-type>>()),
* invokator = <callable-invokator>,
* parameters = arrayOf( // or emptyArray()
* RpcParameter(
* "<method-parameter-name-1>",
* typeOf<<method-parameter-type-1>>(),
* RpcCall(typeOf<<method-parameter-type-1>>())
* ),
* ...
* ),
Expand Down Expand Up @@ -1247,14 +1252,14 @@ internal class RpcStubGenerator(
is ServiceDeclaration.FlowField -> ctx.fieldDataObject.defaultType
}

putValueArgument(1, irTypeOfCall(dataType))
putValueArgument(1, irRpcTypeCall(dataType))

val returnType = when (callable) {
is ServiceDeclaration.Method -> callable.function.returnType
is ServiceDeclaration.FlowField -> callable.property.getterOrFail.returnType
}

putValueArgument(2, irTypeOfCall(returnType))
putValueArgument(2, irRpcTypeCall(returnType))

val invokator = invokators[callable.name]
?: error("Expected invokator for ${callable.name} in ${declaration.service.name}")
Expand Down Expand Up @@ -1309,7 +1314,7 @@ internal class RpcStubGenerator(
)
}.apply {
putValueArgument(0, stringConst(parameter.value.name.asString()))
putValueArgument(1, irTypeOfCall(parameter.type))
putValueArgument(1, irRpcTypeCall(parameter.type))
}
},
)
Expand Down Expand Up @@ -1521,6 +1526,25 @@ internal class RpcStubGenerator(
}
}

/**
* IR call of the `RpcType(KType, Array<Annotation>)` function
*/
private fun irRpcTypeCall(type: IrType): IrConstructorCallImpl {
return vsApi {
IrConstructorCallImplVS(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
type = ctx.rpcType.defaultType,
symbol = ctx.rpcType.constructors.single(),
typeArgumentsCount = 0,
valueArgumentsCount = 1,
constructorTypeArgumentsCount = 0,
)
}.apply {
putValueArgument(0, irTypeOfCall(type))
}
}

/**
* IR call of the `typeOf<...>()` function
*/
Expand Down
16 changes: 11 additions & 5 deletions core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ public abstract interface annotation class kotlinx/rpc/annotations/Rpc : java/la
}

public final class kotlinx/rpc/descriptor/RpcCallable {
public fun <init> (Ljava/lang/String;Lkotlin/reflect/KType;Lkotlin/reflect/KType;Lkotlinx/rpc/descriptor/RpcInvokator;[Lkotlinx/rpc/descriptor/RpcParameter;)V
public final fun getDataType ()Lkotlin/reflect/KType;
public fun <init> (Ljava/lang/String;Lkotlinx/rpc/descriptor/RpcType;Lkotlinx/rpc/descriptor/RpcType;Lkotlinx/rpc/descriptor/RpcInvokator;[Lkotlinx/rpc/descriptor/RpcParameter;)V
public final fun getDataType ()Lkotlinx/rpc/descriptor/RpcType;
public final fun getInvokator ()Lkotlinx/rpc/descriptor/RpcInvokator;
public final fun getName ()Ljava/lang/String;
public final fun getParameters ()[Lkotlinx/rpc/descriptor/RpcParameter;
public final fun getReturnType ()Lkotlin/reflect/KType;
public final fun getReturnType ()Lkotlinx/rpc/descriptor/RpcType;
}

public abstract interface class kotlinx/rpc/descriptor/RpcInvokator {
Expand All @@ -76,9 +76,9 @@ public abstract interface class kotlinx/rpc/descriptor/RpcInvokator$Method : kot
}

public final class kotlinx/rpc/descriptor/RpcParameter {
public fun <init> (Ljava/lang/String;Lkotlin/reflect/KType;)V
public fun <init> (Ljava/lang/String;Lkotlinx/rpc/descriptor/RpcType;)V
public final fun getName ()Ljava/lang/String;
public final fun getType ()Lkotlin/reflect/KType;
public final fun getType ()Lkotlinx/rpc/descriptor/RpcType;
}

public abstract interface class kotlinx/rpc/descriptor/RpcServiceDescriptor {
Expand All @@ -92,3 +92,9 @@ public final class kotlinx/rpc/descriptor/RpcServiceDescriptorKt {
public static final fun serviceDescriptorOf (Lkotlin/reflect/KType;)Lkotlinx/rpc/descriptor/RpcServiceDescriptor;
}

public final class kotlinx/rpc/descriptor/RpcType {
public fun <init> (Lkotlin/reflect/KType;)V
public final fun getKType ()Lkotlin/reflect/KType;
public fun toString ()Ljava/lang/String;
}

Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public interface RpcServiceDescriptor<T : RemoteService> {
@ExperimentalRpcApi
public class RpcCallable<T : RemoteService>(
public val name: String,
public val dataType: KType,
public val returnType: KType,
public val dataType: RpcType,
public val returnType: RpcType,
public val invokator: RpcInvokator<T>,
public val parameters: Array<RpcParameter>,
)
Expand All @@ -74,4 +74,11 @@ public sealed interface RpcInvokator<T : RemoteService> {
}

@ExperimentalRpcApi
public class RpcParameter(public val name: String, public val type: KType)
public class RpcParameter(public val name: String, public val type: RpcType)

@ExperimentalRpcApi
public class RpcType(public val kType: KType) {
override fun toString(): String {
return return kType.toString()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@ plugins {
doctor {
enableTestCaching = false
warnWhenNotUsingParallelGC = true
disallowMultipleDaemons = true
disallowMultipleDaemons = false
GCFailThreshold = 0.5f
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package kotlinx.rpc.krpc.internal
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.rpc.descriptor.RpcType
import kotlinx.rpc.internal.utils.InternalRpcApi
import kotlinx.serialization.*
import kotlinx.serialization.modules.SerializersModule
Expand All @@ -27,6 +28,11 @@ internal fun SerializersModule.buildContextual(type: KType): KSerializer<Any?> {
return result as? KSerializer<Any?> ?: error("No serializer found for $type")
}

@InternalRpcApi
public fun SerializersModule.rpcSerializerForType(type: RpcType): KSerializer<Any?> {
return rpcSerializerForType(type.kType)
}

@InternalRpcApi
public fun SerializersModule.rpcSerializerForType(type: KType): KSerializer<Any?> {
return when (type.classifier) {
Expand All @@ -35,6 +41,7 @@ public fun SerializersModule.rpcSerializerForType(type: KType): KSerializer<Any?
}
}


@InternalRpcApi
public fun unsupportedSerialFormatError(serialFormat: SerialFormat): Nothing {
error("Unsupported serial format ${serialFormat::class}, only StringFormat and BinaryFormats are supported")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ interface KrpcTestService : RemoteService {
suspend fun nonSerializableClass(localDate: @Contextual LocalDate): LocalDate
suspend fun nonSerializableClassWithSerializer(
localDateTime: @Serializable(LocalDateTimeSerializer::class) LocalDateTime,
): @Serializable(LocalDateTimeSerializer::class) LocalDateTime
): String

suspend fun incomingStreamSyncCollect(arg1: Flow<String>): Int
suspend fun incomingStreamAsyncCollect(arg1: Flow<String>): Int
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,6 @@ abstract class KrpcTransportTestBase {
}

@Test
@Ignore // todo will fix in next PR
fun nonSerializableParameter() {
runBlocking {
val localDate = LocalDate.of(2001, 8, 23)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
package kotlinx.rpc.codegen.test.runners;

import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.junit.jupiter.api.Test;

import java.io.File;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,42 +440,48 @@ FILE fqName:<root> fileName:/customParameterTypes.kt
<A>: kotlin.String
<B>: kotlinx.rpc.descriptor.RpcCallable<<root>.BoxService>
$receiver: CONST String type=kotlin.String value="test1"
that: CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, dataType: kotlin.reflect.KType, returnType: kotlin.reflect.KType, invokator: kotlinx.rpc.descriptor.RpcInvokator<T of kotlinx.rpc.descriptor.RpcCallable>, parameters: kotlin.Array<kotlinx.rpc.descriptor.RpcParameter>) declared in kotlinx.rpc.descriptor.RpcCallable' type=kotlinx.rpc.descriptor.RpcCallable<<root>.BoxService> origin=null
that: CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, dataType: kotlinx.rpc.descriptor.RpcType, returnType: kotlinx.rpc.descriptor.RpcType, invokator: kotlinx.rpc.descriptor.RpcInvokator<T of kotlinx.rpc.descriptor.RpcCallable>, parameters: kotlin.Array<kotlinx.rpc.descriptor.RpcParameter>) declared in kotlinx.rpc.descriptor.RpcCallable' type=kotlinx.rpc.descriptor.RpcCallable<<root>.BoxService> origin=null
<T>: <root>.BoxService
name: CONST String type=kotlin.String value="test1"
dataType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: <root>.BoxService.$rpcServiceStub.test1$rpcMethod
returnType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: kotlin.String
dataType: CONSTRUCTOR_CALL 'public constructor <init> (kType: kotlin.reflect.KType) declared in kotlinx.rpc.descriptor.RpcType' type=kotlinx.rpc.descriptor.RpcType origin=null
kType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: <root>.BoxService.$rpcServiceStub.test1$rpcMethod
returnType: CONSTRUCTOR_CALL 'public constructor <init> (kType: kotlin.reflect.KType) declared in kotlinx.rpc.descriptor.RpcType' type=kotlinx.rpc.descriptor.RpcType origin=null
kType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: kotlin.String
invokator: CALL 'private final fun <get-test1Invokator> (): kotlinx.rpc.descriptor.RpcInvokator.Method<<root>.BoxService> declared in <root>.BoxService.$rpcServiceStub.Companion' type=kotlinx.rpc.descriptor.RpcInvokator.Method<<root>.BoxService> origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.BoxService.$rpcServiceStub.Companion declared in <root>.BoxService.$rpcServiceStub.Companion' type=<root>.BoxService.$rpcServiceStub.Companion origin=null
parameters: CALL 'public final fun arrayOf <T> (vararg elements: T of kotlin.arrayOf): kotlin.Array<T of kotlin.arrayOf> declared in kotlin' type=kotlin.Array<out kotlinx.rpc.descriptor.RpcParameter> origin=null
<T>: kotlinx.rpc.descriptor.RpcParameter
elements: VARARG type=kotlin.Array<out kotlinx.rpc.descriptor.RpcParameter> varargElementType=kotlinx.rpc.descriptor.RpcParameter
CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, type: kotlin.reflect.KType) declared in kotlinx.rpc.descriptor.RpcParameter' type=kotlinx.rpc.descriptor.RpcParameter origin=null
CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, type: kotlinx.rpc.descriptor.RpcType) declared in kotlinx.rpc.descriptor.RpcParameter' type=kotlinx.rpc.descriptor.RpcParameter origin=null
name: CONST String type=kotlin.String value="testData"
type: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: <root>.TestData
type: CONSTRUCTOR_CALL 'public constructor <init> (kType: kotlin.reflect.KType) declared in kotlinx.rpc.descriptor.RpcType' type=kotlinx.rpc.descriptor.RpcType origin=null
kType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: <root>.TestData
CALL 'public final fun to <A, B> (that: B of kotlin.to): kotlin.Pair<A of kotlin.to, B of kotlin.to> declared in kotlin' type=kotlin.Pair<kotlin.String, kotlinx.rpc.descriptor.RpcCallable<<root>.BoxService>> origin=null
<A>: kotlin.String
<B>: kotlinx.rpc.descriptor.RpcCallable<<root>.BoxService>
$receiver: CONST String type=kotlin.String value="test2"
that: CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, dataType: kotlin.reflect.KType, returnType: kotlin.reflect.KType, invokator: kotlinx.rpc.descriptor.RpcInvokator<T of kotlinx.rpc.descriptor.RpcCallable>, parameters: kotlin.Array<kotlinx.rpc.descriptor.RpcParameter>) declared in kotlinx.rpc.descriptor.RpcCallable' type=kotlinx.rpc.descriptor.RpcCallable<<root>.BoxService> origin=null
that: CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, dataType: kotlinx.rpc.descriptor.RpcType, returnType: kotlinx.rpc.descriptor.RpcType, invokator: kotlinx.rpc.descriptor.RpcInvokator<T of kotlinx.rpc.descriptor.RpcCallable>, parameters: kotlin.Array<kotlinx.rpc.descriptor.RpcParameter>) declared in kotlinx.rpc.descriptor.RpcCallable' type=kotlinx.rpc.descriptor.RpcCallable<<root>.BoxService> origin=null
<T>: <root>.BoxService
name: CONST String type=kotlin.String value="test2"
dataType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: <root>.BoxService.$rpcServiceStub.test2$rpcMethod
returnType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: kotlin.String
dataType: CONSTRUCTOR_CALL 'public constructor <init> (kType: kotlin.reflect.KType) declared in kotlinx.rpc.descriptor.RpcType' type=kotlinx.rpc.descriptor.RpcType origin=null
kType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: <root>.BoxService.$rpcServiceStub.test2$rpcMethod
returnType: CONSTRUCTOR_CALL 'public constructor <init> (kType: kotlin.reflect.KType) declared in kotlinx.rpc.descriptor.RpcType' type=kotlinx.rpc.descriptor.RpcType origin=null
kType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: kotlin.String
invokator: CALL 'private final fun <get-test2Invokator> (): kotlinx.rpc.descriptor.RpcInvokator.Method<<root>.BoxService> declared in <root>.BoxService.$rpcServiceStub.Companion' type=kotlinx.rpc.descriptor.RpcInvokator.Method<<root>.BoxService> origin=GET_PROPERTY
$this: GET_VAR '<this>: <root>.BoxService.$rpcServiceStub.Companion declared in <root>.BoxService.$rpcServiceStub.Companion' type=<root>.BoxService.$rpcServiceStub.Companion origin=null
parameters: CALL 'public final fun arrayOf <T> (vararg elements: T of kotlin.arrayOf): kotlin.Array<T of kotlin.arrayOf> declared in kotlin' type=kotlin.Array<out kotlinx.rpc.descriptor.RpcParameter> origin=null
<T>: kotlinx.rpc.descriptor.RpcParameter
elements: VARARG type=kotlin.Array<out kotlinx.rpc.descriptor.RpcParameter> varargElementType=kotlinx.rpc.descriptor.RpcParameter
CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, type: kotlin.reflect.KType) declared in kotlinx.rpc.descriptor.RpcParameter' type=kotlinx.rpc.descriptor.RpcParameter origin=null
CONSTRUCTOR_CALL 'public constructor <init> (name: kotlin.String, type: kotlinx.rpc.descriptor.RpcType) declared in kotlinx.rpc.descriptor.RpcParameter' type=kotlinx.rpc.descriptor.RpcParameter origin=null
name: CONST String type=kotlin.String value="testData"
type: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: <root>.TestData
type: CONSTRUCTOR_CALL 'public constructor <init> (kType: kotlin.reflect.KType) declared in kotlinx.rpc.descriptor.RpcType' type=kotlinx.rpc.descriptor.RpcType origin=null
kType: CALL 'public final fun typeOf <T> (): kotlin.reflect.KType declared in kotlin.reflect' type=kotlin.reflect.KType origin=null
<T>: <root>.TestData
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-callableMap> visibility:private modality:FINAL <> ($this:<root>.BoxService.$rpcServiceStub.Companion) returnType:kotlin.collections.Map<kotlin.String, kotlinx.rpc.descriptor.RpcCallable<<root>.BoxService>>
correspondingProperty: PROPERTY name:callableMap visibility:private modality:FINAL [val]
$this: VALUE_PARAMETER name:<this> type:<root>.BoxService.$rpcServiceStub.Companion
Expand Down
Loading

0 comments on commit 657cace

Please sign in to comment.