diff --git a/README.md b/README.md
index fc95c9d1f..fd28c8942 100644
--- a/README.md
+++ b/README.md
@@ -17,11 +17,13 @@ Build your RPC with already known language constructs and nothing more!
## Quick start
-First, create your `RPC` service and define some methods:
+First, create your RPC service and define some methods:
```kotlin
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
-interface AwesomeService : RPC {
+@Rpc
+interface AwesomeService : RemoteService {
suspend fun getNews(city: String): Flow
}
```
diff --git a/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
index 8597a8f95..b67314b44 100644
--- a/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
+++ b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
@@ -94,8 +94,8 @@ internal object RPCDeclarationScanner {
private fun unsupportedDeclaration(service: IrClass, declaration: IrDeclaration, logger: MessageCollector): Nothing? {
logger.report(
- severity = CompilerMessageSeverity.WARNING,
- message = "Unsupported declaration in RPC interface ${service.name}: ${declaration.dumpKotlinLike()}",
+ severity = CompilerMessageSeverity.LOGGING,
+ message = "Unsupported declaration in RemoteService interface ${service.name}: ${declaration.dumpKotlinLike()}",
)
return null
diff --git a/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
index 64858b722..ca2ac1b0e 100644
--- a/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
+++ b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
@@ -77,10 +77,6 @@ internal class RPCIrContext(
getIrClassSymbol("kotlin", "Pair")
}
- val rpc by lazy {
- getRpcIrClassSymbol("RPC")
- }
-
val rpcClient by lazy {
getRpcIrClassSymbol("RPCClient")
}
diff --git a/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
index f1c618ee5..e450eb7fd 100644
--- a/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
+++ b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
@@ -4,24 +4,23 @@
package kotlinx.rpc.codegen.extension
+import kotlinx.rpc.codegen.common.RpcClassId
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass
-import org.jetbrains.kotlin.ir.types.defaultType
-import org.jetbrains.kotlin.ir.util.isInterface
+import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
internal class RPCIrServiceProcessor(
@Suppress("unused")
private val logger: MessageCollector,
) : IrElementTransformer {
- @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
- override fun visitClass(declaration: IrClass, context: RPCIrContext): IrStatement {
- if (declaration.isInterface && declaration.superTypes.contains(context.rpc.defaultType)) {
- processService(declaration, context)
+ override fun visitClass(declaration: IrClass, data: RPCIrContext): IrStatement {
+ if (declaration.hasAnnotation(RpcClassId.rpcAnnotation)) {
+ processService(declaration, data)
}
- return super.visitClass(declaration, context)
+ return super.visitClass(declaration, data)
}
private fun processService(service: IrClass, context: RPCIrContext) {
diff --git a/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
index e30fa0605..a70483aa1 100644
--- a/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
+++ b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
@@ -196,7 +196,7 @@ internal class RPCStubGenerator(
private var coroutineContextProperty: IrProperty by Delegates.notNull()
/**
- * `coroutineContext` property from `RPC` interface
+ * `coroutineContext` property from `RemoteService` interface
*
* ```kotlin
* final override val coroutineContext: CoroutineContext = __rpc_client.provideStubContext(__rpc_stub_id)
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-cli/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index 5f725c7ea..aa7010119 100644
--- a/compiler-plugin/compiler-plugin-cli/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
+++ b/compiler-plugin/compiler-plugin-cli/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -34,5 +34,5 @@ fun CompilerPluginRegistrar.ExtensionStorage.registerRpcExtensions(configuration
VersionSpecificApi.INSTANCE = VersionSpecificApiImpl
IrGenerationExtension.registerExtension(RPCIrExtension(configuration))
- FirExtensionRegistrarAdapter.registerExtension(FirRPCExtensionRegistrar(configuration))
+ FirExtensionRegistrarAdapter.registerExtension(FirRpcExtensionRegistrar(configuration))
}
diff --git a/compiler-plugin/compiler-plugin-common/src/main/core/kotlinx/rpc/codegen/common/Names.kt b/compiler-plugin/compiler-plugin-common/src/main/core/kotlinx/rpc/codegen/common/Names.kt
index f31121112..5c83460ec 100644
--- a/compiler-plugin/compiler-plugin-common/src/main/core/kotlinx/rpc/codegen/common/Names.kt
+++ b/compiler-plugin/compiler-plugin-common/src/main/core/kotlinx/rpc/codegen/common/Names.kt
@@ -8,8 +8,9 @@ import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
-object ClassDeclarations {
- val rpcInterface = ClassId(FqName("kotlinx.rpc"), Name.identifier("RPC"))
+object RpcClassId {
+ val remoteServiceInterface = ClassId(FqName("kotlinx.rpc"), Name.identifier("RemoteService"))
+ val rpcAnnotation = ClassId(FqName("kotlinx.rpc.annotations"), Name.identifier("Rpc"))
val serializableAnnotation = ClassId(FqName("kotlinx.serialization"), Name.identifier("Serializable"))
val contextualAnnotation = ClassId(FqName("kotlinx.serialization"), Name.identifier("Contextual"))
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRPCExtensionRegistrar.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRPCExtensionRegistrar.kt
index 40de0b364..07c07447d 100644
--- a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRPCExtensionRegistrar.kt
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRPCExtensionRegistrar.kt
@@ -8,12 +8,16 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar
+import org.jetbrains.kotlin.fir.analysis.extensions.FirAdditionalCheckersExtension.Factory as CFactory
import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension.Factory as GFactory
+import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension.Factory as SFactory
-class FirRPCExtensionRegistrar(private val configuration: CompilerConfiguration) : FirExtensionRegistrar() {
+class FirRpcExtensionRegistrar(private val configuration: CompilerConfiguration) : FirExtensionRegistrar() {
override fun ExtensionRegistrarContext.configurePlugin() {
val logger = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
- +GFactory { FirRPCServiceGenerator(it, logger) }
+ +CFactory { FirRpcCheckers(it) }
+ +GFactory { FirRpcServiceGenerator(it, logger) }
+ +SFactory { FirRpcSupertypeGenerator(it, logger) }
}
}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRPCServiceGenerator.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRPCServiceGenerator.kt
index 136a0709f..70ff68d27 100644
--- a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRPCServiceGenerator.kt
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRPCServiceGenerator.kt
@@ -4,7 +4,7 @@
package kotlinx.rpc.codegen
-import kotlinx.rpc.codegen.common.ClassDeclarations
+import kotlinx.rpc.codegen.common.RpcClassId
import kotlinx.rpc.codegen.common.RpcNames
import kotlinx.rpc.codegen.common.rpcMethodClassName
import kotlinx.rpc.codegen.common.rpcMethodName
@@ -19,9 +19,7 @@ import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.FirFunction
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.fir.declarations.utils.visibility
-import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension
-import org.jetbrains.kotlin.fir.extensions.MemberGenerationContext
-import org.jetbrains.kotlin.fir.extensions.NestedClassGenerationContext
+import org.jetbrains.kotlin.fir.extensions.*
import org.jetbrains.kotlin.fir.moduleData
import org.jetbrains.kotlin.fir.plugin.*
import org.jetbrains.kotlin.fir.symbols.SymbolInternals
@@ -44,22 +42,7 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackage
*
* ## General idea
*
- * [getNestedClassifiersNames] should return a set of [Name]s to generate for.
- * For these names [generateNestedClassLikeDeclaration] can generate some nested classes,
- * which is what we need.
- *
- * But the catch is that we cannot say for sure, if we need to generate a class
- * while in [getNestedClassifiersNames], but if we do not return anything
- * [generateNestedClassLikeDeclaration] will not be called.
- * We need to generate a class if only the current declaration is an RPC interface
- * (inherits kotlinx.rpc.RPC). There is no resolved supertypes in [getNestedClassifiersNames],
- * But, if the potentially generated class is not referenced anywhere,
- * then [generateNestedClassLikeDeclaration] will already have supertypes resolved,
- * so we can use this info to check the actual supertypes for RPC interface.
- *
- * So we always return a class name that may be generated.
- * And then, in [generateNestedClassLikeDeclaration] we do the actual check with the resolved supertypes
- * and generate a class if needed, otherwise returning null.
+ * Detect `@Rpc` annotation - generate stub classes.
*
* ## Usage of kotlinx.serialization plugin
*
@@ -68,7 +51,7 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackage
* We generate classes that are marked `@Serializable`.
* In that case, the serialization plugin will not be able to pick up those classes and process them accordingly.
*
- * That's why we have an instance of this plugin, which we call only on our generated classes - [serializationExtension]
+ * That is why we have an instance of this plugin, which we call only on our generated classes - [serializationExtension]
*
* Not all the methods that we would like to call are public, so we access them via reflection:
* - [generateCompanionDeclaration]
@@ -76,7 +59,7 @@ import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackage
*
* This is basically copying the behavior of the actual plugin but isolated only for our generated classes.
*/
-class FirRPCServiceGenerator(
+class FirRpcServiceGenerator(
session: FirSession,
@Suppress("unused")
private val logger: MessageCollector,
@@ -84,22 +67,22 @@ class FirRPCServiceGenerator(
private val serializationExtension = SerializationFirResolveExtension(session)
private val isJvmOrMetadata = !session.moduleData.platform.run { isJs() || isWasm() || isNative() }
+ override fun FirDeclarationPredicateRegistrar.registerPredicates() {
+ register(FirRpcPredicates.rpc)
+ }
+
/**
* Generates nested classifiers.
*
* They can be of three kinds:
* - Nested Service Stub class.
* In that case [classSymbol] will not have any RPC-generated [FirClassSymbol.origin].
- * Rge only check we do - is we check that the declaration is an interface,
- * and return [RpcNames.SERVICE_STUB_NAME].
- * We cannot be sure if the declaration is actually an RPC service,
- * because superTypes are not resolved during that stage.
- * We postpone this check until [generateNestedClassLikeDeclaration].
+ * The only check we do - presence of the `@Rpc` annotation and return [RpcNames.SERVICE_STUB_NAME].
*
* - Companion object of the service stub and method classes.
* If we generate this companion object, we will have [FirClassSymbol.origin]
* of [classSymbol] be set to [RPCGeneratedStubKey],
- * because we are inside the previously generated service stub class.
+ * because we're inside the previously generated service stub class.
* The same goes for method classes too.
* So we return [SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT]
* and a list of method class names.
@@ -141,7 +124,7 @@ class FirRPCServiceGenerator(
SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
}
- classSymbol.isInterface -> {
+ classSymbol.isInterface && session.predicateBasedProvider.matches(FirRpcPredicates.rpc, classSymbol) -> {
setOf(RpcNames.SERVICE_STUB_NAME)
}
@@ -158,7 +141,7 @@ class FirRPCServiceGenerator(
override fun generateNestedClassLikeDeclaration(
owner: FirClassSymbol<*>,
name: Name,
- context: NestedClassGenerationContext
+ context: NestedClassGenerationContext,
): FirClassLikeSymbol<*>? {
val rpcServiceStubKey = owner.generatedRpcServiceStubKey
return when {
@@ -214,7 +197,7 @@ class FirRPCServiceGenerator(
modality = Modality.FINAL
}
- rpcMethodClass.addAnnotation(ClassDeclarations.serializableAnnotation, session)
+ rpcMethodClass.addAnnotation(RpcClassId.serializableAnnotation, session)
/**
* Required to pass isSerializableObjectAndNeedsFactory check
@@ -264,18 +247,10 @@ class FirRPCServiceGenerator(
}
/**
- * Checks whether the [owner] class is actually an RPC service
- * (the supertypes are resolved at this stage,
- * as the [RpcNames.SERVICE_STUB_NAME] is not references anywhere)
- *
- * If the [owner] is an RPC service - generates its service stub.
+ * Generates [owner]'s service stub.
* Scrapes the functions from the [owner] to generate method classes.
*/
private fun generateRpcServiceStubClass(owner: FirClassSymbol<*>): FirRegularClassSymbol? {
- owner.resolvedSuperTypes.find {
- it.classId == ClassDeclarations.rpcInterface
- } ?: return null
-
@OptIn(SymbolInternals::class)
val functions = owner.fir.declarations
.filterIsInstance()
@@ -306,7 +281,7 @@ class FirRPCServiceGenerator(
}
/**
- * If the method does not have any parameters, it is an object,
+ * If the method doesn't have any parameters, it is an object,
* and its only callable names are constructor, and the ones provided by the [serializationExtension].
* Otherwise, the callable names are the names of the method parameters and the constructor.
*/
@@ -322,7 +297,7 @@ class FirRPCServiceGenerator(
rpcMethodClassKey.rpcMethod.valueParameterSymbols.map { it.name }.toSet()
} + SpecialNames.INIT
- // ^ init is necessary either way, as serialization does not add it for a serializable object
+ // ^ init is necessary either way, as serialization doesn't add it for a serializable object
}
override fun generateConstructors(context: MemberGenerationContext): List {
@@ -361,7 +336,7 @@ class FirRPCServiceGenerator(
override fun generateProperties(
callableId: CallableId,
- context: MemberGenerationContext?
+ context: MemberGenerationContext?,
): List {
context ?: return emptyList()
@@ -399,14 +374,14 @@ class FirRPCServiceGenerator(
returnType = valueParam.resolvedReturnType,
).apply {
if (valueParam.resolvedReturnType.requiresContextual()) {
- addAnnotation(ClassDeclarations.contextualAnnotation, session)
+ addAnnotation(RpcClassId.contextualAnnotation, session)
}
}.symbol.let(::listOf)
}
private fun ConeKotlinType.requiresContextual(): Boolean {
return when (classId) {
- ClassDeclarations.flow, ClassDeclarations.sharedFlow, ClassDeclarations.stateFlow -> true
+ RpcClassId.flow, RpcClassId.sharedFlow, RpcClassId.stateFlow -> true
else -> false
}
}
@@ -416,7 +391,7 @@ class FirRPCServiceGenerator(
*/
override fun generateFunctions(
callableId: CallableId,
- context: MemberGenerationContext?
+ context: MemberGenerationContext?,
): List {
val owner = context?.owner ?: return emptyList()
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcCheckers.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcCheckers.kt
new file mode 100644
index 000000000..4c3289e04
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcCheckers.kt
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc.codegen
+
+import kotlinx.rpc.codegen.checkers.FirRpcDeclarationCheckers
+import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
+import org.jetbrains.kotlin.fir.analysis.extensions.FirAdditionalCheckersExtension
+import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
+
+class FirRpcCheckers(session: FirSession) : FirAdditionalCheckersExtension(session) {
+ override fun FirDeclarationPredicateRegistrar.registerPredicates() {
+ register(FirRpcPredicates.rpc)
+ }
+
+ override val declarationCheckers: DeclarationCheckers = FirRpcDeclarationCheckers
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcPredicates.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcPredicates.kt
new file mode 100644
index 000000000..8ec8e808c
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcPredicates.kt
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc.codegen
+
+import kotlinx.rpc.codegen.common.RpcClassId
+import org.jetbrains.kotlin.fir.extensions.predicate.DeclarationPredicate
+
+object FirRpcPredicates {
+ internal val rpc = DeclarationPredicate.create {
+ annotated(RpcClassId.rpcAnnotation.asSingleFqName()) // @Rpc
+ }
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcSupertypeGenerator.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcSupertypeGenerator.kt
new file mode 100644
index 000000000..8dd784e49
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcSupertypeGenerator.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc.codegen
+
+import kotlinx.rpc.codegen.common.RpcClassId
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
+import org.jetbrains.kotlin.fir.extensions.FirDeclarationPredicateRegistrar
+import org.jetbrains.kotlin.fir.extensions.FirSupertypeGenerationExtension
+import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
+import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
+import org.jetbrains.kotlin.fir.types.constructClassLikeType
+import org.jetbrains.kotlin.fir.types.toFirResolvedTypeRef
+
+class FirRpcSupertypeGenerator(
+ session: FirSession,
+ @Suppress("unused") private val logger: MessageCollector,
+) : FirSupertypeGenerationExtension(session) {
+ override fun FirDeclarationPredicateRegistrar.registerPredicates() {
+ register(FirRpcPredicates.rpc)
+ }
+
+ override fun needTransformSupertypes(declaration: FirClassLikeDeclaration): Boolean {
+ return session.predicateBasedProvider.matches(FirRpcPredicates.rpc, declaration)
+ }
+
+ override fun computeAdditionalSupertypes(
+ classLikeDeclaration: FirClassLikeDeclaration,
+ resolvedSupertypes: List,
+ typeResolver: TypeResolveService,
+ ): List {
+ if (resolvedSupertypes.any { it.doesMatchesClassId(session, RpcClassId.remoteServiceInterface) }) {
+ return emptyList()
+ }
+
+ return listOf(
+ RpcClassId.remoteServiceInterface
+ .constructClassLikeType(emptyArray(), isNullable = false)
+ .toFirResolvedTypeRef()
+ )
+ }
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcUtils.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcUtils.kt
new file mode 100644
index 000000000..04c5d0607
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/FirRpcUtils.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc.codegen
+
+import kotlinx.rpc.codegen.common.RpcClassId
+import org.jetbrains.kotlin.KtSourceElement
+import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.declarations.getAnnotationByClassId
+import org.jetbrains.kotlin.fir.expressions.FirAnnotation
+import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
+import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
+import org.jetbrains.kotlin.fir.types.ConeClassLikeType
+import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef
+import org.jetbrains.kotlin.fir.types.FirTypeRef
+import org.jetbrains.kotlin.fir.types.coneTypeSafe
+import org.jetbrains.kotlin.name.ClassId
+
+fun FirClassSymbol<*>.isRemoteService(session: FirSession): Boolean = resolvedSuperTypeRefs.any {
+ it.doesMatchesClassId(session, RpcClassId.remoteServiceInterface)
+}
+
+fun FirBasedSymbol<*>.rpcAnnotationSource(session: FirSession): KtSourceElement? {
+ return rpcAnnotation(session)?.source
+}
+
+fun FirBasedSymbol<*>.rpcAnnotation(session: FirSession): FirAnnotation? {
+ return resolvedCompilerAnnotationsWithClassIds.rpcAnnotation(session)
+}
+
+fun List.rpcAnnotation(session: FirSession): FirAnnotation? {
+ return getAnnotationByClassId(RpcClassId.rpcAnnotation, session)
+}
+
+fun FirClassSymbol<*>.remoteServiceSupertypeSource(session: FirSession): KtSourceElement? {
+ return remoteServiceSupertype(session)?.source
+}
+
+fun FirClassSymbol<*>.remoteServiceSupertype(session: FirSession): FirResolvedTypeRef? {
+ return resolvedSuperTypeRefs.find { it.doesMatchesClassId(session, RpcClassId.remoteServiceInterface) }
+}
+
+internal fun FirTypeRef.doesMatchesClassId(session: FirSession, classId: ClassId): Boolean {
+ return coneTypeSafe()?.fullyExpandedType(session)?.lookupTag?.classId == classId
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/FirRpcAnnotationChecker.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/FirRpcAnnotationChecker.kt
new file mode 100644
index 000000000..b0060fc22
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/FirRpcAnnotationChecker.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc.codegen.checkers
+
+import kotlinx.rpc.codegen.FirRpcPredicates
+import kotlinx.rpc.codegen.checkers.diagnostics.FirRpcDiagnostics
+import kotlinx.rpc.codegen.isRemoteService
+import kotlinx.rpc.codegen.remoteServiceSupertypeSource
+import kotlinx.rpc.codegen.rpcAnnotationSource
+import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
+import org.jetbrains.kotlin.diagnostics.reportOn
+import org.jetbrains.kotlin.fir.analysis.checkers.MppCheckerKind
+import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
+import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirRegularClassChecker
+import org.jetbrains.kotlin.fir.declarations.FirRegularClass
+import org.jetbrains.kotlin.fir.declarations.utils.isInterface
+import org.jetbrains.kotlin.fir.extensions.predicateBasedProvider
+
+object FirRpcAnnotationChecker : FirRegularClassChecker(MppCheckerKind.Common) {
+ override fun check(
+ declaration: FirRegularClass,
+ context: CheckerContext,
+ reporter: DiagnosticReporter,
+ ) {
+ val rpcAnnotated = context.session.predicateBasedProvider.matches(FirRpcPredicates.rpc, declaration)
+
+ if (!declaration.isInterface && rpcAnnotated) {
+ reporter.reportOn(
+ source = declaration.symbol.rpcAnnotationSource(context.session),
+ factory = FirRpcDiagnostics.WRONG_RPC_ANNOTATION_TARGET,
+ context = context,
+ )
+ }
+
+ if (declaration.symbol.isRemoteService(context.session) && !rpcAnnotated) {
+ reporter.reportOn(
+ source = declaration.symbol.remoteServiceSupertypeSource(context.session),
+ factory = FirRpcDiagnostics.MISSING_RPC_ANNOTATION,
+ context = context,
+ )
+ }
+ }
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/FirRpcDeclarationCheckers.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/FirRpcDeclarationCheckers.kt
new file mode 100644
index 000000000..45c3d5742
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/FirRpcDeclarationCheckers.kt
@@ -0,0 +1,14 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc.codegen.checkers
+
+import org.jetbrains.kotlin.fir.analysis.checkers.declaration.DeclarationCheckers
+import org.jetbrains.kotlin.fir.analysis.checkers.declaration.FirRegularClassChecker
+
+object FirRpcDeclarationCheckers : DeclarationCheckers() {
+ override val regularClassCheckers: Set = setOf(
+ FirRpcAnnotationChecker,
+ )
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt
new file mode 100644
index 000000000..2b93e2fda
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/diagnostics/FirRpcDiagnostics.kt
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc.codegen.checkers.diagnostics
+
+import org.jetbrains.kotlin.diagnostics.error0
+import org.jetbrains.kotlin.diagnostics.rendering.RootDiagnosticRendererFactory
+import org.jetbrains.kotlin.psi.KtAnnotationEntry
+
+object FirRpcDiagnostics {
+ val MISSING_RPC_ANNOTATION by error0()
+ val WRONG_RPC_ANNOTATION_TARGET by error0()
+
+ init {
+ RootDiagnosticRendererFactory.registerFactory(RpcDiagnosticRendererFactory)
+ }
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt
new file mode 100644
index 000000000..fd1254044
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/latest/kotlinx/rpc/codegen/checkers/diagnostics/RpcDiagnosticRendererFactory.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc.codegen.checkers.diagnostics
+
+import org.jetbrains.kotlin.diagnostics.KtDiagnosticFactoryToRendererMap
+import org.jetbrains.kotlin.diagnostics.rendering.BaseDiagnosticRendererFactory
+
+object RpcDiagnosticRendererFactory : BaseDiagnosticRendererFactory() {
+ override val MAP = KtDiagnosticFactoryToRendererMap("Rpc").apply {
+ put(
+ factory = FirRpcDiagnostics.MISSING_RPC_ANNOTATION,
+ message = "Missing @Rpc annotation. " +
+ "All services children of kotlinx.rpc.RemoteService " +
+ "must be annotated with kotlinx.rpc.annotations.Rpc",
+ )
+
+ put(
+ factory = FirRpcDiagnostics.WRONG_RPC_ANNOTATION_TARGET,
+ message = "@Rpc annotation is only applicable to interfaces.",
+ )
+ }
+}
diff --git a/core/api/core.api b/core/api/core.api
index 1e9b437b4..dba97ab59 100644
--- a/core/api/core.api
+++ b/core/api/core.api
@@ -1,6 +1,6 @@
public final class kotlinx/rpc/AwaitFieldInitializationKt {
- public static final fun awaitFieldInitialization (Lkotlinx/rpc/RPC;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
- public static final fun awaitFieldInitialization (Lkotlinx/rpc/RPC;Lkotlin/reflect/KClass;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+ public static final fun awaitFieldInitialization (Lkotlinx/rpc/RemoteService;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
+ public static final fun awaitFieldInitialization (Lkotlinx/rpc/RemoteService;Lkotlin/reflect/KClass;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
}
public abstract interface class kotlinx/rpc/RPC : kotlinx/coroutines/CoroutineScope {
@@ -69,13 +69,19 @@ public abstract interface class kotlinx/rpc/RPCServer : kotlinx/coroutines/Corou
public abstract fun registerService (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
}
+public abstract interface class kotlinx/rpc/RemoteService : kotlinx/coroutines/CoroutineScope {
+}
+
public final class kotlinx/rpc/UninitializedRPCFieldException : java/lang/Exception {
public fun (Ljava/lang/String;Lkotlin/reflect/KProperty;)V
public fun getMessage ()Ljava/lang/String;
}
public final class kotlinx/rpc/WithServiceKt {
- public static final fun withService (Lkotlinx/rpc/RPCClient;Lkotlin/reflect/KClass;)Lkotlinx/rpc/RPC;
- public static final fun withService (Lkotlinx/rpc/RPCClient;Lkotlin/reflect/KType;)Lkotlinx/rpc/RPC;
+ public static final fun withService (Lkotlinx/rpc/RPCClient;Lkotlin/reflect/KClass;)Lkotlinx/rpc/RemoteService;
+ public static final fun withService (Lkotlinx/rpc/RPCClient;Lkotlin/reflect/KType;)Lkotlinx/rpc/RemoteService;
+}
+
+public abstract interface annotation class kotlinx/rpc/annotations/Rpc : java/lang/annotation/Annotation {
}
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/RPCCall.kt b/core/src/commonMain/kotlin/kotlinx/rpc/RPCCall.kt
index d49749689..d2aace238 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/RPCCall.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/RPCCall.kt
@@ -7,7 +7,7 @@ package kotlinx.rpc
import kotlin.reflect.KType
/**
- * Represents a method or field call of the RPC interface.
+ * Represents a method or field call of an RPC service.
* Contains all types and values information for the call, so it can be passed to a server.
*
* @property serviceTypeString The service type as a string.
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/RPCClient.kt b/core/src/commonMain/kotlin/kotlinx/rpc/RPCClient.kt
index ee3f60274..8dd4ed0ce 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/RPCClient.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/RPCClient.kt
@@ -63,9 +63,9 @@ public interface RPCClient : CoroutineScope {
public fun registerStateFlowField(serviceScope: CoroutineScope, field: RPCField): StateFlow
/**
- * Provides child [CoroutineContext] for a new [RPC] service stub.
+ * Provides child [CoroutineContext] for a new [RemoteService] service stub.
*
- * This function should not be called directly.
+ * This function shouldn't be called directly.
*
* @param serviceId id of the new service. Used for service cancellation messages.
*/
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/RPCServer.kt b/core/src/commonMain/kotlin/kotlinx/rpc/RPCServer.kt
index 5bb7a3ba2..1aa492182 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/RPCServer.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/RPCServer.kt
@@ -24,7 +24,7 @@ public interface RPCServer : CoroutineScope {
* @param serviceKClass [KClass] of the [Service].
* @param serviceFactory function that produces the actual implementation of the service that will handle the calls.
*/
- public fun registerService(
+ public fun registerService(
serviceKClass: KClass,
serviceFactory: (CoroutineContext) -> Service,
)
@@ -39,7 +39,7 @@ public interface RPCServer : CoroutineScope {
* type `MyService` should be specified explicitly.
* @param serviceFactory function that produces the actual implementation of the service that will handle the calls.
*/
-public inline fun RPCServer.registerService(
+public inline fun RPCServer.registerService(
noinline serviceFactory: (CoroutineContext) -> Service,
) {
registerService(Service::class, serviceFactory)
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/RemoteService.kt b/core/src/commonMain/kotlin/kotlinx/rpc/RemoteService.kt
new file mode 100644
index 000000000..ce41e270b
--- /dev/null
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/RemoteService.kt
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+package kotlinx.rpc
+
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.rpc.annotations.Rpc
+
+/**
+ * Marker interface for an RPC service.
+ * Provides type safety and [CoroutineScope] for [Rpc] annotated services.
+ *
+ * Every [RemoteService] service MUST be annotated with [Rpc] annotation.
+ *
+ * @see Rpc
+ */
+public interface RemoteService : CoroutineScope
+
+@Deprecated(
+ message = "Deprecated in favor of RemoteService. Will be removed in 0.5.0",
+ replaceWith = ReplaceWith("RemoteService", "kotlinx.rpc.RemoteService"),
+ level = DeprecationLevel.ERROR,
+)
+public interface RPC : CoroutineScope
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/UninitializedRPCFieldException.kt b/core/src/commonMain/kotlin/kotlinx/rpc/UninitializedRPCFieldException.kt
index 49db36cfc..dcf42b189 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/UninitializedRPCFieldException.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/UninitializedRPCFieldException.kt
@@ -7,7 +7,7 @@ package kotlinx.rpc
import kotlin.reflect.KProperty
/**
- * Thrown when an uninitialized field of an RPC interface is accessed.
+ * Thrown when an uninitialized field of an RPC service is accessed.
*
* Use [awaitFieldInitialization] to await for the field initialization
*/
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/RPC.kt b/core/src/commonMain/kotlin/kotlinx/rpc/annotations/Rpc.kt
similarity index 53%
rename from core/src/commonMain/kotlin/kotlinx/rpc/RPC.kt
rename to core/src/commonMain/kotlin/kotlinx/rpc/annotations/Rpc.kt
index ca79c1729..3b9dab8fe 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/RPC.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/annotations/Rpc.kt
@@ -2,40 +2,42 @@
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
-package kotlinx.rpc
+package kotlinx.rpc.annotations
-import kotlinx.coroutines.CoroutineScope
+import kotlinx.rpc.RemoteService
/**
- * Marker interface for an RPC service.
- * For each service that inherits this interface library will generate an implementation to use it on the client side.
+ * Every [Rpc] annotated interface will have a code generation process run on it,
+ * making the interface effectively usable for RPC calls.
*
- * [CoroutineScope] defines service lifetime.
+ * Every [Rpc] annotated interface MAY inherit from the [RemoteService] interface.
+ * If it is not done explicitly, the supertype will be added during the compilation process.
+ * In that case an IDE will highlight false-positive type mismatch errors,
+ * so it is recommended to add the [RemoteService] parent explicitly, until proper IDE support is provided.
*
* Example usage:
* ```kotlin
* // common code
- * interface MyService : RPC {
+ * @Rpc
+ * interface MyService : RemoteService {
* suspend fun sayHello(firstName: String, lastName: String, age: Int): String
* }
- *
* // client code
* val rpcClient: RPCClient
* val myService = rpcClient.withService()
* val greetingFromServer = myService.sayHello("Alex", "Smith", 35)
- *
* // server code
* class MyServiceImpl(override val coroutineContext: CoroutineContext) : MyService {
* override suspend fun sayHello(firstName: String, lastName: String, age: Int): String {
* return "Hello, $firstName $lastName, of age $age. I am your server!"
* }
* }
- *
* val server: RPCServer
* server.registerService { ctx -> MyServiceImpl(ctx) }
* ```
*
- * @see RPCClient
- * @see RPCServer
+ * @see [RemoteService]
*/
-public interface RPC : CoroutineScope
+@Target(AnnotationTarget.CLASS)
+@Retention(AnnotationRetention.RUNTIME)
+public annotation class Rpc
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/awaitFieldInitialization.kt b/core/src/commonMain/kotlin/kotlinx/rpc/awaitFieldInitialization.kt
index 0fd06b13a..9961247da 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/awaitFieldInitialization.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/awaitFieldInitialization.kt
@@ -14,7 +14,8 @@ import kotlin.reflect.KClass
* Waits for the initialization of an RPC field in the generated client:
*
* ```kotlin
- * interface MyService : RPC {
+ * @Rpc
+ * interface MyService : RemoteService {
* val stateFlow: StateFlow
* }
*
@@ -27,7 +28,7 @@ import kotlin.reflect.KClass
* @param getter function that returns the field of the context service to wait for.
* @return service filed after it was initialized.
*/
-public suspend fun T.awaitFieldInitialization(getter: T.() -> R): R {
+public suspend fun T.awaitFieldInitialization(getter: T.() -> R): R {
val field = getter()
if (field is RPCDeferredField<*>) {
@@ -42,7 +43,8 @@ public suspend fun T.awaitFieldInitialization(getter: T.() -> R): R
* Waits for the initialization of all RPC fields in the generated client:
*
* ```kotlin
- * interface MyService : RPC {
+ * @Rpc
+ * interface MyService : RemoteService {
* val stateFlow1: StateFlow
* val stateFlow2: StateFlow
* }
@@ -55,7 +57,7 @@ public suspend fun T.awaitFieldInitialization(getter: T.() -> R): R
* @param T service type
* @return specified service, after all of it's field were initialized.
*/
-public suspend inline fun T.awaitFieldInitialization(): T {
+public suspend inline fun T.awaitFieldInitialization(): T {
return awaitFieldInitialization(T::class)
}
@@ -63,7 +65,8 @@ public suspend inline fun T.awaitFieldInitialization(): T {
* Waits for the initialization of all RPC fields in the generated client:
*
* ```kotlin
- * interface MyService : RPC {
+ * @Rpc
+ * interface MyService : RemoteService {
* val stateFlow1: StateFlow
* val stateFlow2: StateFlow
* }
@@ -77,7 +80,7 @@ public suspend inline fun T.awaitFieldInitialization(): T {
* @param kClass [KClass] of the [T] type.
* @return specified service, after all of it's field were initialized.
*/
-public suspend fun T.awaitFieldInitialization(kClass: KClass): T {
+public suspend fun T.awaitFieldInitialization(kClass: KClass): T {
findRPCStubProvider>(kClass, RPCServiceFieldsProvider::class.safeCast())
.rpcFields(this)
.forEach { field ->
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCStubObject.kt b/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCStubObject.kt
index 7b9264c82..2cef230d9 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCStubObject.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCStubObject.kt
@@ -4,19 +4,19 @@
package kotlinx.rpc.internal
-import kotlinx.rpc.RPC
import kotlinx.rpc.RPCClient
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.utils.InternalRPCApi
import kotlin.reflect.KType
@InternalRPCApi
-public interface RPCStubObject :
+public interface RPCStubObject :
RPCStubServiceProvider,
RPCServiceMethodSerializationTypeProvider,
RPCServiceFieldsProvider
@InternalRPCApi
-public interface RPCStubServiceProvider {
+public interface RPCStubServiceProvider {
public fun withClient(serviceId: Long, client: RPCClient) : T
}
@@ -26,6 +26,6 @@ public interface RPCServiceMethodSerializationTypeProvider {
}
@InternalRPCApi
-public interface RPCServiceFieldsProvider {
+public interface RPCServiceFieldsProvider {
public fun rpcFields(service: T): List>
}
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/withService.kt b/core/src/commonMain/kotlin/kotlinx/rpc/withService.kt
index 8a8ed47fe..10123a523 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/withService.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/withService.kt
@@ -20,7 +20,7 @@ import kotlin.reflect.KType
* @param T the exact type of the service to be created.
* @return instance of the generated service.
*/
-public inline fun RPCClient.withService(): T {
+public inline fun RPCClient.withService(): T {
return withService(T::class)
}
@@ -33,7 +33,7 @@ public inline fun RPCClient.withService(): T {
* @param serviceKType [KType] of the service to be created.
* @return instance of the generated service.
*/
-public fun RPCClient.withService(serviceKType: KType): T {
+public fun RPCClient.withService(serviceKType: KType): T {
return withService(serviceKType.kClass())
}
@@ -52,7 +52,7 @@ private val SERVICE_ID = atomic(0L)
* @param serviceKClass [KClass] of the service to be created.
* @return instance of the generated service.
*/
-public fun RPCClient.withService(serviceKClass: KClass): T {
+public fun RPCClient.withService(serviceKClass: KClass): T {
val provider = findRPCStubProvider>(
kClass = serviceKClass,
resultKClass = RPCStubServiceProvider::class.safeCast(),
diff --git a/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt b/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
index b3805eca4..2a40cf266 100644
--- a/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
+++ b/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
@@ -7,7 +7,7 @@
package kotlinx.rpc.internal
import js.objects.Object
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.utils.InternalRPCApi
import kotlin.reflect.AssociatedObjectKey
import kotlin.reflect.ExperimentalAssociatedObjects
@@ -20,7 +20,7 @@ import kotlin.reflect.findAssociatedObject
@Target(AnnotationTarget.CLASS)
public annotation class WithRPCStubObject(
@Suppress("unused")
- val stub: KClass>
+ val stub: KClass>,
)
@InternalRPCApi
diff --git a/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt b/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt
index 0eb4cbb0c..b7da9531f 100644
--- a/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt
+++ b/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt
@@ -6,7 +6,7 @@
package kotlinx.rpc.internal
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.utils.InternalRPCApi
import kotlin.reflect.AssociatedObjectKey
import kotlin.reflect.ExperimentalAssociatedObjects
@@ -19,7 +19,7 @@ import kotlin.reflect.findAssociatedObject
@Target(AnnotationTarget.CLASS)
public annotation class WithRPCStubObject(
@Suppress("unused")
- val stub: KClass>
+ val stub: KClass>,
)
@InternalRPCApi
diff --git a/core/src/wasmJsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.wasm.kt b/core/src/wasmJsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.wasm.kt
index 054f9fbe4..0b03caeca 100644
--- a/core/src/wasmJsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.wasm.kt
+++ b/core/src/wasmJsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.wasm.kt
@@ -6,7 +6,7 @@
package kotlinx.rpc.internal
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.utils.InternalRPCApi
import kotlin.reflect.AssociatedObjectKey
import kotlin.reflect.ExperimentalAssociatedObjects
@@ -19,7 +19,7 @@ import kotlin.reflect.findAssociatedObject
@Target(AnnotationTarget.CLASS)
public annotation class WithRPCStubObject(
@Suppress("unused")
- val stub: KClass>
+ val stub: KClass>,
)
@OptIn(ExperimentalAssociatedObjects::class)
diff --git a/core/src/wasmWasiMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.wasi.kt b/core/src/wasmWasiMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.wasi.kt
index 054f9fbe4..0b03caeca 100644
--- a/core/src/wasmWasiMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.wasi.kt
+++ b/core/src/wasmWasiMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.wasi.kt
@@ -6,7 +6,7 @@
package kotlinx.rpc.internal
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.utils.InternalRPCApi
import kotlin.reflect.AssociatedObjectKey
import kotlin.reflect.ExperimentalAssociatedObjects
@@ -19,7 +19,7 @@ import kotlin.reflect.findAssociatedObject
@Target(AnnotationTarget.CLASS)
public annotation class WithRPCStubObject(
@Suppress("unused")
- val stub: KClass>
+ val stub: KClass>,
)
@OptIn(ExperimentalAssociatedObjects::class)
diff --git a/docs/pages/kotlinx-rpc/topics/features.topic b/docs/pages/kotlinx-rpc/topics/features.topic
index 6ad69c72b..9b236eae8 100644
--- a/docs/pages/kotlinx-rpc/topics/features.topic
+++ b/docs/pages/kotlinx-rpc/topics/features.topic
@@ -24,7 +24,8 @@
val innerFlow: StateFlow<Int>
}
- interface MyService : RPC {
+ @Rpc
+ interface MyService : RemoteService {
suspend fun sendStream(stream: Flow<Flow<Int>>): Flow<StreamResult>
}
@@ -85,7 +86,8 @@
Our protocol provides you with an ability to declare service fields:
- interface MyService : RPC {
+ @Rpc
+ interface MyService : RemoteService {
val plainFlow: Flow<Int>
val sharedFlow: SharedFlow<Int>
val stateFlow: StateFlow<Int>
@@ -142,7 +144,8 @@
- interface MyService : RPC {
+ @Rpc
+ interface MyService : RemoteService {
val flow: StateFlow<Int>
}
@@ -163,7 +166,8 @@
(when withService
method is called):
- interface MyService : RPC {
+ @Rpc
+ interface MyService : RemoteService {
val lazyFlow: Flow<Int> // initialized on first access
@RPCEagerField
@@ -171,4 +175,4 @@
}
-
\ No newline at end of file
+
diff --git a/docs/pages/kotlinx-rpc/topics/services.topic b/docs/pages/kotlinx-rpc/topics/services.topic
index 0c34097a8..a2840eb18 100644
--- a/docs/pages/kotlinx-rpc/topics/services.topic
+++ b/docs/pages/kotlinx-rpc/topics/services.topic
@@ -15,7 +15,8 @@
A simple service can be declared as follows:
- interface MyService : RPC {
+ @Rpc
+ interface MyService : RemoteService {
suspend fun hello(name: String): String
}
@@ -41,4 +42,4 @@
}
The server will use that implementation to answer the client requests.
-
\ No newline at end of file
+
diff --git a/docs/pages/kotlinx-rpc/topics/transport.topic b/docs/pages/kotlinx-rpc/topics/transport.topic
index cf8d16915..a89f193db 100644
--- a/docs/pages/kotlinx-rpc/topics/transport.topic
+++ b/docs/pages/kotlinx-rpc/topics/transport.topic
@@ -86,7 +86,8 @@
val numberOfDogs: Int
)
- interface ImageService : RPC {
+ @Rpc
+ interface ImageService : RemoteService {
suspend fun processImage(url: Srting): ProcessedImage
}
@@ -147,4 +148,4 @@
You can provide your own transport and even your own fully implemented protocols,
while the library will take care of code generation.
-
\ No newline at end of file
+
diff --git a/krpc/krpc-client/api/krpc-client.api b/krpc/krpc-client/api/krpc-client.api
index 084717c78..d62feabc2 100644
--- a/krpc/krpc-client/api/krpc-client.api
+++ b/krpc/krpc-client/api/krpc-client.api
@@ -10,8 +10,3 @@ public abstract class kotlinx/rpc/krpc/client/KRPCClient : kotlinx/rpc/krpc/inte
public final fun registerStateFlowField (Lkotlinx/coroutines/CoroutineScope;Lkotlinx/rpc/RPCField;)Lkotlinx/coroutines/flow/StateFlow;
}
-public final class kotlinx/rpc/krpc/client/RPCClientUtilsKt {
- public static final fun withService (Lkotlinx/rpc/RPCClient;Lkotlin/reflect/KClass;)Lkotlinx/rpc/RPC;
- public static final fun withService (Lkotlinx/rpc/RPCClient;Lkotlin/reflect/KType;)Lkotlinx/rpc/RPC;
-}
-
diff --git a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/krpc/client/RPCClientUtils.kt b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/krpc/client/RPCClientUtils.kt
deleted file mode 100644
index 99e3b99a8..000000000
--- a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/krpc/client/RPCClientUtils.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
- */
-
-package kotlinx.rpc.krpc.client
-
-import kotlinx.rpc.RPC
-import kotlinx.rpc.RPCClient
-import kotlinx.rpc.withService
-import kotlin.reflect.KClass
-import kotlin.reflect.KType
-
-@Deprecated(
- message = "withService was moved to kotlinx-rpc-core, to kotlinx.rpc package",
- level = DeprecationLevel.WARNING,
- replaceWith = ReplaceWith("withService()", "kotlinx.rpc.withService")
-)
-public inline fun RPCClient.withService(): T {
- return withService()
-}
-
-@Deprecated(
- message = "withService was moved to kotlinx-rpc-core, to kotlinx.rpc package",
- level = DeprecationLevel.WARNING,
- replaceWith = ReplaceWith("withService(serviceKType)", "kotlinx.rpc.withService")
-)
-public fun RPCClient.withService(serviceKType: KType): T {
- return withService(serviceKType)
-}
-
-@Deprecated(
- message = "withService was moved to kotlinx-rpc-core, to kotlinx.rpc package",
- level = DeprecationLevel.WARNING,
- replaceWith = ReplaceWith("withService(serviceKClass)", "kotlinx.rpc.withService")
-)
-public fun RPCClient.withService(serviceKClass: KClass): T {
- return withService(serviceKClass)
-}
diff --git a/krpc/krpc-ktor/krpc-ktor-core/src/jvmTest/kotlin/kotlinx/rpc/krpc/ktor/KtorTransportTest.kt b/krpc/krpc-ktor/krpc-ktor-core/src/jvmTest/kotlin/kotlinx/rpc/krpc/ktor/KtorTransportTest.kt
index 574a7bd09..5e9d4eb80 100644
--- a/krpc/krpc-ktor/krpc-ktor-core/src/jvmTest/kotlin/kotlinx/rpc/krpc/ktor/KtorTransportTest.kt
+++ b/krpc/krpc-ktor/krpc-ktor-core/src/jvmTest/kotlin/kotlinx/rpc/krpc/ktor/KtorTransportTest.kt
@@ -9,7 +9,8 @@ package kotlinx.rpc.krpc.ktor
import io.ktor.server.application.*
import io.ktor.server.testing.*
import kotlinx.coroutines.cancel
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.krpc.ktor.client.installRPC
import kotlinx.rpc.krpc.ktor.client.rpc
import kotlinx.rpc.krpc.ktor.client.rpcConfig
@@ -21,7 +22,8 @@ import org.junit.Assert.assertEquals
import kotlin.coroutines.CoroutineContext
import kotlin.test.Test
-interface NewService : RPC {
+@Rpc
+interface NewService : RemoteService {
suspend fun echo(value: String): String
}
diff --git a/krpc/krpc-ktor/krpc-ktor-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/ktor/server/RPCRoute.kt b/krpc/krpc-ktor/krpc-ktor-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/ktor/server/RPCRoute.kt
index 41647e2b8..2fb71d0d1 100644
--- a/krpc/krpc-ktor/krpc-ktor-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/ktor/server/RPCRoute.kt
+++ b/krpc/krpc-ktor/krpc-ktor-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/ktor/server/RPCRoute.kt
@@ -5,8 +5,8 @@
package kotlinx.rpc.krpc.ktor.server
import io.ktor.server.websocket.*
-import kotlinx.rpc.RPC
import kotlinx.rpc.RPCServer
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.krpc.RPCConfigBuilder
import kotlin.coroutines.CoroutineContext
import kotlin.reflect.KClass
@@ -42,7 +42,7 @@ public class RPCRoute(
* @param serviceKClass [KClass] of the [Service].
* @param serviceFactory function that produces the actual implementation of the service that will handle the calls.
*/
- public fun registerService(
+ public fun registerService(
serviceKClass: KClass,
serviceFactory: (CoroutineContext) -> Service,
) {
@@ -60,7 +60,7 @@ public class RPCRoute(
* type `MyService` should be specified explicitly.
* @param serviceFactory function that produces the actual implementation of the service that will handle the calls.
*/
- public inline fun registerService(
+ public inline fun registerService(
noinline serviceFactory: (CoroutineContext) -> Service,
) {
registerService(Service::class, serviceFactory)
diff --git a/krpc/krpc-server/src/commonMain/kotlin/kotlinx/rpc/krpc/server/internal/RPCServiceUtils.kt b/krpc/krpc-server/src/commonMain/kotlin/kotlinx/rpc/krpc/server/internal/RPCServiceUtils.kt
index 2c8661e5b..ed0d380fd 100644
--- a/krpc/krpc-server/src/commonMain/kotlin/kotlinx/rpc/krpc/server/internal/RPCServiceUtils.kt
+++ b/krpc/krpc-server/src/commonMain/kotlin/kotlinx/rpc/krpc/server/internal/RPCServiceUtils.kt
@@ -4,7 +4,7 @@
package kotlinx.rpc.krpc.server.internal
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.RPCServiceMethodSerializationTypeProvider
import kotlinx.rpc.internal.findRPCStubProvider
import kotlinx.rpc.internal.kClass
@@ -16,7 +16,7 @@ import kotlin.reflect.KType
* Utility method that returns [KType] for the class which is used to serialize method request with the [methodName]
*/
@InternalRPCApi
-public inline fun rpcServiceMethodSerializationTypeOf(methodName: String): KType? {
+public inline fun rpcServiceMethodSerializationTypeOf(methodName: String): KType? {
return rpcServiceMethodSerializationTypeOf(T::class, methodName)
}
diff --git a/krpc/krpc-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/server/KRPCServer.kt b/krpc/krpc-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/server/KRPCServer.kt
index b986afc03..ed5706736 100644
--- a/krpc/krpc-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/server/KRPCServer.kt
+++ b/krpc/krpc-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/server/KRPCServer.kt
@@ -5,8 +5,8 @@
package kotlinx.rpc.krpc.server
import kotlinx.coroutines.*
-import kotlinx.rpc.RPC
import kotlinx.rpc.RPCServer
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.qualifiedClassName
import kotlinx.rpc.internal.utils.InternalRPCApi
import kotlinx.rpc.internal.utils.map.ConcurrentHashMap
@@ -99,7 +99,7 @@ public abstract class KRPCServer(
}
}
- final override fun registerService(
+ final override fun registerService(
serviceKClass: KClass,
serviceFactory: (CoroutineContext) -> Service,
) {
@@ -122,7 +122,7 @@ public abstract class KRPCServer(
}
}
- private fun createNewServiceInstance(
+ private fun createNewServiceInstance(
serviceKClass: KClass,
serviceFactory: (CoroutineContext) -> Service,
): RPCServerService {
diff --git a/krpc/krpc-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/server/internal/RPCServerService.kt b/krpc/krpc-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/server/internal/RPCServerService.kt
index b19e11db8..ed68e0ef8 100644
--- a/krpc/krpc-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/server/internal/RPCServerService.kt
+++ b/krpc/krpc-server/src/jvmMain/kotlin/kotlinx/rpc/krpc/server/internal/RPCServerService.kt
@@ -5,7 +5,7 @@
package kotlinx.rpc.krpc.server.internal
import kotlinx.coroutines.*
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.RPCMethodClassArguments
import kotlinx.rpc.internal.qualifiedClassName
import kotlinx.rpc.internal.utils.map.ConcurrentHashMap
@@ -24,7 +24,7 @@ import kotlin.reflect.KClass
import kotlin.reflect.KProperty
import kotlin.reflect.full.callSuspend
-internal class RPCServerService(
+internal class RPCServerService(
private val service: T,
private val serviceKClass: KClass,
override val config: RPCConfig.Server,
diff --git a/krpc/krpc-test/src/jvmMain/kotlin/kotlinx/rpc/krpc/test/KRPCTestService.kt b/krpc/krpc-test/src/jvmMain/kotlin/kotlinx/rpc/krpc/test/KRPCTestService.kt
index 60a03d617..ddd6ca0dd 100644
--- a/krpc/krpc-test/src/jvmMain/kotlin/kotlinx/rpc/krpc/test/KRPCTestService.kt
+++ b/krpc/krpc-test/src/jvmMain/kotlin/kotlinx/rpc/krpc/test/KRPCTestService.kt
@@ -7,10 +7,12 @@ package kotlinx.rpc.krpc.test
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.StateFlow
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
@Suppress("detekt.TooManyFunctions")
-interface KRPCTestService : RPC {
+@Rpc
+interface KRPCTestService : RemoteService {
suspend fun empty()
suspend fun returnType(): String
suspend fun simpleWithParams(name: String): String
diff --git a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/ProtocolTestBase.kt b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/ProtocolTestBase.kt
index cebe69a4c..02e67ad2d 100644
--- a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/ProtocolTestBase.kt
+++ b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/ProtocolTestBase.kt
@@ -9,7 +9,8 @@ import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.job
import kotlinx.coroutines.test.TestResult
import kotlinx.coroutines.test.TestScope
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.internal.utils.hex.hexToReadableBinary
import kotlinx.rpc.krpc.RPCConfig
import kotlinx.rpc.krpc.client.KRPCClient
@@ -90,7 +91,8 @@ abstract class ProtocolTestBase {
}
}
-interface ProtocolTestService : RPC {
+@Rpc
+interface ProtocolTestService : RemoteService {
suspend fun sendRequest()
}
diff --git a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/SamplingService.kt b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/SamplingService.kt
index 54f3a416d..998e87975 100644
--- a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/SamplingService.kt
+++ b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/SamplingService.kt
@@ -9,7 +9,8 @@ package org.jetbrains.krpc.test.api.util
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.krpc.test.plainFlow
import kotlinx.rpc.krpc.test.sharedFlowOfT
import kotlinx.rpc.krpc.test.stateFlowOfT
@@ -21,7 +22,8 @@ data class SamplingData(
val data: String,
)
-interface SamplingService : RPC {
+@Rpc
+interface SamplingService : RemoteService {
suspend fun echo(arg1: String, data: SamplingData): SamplingData
suspend fun clientStream(flow: Flow): List
diff --git a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/TransportTest.kt b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/TransportTest.kt
index 0e0dedaab..ed44cd4f5 100644
--- a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/TransportTest.kt
+++ b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/TransportTest.kt
@@ -7,6 +7,7 @@ package kotlinx.rpc.krpc.test
import junit.framework.TestCase.assertEquals
import kotlinx.coroutines.*
import kotlinx.rpc.*
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.krpc.RPCConfigBuilder
import kotlinx.rpc.krpc.rpcClientConfig
import kotlinx.rpc.krpc.rpcServerConfig
@@ -18,11 +19,13 @@ import kotlin.test.Test
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
-interface Echo : RPC {
+@Rpc
+interface Echo : RemoteService {
suspend fun echo(message: String): String
}
-interface Second : RPC {
+@Rpc
+interface Second : RemoteService {
suspend fun second(message: String): String
}
@@ -232,7 +235,7 @@ class TransportTest {
assertTrue(echoServices.single().coroutineContext.job.isCancelled)
}
- private inline fun RPCServer.registerServiceAndReturn(
+ private inline fun RPCServer.registerServiceAndReturn(
crossinline body: (CoroutineContext) -> Impl,
): List {
val instances = mutableListOf()
diff --git a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/api/WireSamplingTestScope.kt b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/api/WireSamplingTestScope.kt
index d71934dd5..5ed99e372 100644
--- a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/api/WireSamplingTestScope.kt
+++ b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/api/WireSamplingTestScope.kt
@@ -11,7 +11,7 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.test.TestResult
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runTest
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.internal.utils.hex.hexToByteArrayInternal
import kotlinx.rpc.internal.utils.hex.hexToReadableBinary
import kotlinx.rpc.krpc.RPCTransportMessage
@@ -246,7 +246,7 @@ private class WireToolkit(scope: CoroutineScope, format: SamplingFormat, val log
DumpLoggerContainer.set(dumpLogger)
}
- private inline fun Service.withConsistentServiceId(): Service = apply {
+ private inline fun Service.withConsistentServiceId(): Service = apply {
val clazz = this::class.java
val prop = clazz
.declaredFields
diff --git a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/cancellation/CancellationService.kt b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/cancellation/CancellationService.kt
index 37c168e25..dcd83bb7c 100644
--- a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/cancellation/CancellationService.kt
+++ b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/krpc/test/cancellation/CancellationService.kt
@@ -7,13 +7,15 @@ package kotlinx.rpc.krpc.test.cancellation
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.krpc.invokeOnStreamScopeCompletion
import kotlin.coroutines.CoroutineContext
import kotlin.properties.Delegates
import kotlin.test.assertIs
-interface CancellationService : RPC {
+@Rpc
+interface CancellationService : RemoteService {
suspend fun longRequest()
suspend fun serverDelay(millis: Long)
diff --git a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/ACodeGenerationException.kt b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/ACodeGenerationException.kt
index 3eddf7e41..72814052e 100644
--- a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/ACodeGenerationException.kt
+++ b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/ACodeGenerationException.kt
@@ -29,7 +29,7 @@ class FieldExtensionReceiverCodeGenerationException(declaration: KSDeclaration?
ACodeGenerationException("RPC Service field can not have extension receiver", declaration)
class ForbiddenFieldTypeCodeGenerationException(declaration: KSDeclaration? = null) : ACodeGenerationException(
- initMessage = "Only Flow, SharedFlow and StateFlow fields are allowed in RPC Service interfaces",
+ initMessage = "Only Flow, SharedFlow and StateFlow fields are allowed in a RemoteService",
declaration = declaration
)
diff --git a/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.fir.ir.txt b/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.fir.ir.txt
index 07d5368b1..4616c7425 100644
--- a/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.fir.ir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.fir.ir.txt
@@ -311,7 +311,9 @@ FILE fqName: fileName:/customParameterTypes.kt
index: CONST Int type=kotlin.Int value=0
value: CALL 'public final fun (): kotlin.String declared in .TestData' type=kotlin.String origin=GET_PROPERTY
$this: GET_VAR 'self: .TestData declared in .TestData.write$Self' type=.TestData origin=null
- CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RPC]
+ CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RemoteService]
+ annotations:
+ Rpc
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService
CLASS GENERATED[kotlinx.rpc.codegen.RPCGeneratedStubKey] CLASS name:$rpcServiceStub modality:FINAL visibility:public superTypes:[.BoxService]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService.$rpcServiceStub
@@ -1060,16 +1062,16 @@ FILE fqName: fileName:/customParameterTypes.kt
: kotlin.String
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
- public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RPC
+ public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
- public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RPC
+ public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
- public open fun toString (): kotlin.String declared in kotlinx.rpc.RPC
+ public open fun toString (): kotlin.String declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN name:test1 visibility:public modality:ABSTRACT <> ($this:.BoxService, testData:.TestData) returnType:kotlin.String [suspend]
$this: VALUE_PARAMETER name: type:.BoxService
@@ -1080,11 +1082,11 @@ FILE fqName: fileName:/customParameterTypes.kt
PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
public abstract coroutineContext: kotlin.coroutines.CoroutineContext
- FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RPC) returnType:kotlin.coroutines.CoroutineContext [fake_override]
+ FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RemoteService) returnType:kotlin.coroutines.CoroutineContext [fake_override]
correspondingProperty: PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
- public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RPC
- $this: VALUE_PARAMETER name: type:kotlinx.rpc.RPC
+ public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RemoteService
+ $this: VALUE_PARAMETER name: type:kotlinx.rpc.RemoteService
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in '
diff --git a/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.fir.txt b/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.fir.txt
index 16083527f..8f4220e9c 100644
--- a/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.fir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.fir.txt
@@ -37,7 +37,7 @@ FILE: customParameterTypes.kt
}
}
- public abstract interface BoxService : R|kotlinx/rpc/RPC| {
+ @R|kotlinx/rpc/annotations/Rpc|() public abstract interface BoxService : R|kotlinx/rpc/RemoteService| {
public abstract suspend fun test1(testData: R|TestData|): R|kotlin/String|
public abstract suspend fun test2(testData: R|TestData|): R|kotlin/String|
diff --git a/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.kt b/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.kt
index 4bda56322..e8f0b5472 100644
--- a/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.kt
+++ b/tests/compiler-plugin-tests/src/testData/box/customParameterTypes.kt
@@ -5,14 +5,16 @@
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.Serializable
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.withService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.codegen.test.TestRpcClient
@Serializable
data class TestData(val value: String)
-interface BoxService : RPC {
+@Rpc
+interface BoxService : RemoteService {
suspend fun test1(testData: TestData): String
suspend fun test2(testData: TestData): String
diff --git a/tests/compiler-plugin-tests/src/testData/box/fields.fir.ir.txt b/tests/compiler-plugin-tests/src/testData/box/fields.fir.ir.txt
index 4746e26ad..dc3e1a5a7 100644
--- a/tests/compiler-plugin-tests/src/testData/box/fields.fir.ir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/fields.fir.ir.txt
@@ -1,5 +1,7 @@
FILE fqName: fileName:/fields.kt
- CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RPC]
+ CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RemoteService]
+ annotations:
+ Rpc
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService
CLASS GENERATED[kotlinx.rpc.codegen.RPCGeneratedStubKey] CLASS name:$rpcServiceStub modality:FINAL visibility:public superTypes:[.BoxService]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService.$rpcServiceStub
@@ -244,25 +246,25 @@ FILE fqName: fileName:/fields.kt
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
- public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RPC
+ public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
- public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RPC
+ public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
- public open fun toString (): kotlin.String declared in kotlinx.rpc.RPC
+ public open fun toString (): kotlin.String declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
public abstract coroutineContext: kotlin.coroutines.CoroutineContext
- FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RPC) returnType:kotlin.coroutines.CoroutineContext [fake_override]
+ FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RemoteService) returnType:kotlin.coroutines.CoroutineContext [fake_override]
correspondingProperty: PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
- public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RPC
- $this: VALUE_PARAMETER name: type:kotlinx.rpc.RPC
+ public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RemoteService
+ $this: VALUE_PARAMETER name: type:kotlinx.rpc.RemoteService
PROPERTY name:plainFlow visibility:public modality:ABSTRACT [val]
FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:ABSTRACT <> ($this:.BoxService) returnType:kotlinx.coroutines.flow.Flow
correspondingProperty: PROPERTY name:plainFlow visibility:public modality:ABSTRACT [val]
diff --git a/tests/compiler-plugin-tests/src/testData/box/fields.fir.txt b/tests/compiler-plugin-tests/src/testData/box/fields.fir.txt
index 4fd39dbf1..ec381714c 100644
--- a/tests/compiler-plugin-tests/src/testData/box/fields.fir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/fields.fir.txt
@@ -1,5 +1,5 @@
FILE: fields.kt
- public abstract interface BoxService : R|kotlinx/rpc/RPC| {
+ @R|kotlinx/rpc/annotations/Rpc|() public abstract interface BoxService : R|kotlinx/rpc/RemoteService| {
public abstract val plainFlow: R|kotlinx/coroutines/flow/Flow|
public get(): R|kotlinx/coroutines/flow/Flow|
diff --git a/tests/compiler-plugin-tests/src/testData/box/fields.kt b/tests/compiler-plugin-tests/src/testData/box/fields.kt
index 1c35cdc9a..0b08d6759 100644
--- a/tests/compiler-plugin-tests/src/testData/box/fields.kt
+++ b/tests/compiler-plugin-tests/src/testData/box/fields.kt
@@ -4,11 +4,13 @@
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.withService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.codegen.test.TestRpcClient
-interface BoxService : RPC {
+@Rpc
+interface BoxService : RemoteService {
val plainFlow: Flow
val sharedFlow: SharedFlow
diff --git a/tests/compiler-plugin-tests/src/testData/box/flowParameter.fir.ir.txt b/tests/compiler-plugin-tests/src/testData/box/flowParameter.fir.ir.txt
index 761e44206..e5748a0e8 100644
--- a/tests/compiler-plugin-tests/src/testData/box/flowParameter.fir.ir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/flowParameter.fir.ir.txt
@@ -1,5 +1,7 @@
FILE fqName: fileName:/flowParameter.kt
- CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RPC]
+ CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RemoteService]
+ annotations:
+ Rpc
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService
CLASS GENERATED[kotlinx.rpc.codegen.RPCGeneratedStubKey] CLASS name:$rpcServiceStub modality:FINAL visibility:public superTypes:[.BoxService]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService.$rpcServiceStub
@@ -477,16 +479,16 @@ FILE fqName: fileName:/flowParameter.kt
: kotlin.String
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
- public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RPC
+ public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
- public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RPC
+ public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
- public open fun toString (): kotlin.String declared in kotlinx.rpc.RPC
+ public open fun toString (): kotlin.String declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN name:stream visibility:public modality:ABSTRACT <> ($this:.BoxService, flow:kotlinx.coroutines.flow.Flow) returnType:kotlin.String [suspend]
$this: VALUE_PARAMETER name: type:.BoxService
@@ -494,11 +496,11 @@ FILE fqName: fileName:/flowParameter.kt
PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
public abstract coroutineContext: kotlin.coroutines.CoroutineContext
- FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RPC) returnType:kotlin.coroutines.CoroutineContext [fake_override]
+ FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RemoteService) returnType:kotlin.coroutines.CoroutineContext [fake_override]
correspondingProperty: PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
- public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RPC
- $this: VALUE_PARAMETER name: type:kotlinx.rpc.RPC
+ public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RemoteService
+ $this: VALUE_PARAMETER name: type:kotlinx.rpc.RemoteService
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in '
diff --git a/tests/compiler-plugin-tests/src/testData/box/flowParameter.fir.txt b/tests/compiler-plugin-tests/src/testData/box/flowParameter.fir.txt
index bb9b6aa26..bbcf6fbd8 100644
--- a/tests/compiler-plugin-tests/src/testData/box/flowParameter.fir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/flowParameter.fir.txt
@@ -1,5 +1,5 @@
FILE: flowParameter.kt
- public abstract interface BoxService : R|kotlinx/rpc/RPC| {
+ @R|kotlinx/rpc/annotations/Rpc|() public abstract interface BoxService : R|kotlinx/rpc/RemoteService| {
public abstract suspend fun stream(flow: R|kotlinx/coroutines/flow/Flow|): R|kotlin/String|
public final class $rpcServiceStub : R|kotlin/Any| {
diff --git a/tests/compiler-plugin-tests/src/testData/box/flowParameter.kt b/tests/compiler-plugin-tests/src/testData/box/flowParameter.kt
index 06362e391..bf1be1abf 100644
--- a/tests/compiler-plugin-tests/src/testData/box/flowParameter.kt
+++ b/tests/compiler-plugin-tests/src/testData/box/flowParameter.kt
@@ -4,11 +4,13 @@
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.runBlocking
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.withService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.codegen.test.TestRpcClient
-interface BoxService : RPC {
+@Rpc
+interface BoxService : RemoteService {
// plugin should add @Contextual annotation to the flow parameter in the generated class
suspend fun stream(flow: Flow): String
}
diff --git a/tests/compiler-plugin-tests/src/testData/box/multiModule.fir.ir.txt b/tests/compiler-plugin-tests/src/testData/box/multiModule.fir.ir.txt
index df3fa624e..765920175 100644
--- a/tests/compiler-plugin-tests/src/testData/box/multiModule.fir.ir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/multiModule.fir.ir.txt
@@ -1,6 +1,8 @@
Module: lib
FILE fqName: fileName:/module_lib_multiModule.kt
- CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RPC]
+ CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RemoteService]
+ annotations:
+ Rpc
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService
CLASS GENERATED[kotlinx.rpc.codegen.RPCGeneratedStubKey] CLASS name:$rpcServiceStub modality:FINAL visibility:public superTypes:[.BoxService]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService.$rpcServiceStub
@@ -228,27 +230,27 @@ FILE fqName: fileName:/module_lib_multiModule.kt
: kotlin.String
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
- public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RPC
+ public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
- public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RPC
+ public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
- public open fun toString (): kotlin.String declared in kotlinx.rpc.RPC
+ public open fun toString (): kotlin.String declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN name:simple visibility:public modality:ABSTRACT <> ($this:.BoxService) returnType:kotlin.String [suspend]
$this: VALUE_PARAMETER name: type:.BoxService
PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
public abstract coroutineContext: kotlin.coroutines.CoroutineContext
- FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RPC) returnType:kotlin.coroutines.CoroutineContext [fake_override]
+ FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RemoteService) returnType:kotlin.coroutines.CoroutineContext [fake_override]
correspondingProperty: PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
- public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RPC
- $this: VALUE_PARAMETER name: type:kotlinx.rpc.RPC
+ public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RemoteService
+ $this: VALUE_PARAMETER name: type:kotlinx.rpc.RemoteService
Module: main
FILE fqName: fileName:/module_main_multiModule.kt
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
diff --git a/tests/compiler-plugin-tests/src/testData/box/multiModule.fir.txt b/tests/compiler-plugin-tests/src/testData/box/multiModule.fir.txt
index 28244d13f..92835fc84 100644
--- a/tests/compiler-plugin-tests/src/testData/box/multiModule.fir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/multiModule.fir.txt
@@ -1,6 +1,6 @@
Module: lib
FILE: module_lib_multiModule.kt
- public abstract interface BoxService : R|kotlinx/rpc/RPC| {
+ @R|kotlinx/rpc/annotations/Rpc|() public abstract interface BoxService : R|kotlinx/rpc/RemoteService| {
public abstract suspend fun simple(): R|kotlin/String|
public final class $rpcServiceStub : R|kotlin/Any| {
diff --git a/tests/compiler-plugin-tests/src/testData/box/multiModule.kt b/tests/compiler-plugin-tests/src/testData/box/multiModule.kt
index 6d89cfb3b..a575bb86d 100644
--- a/tests/compiler-plugin-tests/src/testData/box/multiModule.kt
+++ b/tests/compiler-plugin-tests/src/testData/box/multiModule.kt
@@ -4,16 +4,18 @@
// MODULE: lib
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
+import kotlinx.rpc.annotations.Rpc
-interface BoxService : RPC {
+@Rpc
+interface BoxService : RemoteService {
suspend fun simple(): String
}
// MODULE: main(lib)
import kotlinx.coroutines.runBlocking
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.withService
import kotlinx.rpc.codegen.test.TestRpcClient
diff --git a/tests/compiler-plugin-tests/src/testData/box/simple.fir.ir.txt b/tests/compiler-plugin-tests/src/testData/box/simple.fir.ir.txt
index e994089be..8f07a49d4 100644
--- a/tests/compiler-plugin-tests/src/testData/box/simple.fir.ir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/simple.fir.ir.txt
@@ -1,5 +1,7 @@
FILE fqName: fileName:/simple.kt
- CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RPC]
+ CLASS INTERFACE name:BoxService modality:ABSTRACT visibility:public superTypes:[kotlinx.rpc.RemoteService]
+ annotations:
+ Rpc
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService
CLASS GENERATED[kotlinx.rpc.codegen.RPCGeneratedStubKey] CLASS name:$rpcServiceStub modality:FINAL visibility:public superTypes:[.BoxService]
$this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.BoxService.$rpcServiceStub
@@ -227,27 +229,27 @@ FILE fqName: fileName:/simple.kt
: kotlin.String
FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator]
overridden:
- public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RPC
+ public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
VALUE_PARAMETER name:other index:0 type:kotlin.Any?
FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override]
overridden:
- public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RPC
+ public open fun hashCode (): kotlin.Int declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override]
overridden:
- public open fun toString (): kotlin.String declared in kotlinx.rpc.RPC
+ public open fun toString (): kotlin.String declared in kotlinx.rpc.RemoteService
$this: VALUE_PARAMETER name: type:kotlin.Any
FUN name:simple visibility:public modality:ABSTRACT <> ($this:.BoxService) returnType:kotlin.String [suspend]
$this: VALUE_PARAMETER name: type:.BoxService
PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
public abstract coroutineContext: kotlin.coroutines.CoroutineContext
- FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RPC) returnType:kotlin.coroutines.CoroutineContext [fake_override]
+ FUN FAKE_OVERRIDE name: visibility:public modality:ABSTRACT <> ($this:kotlinx.rpc.RemoteService) returnType:kotlin.coroutines.CoroutineContext [fake_override]
correspondingProperty: PROPERTY FAKE_OVERRIDE name:coroutineContext visibility:public modality:ABSTRACT [fake_override,val]
overridden:
- public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RPC
- $this: VALUE_PARAMETER name: type:kotlinx.rpc.RPC
+ public abstract fun (): kotlin.coroutines.CoroutineContext declared in kotlinx.rpc.RemoteService
+ $this: VALUE_PARAMETER name: type:kotlinx.rpc.RemoteService
FUN name:box visibility:public modality:FINAL <> () returnType:kotlin.String
BLOCK_BODY
RETURN type=kotlin.Nothing from='public final fun box (): kotlin.String declared in '
diff --git a/tests/compiler-plugin-tests/src/testData/box/simple.fir.txt b/tests/compiler-plugin-tests/src/testData/box/simple.fir.txt
index 44770b129..dd09bd08f 100644
--- a/tests/compiler-plugin-tests/src/testData/box/simple.fir.txt
+++ b/tests/compiler-plugin-tests/src/testData/box/simple.fir.txt
@@ -1,5 +1,5 @@
FILE: simple.kt
- public abstract interface BoxService : R|kotlinx/rpc/RPC| {
+ @R|kotlinx/rpc/annotations/Rpc|() public abstract interface BoxService : R|kotlinx/rpc/RemoteService| {
public abstract suspend fun simple(): R|kotlin/String|
public final class $rpcServiceStub : R|kotlin/Any| {
diff --git a/tests/compiler-plugin-tests/src/testData/box/simple.kt b/tests/compiler-plugin-tests/src/testData/box/simple.kt
index 67a2488c1..637ba9990 100644
--- a/tests/compiler-plugin-tests/src/testData/box/simple.kt
+++ b/tests/compiler-plugin-tests/src/testData/box/simple.kt
@@ -3,11 +3,13 @@
*/
import kotlinx.coroutines.runBlocking
-import kotlinx.rpc.RPC
+import kotlinx.rpc.RemoteService
import kotlinx.rpc.withService
+import kotlinx.rpc.annotations.Rpc
import kotlinx.rpc.codegen.test.TestRpcClient
-interface BoxService : RPC {
+@Rpc
+interface BoxService : RemoteService {
suspend fun simple(): String
}