Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Api naming #236

Merged
merged 7 commits into from
Nov 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ A few things to remember:
* Every public API (including functions, classes, objects and so on) should be documented,
every parameter, property, return types and exceptions should be described properly.
* A Public API that is not intended to be used by end-users that couldn't be made private/internal due to technical reasons,
should be marked with `@InternalRPCApi` annotation.
should be marked with `@InternalRpcApi` annotation.

### Commit messages

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ Then, choose how do you want your service to communicate. For example, you can u
```kotlin
fun main() {
embeddedServer(Netty, 8080) {
install(RPC)
install(Krpc)
routing {
rpc("/awesome") {
rpcConfig {
Expand All @@ -61,7 +61,7 @@ fun main() {
```
To connect to the server use the following [Ktor Client](https://ktor.io/docs/create-client.html) setup:
```kotlin
val rpcClient = HttpClient { installRPC() }.rpc {
val rpcClient = HttpClient { installKrpc() }.rpc {
url("ws://localhost:8080/awesome")

rpcConfig {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ import org.jetbrains.kotlin.ir.util.dumpKotlinLike

/**
* This class scans user declared RPC service
* and returns all necessary information for code generation by [RPCStubGenerator].
* and returns all necessary information for code generation by [RpcStubGenerator].
*
* Some checks are preformed during scanning,
* but all user-friendly errors are expected to be thrown by frontend plugins
*/
internal object RPCDeclarationScanner {
fun scanServiceDeclaration(service: IrClass, ctx: RPCIrContext, logger: MessageCollector): ServiceDeclaration {
internal object RpcDeclarationScanner {
fun scanServiceDeclaration(service: IrClass, ctx: RpcIrContext, logger: MessageCollector): ServiceDeclaration {
var stubClass: IrClass? = null

val declarations = service.declarations.memoryOptimizedMap { declaration ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import org.jetbrains.kotlin.ir.util.properties
import org.jetbrains.kotlin.platform.konan.isNative
import org.jetbrains.kotlin.types.Variance

internal class RPCIrContext(
internal class RpcIrContext(
val pluginContext: IrPluginContext,
val versionSpecificApi: VersionSpecificApi,
) {
Expand Down Expand Up @@ -98,7 +98,7 @@ internal class RPCIrContext(
}

val rpcEagerFieldAnnotation by lazy {
getRpcIrClassSymbol("RPCEagerField")
getRpcIrClassSymbol("RpcEagerField")
}

val rpcServiceDescriptor by lazy {
Expand Down Expand Up @@ -200,7 +200,7 @@ internal class RPCIrContext(

val lazyGetValue by lazy {
namedFunction("kotlin", "getValue") {
it.owner.extensionReceiverParameter?.type?.classOrNull == this@RPCIrContext.lazy
it.owner.extensionReceiverParameter?.type?.classOrNull == this@RpcIrContext.lazy
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,16 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment

class RPCIrExtension(configuration: CompilerConfiguration) : IrGenerationExtension {
class RpcIrExtension(configuration: CompilerConfiguration) : IrGenerationExtension {
private val logger = configuration.get(VersionSpecificApi.INSTANCE.messageCollectorKey, MessageCollector.NONE)

override fun generate(
moduleFragment: IrModuleFragment,
pluginContext: IrPluginContext,
) {
val context = RPCIrContext(pluginContext, VersionSpecificApi.INSTANCE)
val context = RpcIrContext(pluginContext, VersionSpecificApi.INSTANCE)

val processor = RPCIrServiceProcessor(logger)
val processor = RpcIrServiceProcessor(logger)
moduleFragment.transform(processor, context)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer

internal class RPCIrServiceProcessor(
internal class RpcIrServiceProcessor(
@Suppress("unused")
private val logger: MessageCollector,
) : IrElementTransformer<RPCIrContext> {
override fun visitClass(declaration: IrClass, data: RPCIrContext): IrStatement {
) : IrElementTransformer<RpcIrContext> {
override fun visitClass(declaration: IrClass, data: RpcIrContext): IrStatement {
if (declaration.hasAnnotation(RpcClassId.rpcAnnotation)) {
processService(declaration, data)
}

return super.visitClass(declaration, data)
}

private fun processService(service: IrClass, context: RPCIrContext) {
val declaration = RPCDeclarationScanner.scanServiceDeclaration(service, context, logger)
RPCStubGenerator(declaration, context, logger).generate()
private fun processService(service: IrClass, context: RpcIrContext) {
val declaration = RpcDeclarationScanner.scanServiceDeclaration(service, context, logger)
RpcStubGenerator(declaration, context, logger).generate()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ private object Descriptor {
}

@Suppress("detekt.LargeClass", "detekt.TooManyFunctions")
internal class RPCStubGenerator(
internal class RpcStubGenerator(
private val declaration: ServiceDeclaration,
private val ctx: RPCIrContext,
private val ctx: RpcIrContext,
@Suppress("unused")
private val logger: MessageCollector,
) {
Expand Down Expand Up @@ -253,7 +253,7 @@ internal class RPCStubGenerator(

/**
* RPC fields.
* Can be of two kinds: Lazy and Eager (defined by `@RPCEagerField` annotation)
* Can be of two kinds: Lazy and Eager (defined by `@RpcEagerField` annotation)
*
* Lazy:
* ``` kotlin
Expand Down Expand Up @@ -623,15 +623,15 @@ internal class RPCStubGenerator(
* ```
*
* This method generates missing getters and backing fields' values.
* And adds RPCMethodClassArguments supertype with `asArray` method implemented.
* And adds RpcMethodClassArguments supertype with `asArray` method implemented.
*
* Resulting class:
* ```kotlin
* @Serializable
* class hello$rpcMethod(
* val arg1: String,
* val arg2: Int,
* ) : RPCMethodClassArguments {
* ) : RpcMethodClassArguments {
* // or emptyArray when no arguments
* override fun asArray(): Array<Any?> = arrayOf(arg1, arg2)
* }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
#

kotlinx.rpc.codegen.RPCCommandLineProcessor
kotlinx.rpc.codegen.RpcCommandLineProcessor
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
# Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
#

kotlinx.rpc.codegen.RPCCompilerPlugin
kotlinx.rpc.codegen.RpcCompilerPlugin
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

package kotlinx.rpc.codegen

import kotlinx.rpc.codegen.extension.RPCIrExtension
import kotlinx.rpc.codegen.extension.RpcIrExtension
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.compiler.plugin.CliOption
import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
Expand All @@ -14,14 +14,14 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter

@OptIn(ExperimentalCompilerApi::class)
class RPCCommandLineProcessor : CommandLineProcessor {
class RpcCommandLineProcessor : CommandLineProcessor {
override val pluginId = "kotlinx.rpc.compiler-plugin"

override val pluginOptions = emptyList<CliOption>()
}

@OptIn(ExperimentalCompilerApi::class)
class RPCCompilerPlugin : CompilerPluginRegistrar() {
class RpcCompilerPlugin : CompilerPluginRegistrar() {
override val supportsK2: Boolean = true

override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
Expand All @@ -33,6 +33,6 @@ class RPCCompilerPlugin : CompilerPluginRegistrar() {
fun CompilerPluginRegistrar.ExtensionStorage.registerRpcExtensions(configuration: CompilerConfiguration) {
VersionSpecificApi.INSTANCE = VersionSpecificApiImpl

IrGenerationExtension.registerExtension(RPCIrExtension(configuration))
IrGenerationExtension.registerExtension(RpcIrExtension(configuration))
FirExtensionRegistrarAdapter.registerExtension(FirRpcExtensionRegistrar(configuration))
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,30 +12,30 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlinx.serialization.compiler.fir.SerializationPluginKey

internal class RPCGeneratedStubKey(
internal class RpcGeneratedStubKey(
private val serviceName: Name,
val functions: List<FirFunctionSymbol<*>>,
) : GeneratedDeclarationKey() {
override fun toString(): String {
return "RPCGeneratedStubKey.$serviceName"
return "RpcGeneratedStubKey.$serviceName"
}
}

internal val FirBasedSymbol<*>.generatedRpcServiceStubKey: RPCGeneratedStubKey? get() =
(origin as? FirDeclarationOrigin.Plugin)?.key as? RPCGeneratedStubKey
internal val FirBasedSymbol<*>.generatedRpcServiceStubKey: RpcGeneratedStubKey? get() =
(origin as? FirDeclarationOrigin.Plugin)?.key as? RpcGeneratedStubKey

internal class RPCGeneratedRpcMethodClassKey(
internal class RpcGeneratedRpcMethodClassKey(
val rpcMethod: FirFunctionSymbol<*>,
) : GeneratedDeclarationKey() {
val isObject = rpcMethod.valueParameterSymbols.isEmpty()

override fun toString(): String {
return "RPCGeneratedRpcMethodClassKey.${rpcMethod.name}"
return "RpcGeneratedRpcMethodClassKey.${rpcMethod.name}"
}
}

internal val FirBasedSymbol<*>.generatedRpcMethodClassKey: RPCGeneratedRpcMethodClassKey? get() =
(origin as? FirDeclarationOrigin.Plugin)?.key as? RPCGeneratedRpcMethodClassKey
internal val FirBasedSymbol<*>.generatedRpcMethodClassKey: RpcGeneratedRpcMethodClassKey? get() =
(origin as? FirDeclarationOrigin.Plugin)?.key as? RpcGeneratedRpcMethodClassKey

internal object FirRpcServiceStubCompanionObject : GeneratedDeclarationKey() {
override fun toString(): String {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,15 @@ class FirRpcServiceGenerator(
*
* - 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],
* of [classSymbol] be set to [RpcGeneratedStubKey],
* 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.
*
* - Inside method classes.
* Method classes will too have their nested declarations.
* We detect them by using [RPCGeneratedRpcMethodClassKey].
* We detect them by using [RpcGeneratedRpcMethodClassKey].
* Nested declarations for these classes are provided by the serialization plugin.
* These declarations can be of two types: serializable object and serializable classes.
* In the case of objects,
Expand Down Expand Up @@ -183,11 +183,11 @@ class FirRpcServiceGenerator(
private fun generateRpcMethodClass(
owner: FirClassSymbol<*>,
name: Name,
rpcServiceStubKey: RPCGeneratedStubKey,
rpcServiceStubKey: RpcGeneratedStubKey,
): FirClassLikeSymbol<*> {
val methodName = name.rpcMethodName
val rpcMethod = rpcServiceStubKey.functions.single { it.name == methodName }
val rpcMethodClassKey = RPCGeneratedRpcMethodClassKey(rpcMethod)
val rpcMethodClassKey = RpcGeneratedRpcMethodClassKey(rpcMethod)
val classKind = if (rpcMethodClassKey.isObject) ClassKind.OBJECT else ClassKind.CLASS

val rpcMethodClass = createNestedClass(
Expand Down Expand Up @@ -261,7 +261,7 @@ class FirRpcServiceGenerator(
.filterIsInstance<FirFunction>()
.map { it.symbol }

return createNestedClass(owner, RpcNames.SERVICE_STUB_NAME, RPCGeneratedStubKey(owner.name, functions)) {
return createNestedClass(owner, RpcNames.SERVICE_STUB_NAME, RpcGeneratedStubKey(owner.name, functions)) {
visibility = Visibilities.Public
modality = Modality.FINAL
}.symbol
Expand Down Expand Up @@ -293,7 +293,7 @@ class FirRpcServiceGenerator(
private fun getCallableNamesForRpcMethodClass(
classSymbol: FirClassSymbol<*>,
context: MemberGenerationContext,
rpcMethodClassKey: RPCGeneratedRpcMethodClassKey,
rpcMethodClassKey: RpcGeneratedRpcMethodClassKey,
): Set<Name> {
return if (rpcMethodClassKey.isObject) {
// add .serializer() method for a serializable object
Expand Down Expand Up @@ -321,7 +321,7 @@ class FirRpcServiceGenerator(
*/
private fun generateConstructorsForRpcMethodClass(
context: MemberGenerationContext,
rpcMethodClassKey: RPCGeneratedRpcMethodClassKey,
rpcMethodClassKey: RpcGeneratedRpcMethodClassKey,
): List<FirConstructorSymbol> {
if (rpcMethodClassKey.isObject) {
return createDefaultPrivateConstructor(context.owner, rpcMethodClassKey).symbol.let(::listOf)
Expand Down Expand Up @@ -366,7 +366,7 @@ class FirRpcServiceGenerator(
private fun generatePropertiesForRpcMethodClass(
callableId: CallableId,
owner: FirClassSymbol<*>,
rpcMethodClassKey: RPCGeneratedRpcMethodClassKey,
rpcMethodClassKey: RpcGeneratedRpcMethodClassKey,
): List<FirPropertySymbol> {
val valueParam = rpcMethodClassKey.rpcMethod.valueParameterSymbols.find {
it.name == callableId.callableName
Expand Down
20 changes: 8 additions & 12 deletions core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,6 @@ public final class kotlinx/rpc/AwaitFieldInitializationKt {
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 {
}

public abstract interface annotation class kotlinx/rpc/RPCEagerField : java/lang/annotation/Annotation {
}

public abstract interface class kotlinx/rpc/RPCServer : kotlinx/coroutines/CoroutineScope {
public abstract fun registerService (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
}

public final class kotlinx/rpc/RegisterFieldKt {
public static final fun registerPlainFlowField (Lkotlinx/rpc/RpcClient;Lkotlinx/coroutines/CoroutineScope;Lkotlinx/rpc/descriptor/RpcServiceDescriptor;Ljava/lang/String;J)Lkotlinx/coroutines/flow/Flow;
public static final fun registerSharedFlowField (Lkotlinx/rpc/RpcClient;Lkotlinx/coroutines/CoroutineScope;Lkotlinx/rpc/descriptor/RpcServiceDescriptor;Ljava/lang/String;J)Lkotlinx/coroutines/flow/SharedFlow;
Expand Down Expand Up @@ -45,7 +35,14 @@ public abstract interface class kotlinx/rpc/RpcClient : kotlinx/coroutines/Corou
public abstract fun provideStubContext (J)Lkotlin/coroutines/CoroutineContext;
}

public final class kotlinx/rpc/UninitializedRPCFieldException : java/lang/Exception {
public abstract interface annotation class kotlinx/rpc/RpcEagerField : java/lang/annotation/Annotation {
}

public abstract interface class kotlinx/rpc/RpcServer : kotlinx/coroutines/CoroutineScope {
public abstract fun registerService (Lkotlin/reflect/KClass;Lkotlin/jvm/functions/Function1;)V
}

public final class kotlinx/rpc/UninitializedRpcFieldException : java/lang/Exception {
public fun <init> (Ljava/lang/String;Lkotlin/reflect/KProperty;)V
public fun getMessage ()Ljava/lang/String;
}
Expand Down Expand Up @@ -87,7 +84,6 @@ public final class kotlinx/rpc/descriptor/RpcParameter {
public abstract interface class kotlinx/rpc/descriptor/RpcServiceDescriptor {
public abstract fun createInstance (JLkotlinx/rpc/RpcClient;)Lkotlinx/rpc/RemoteService;
public abstract fun getCallable (Ljava/lang/String;)Lkotlinx/rpc/descriptor/RpcCallable;
public abstract fun getFields (Lkotlinx/rpc/RemoteService;)Ljava/util/List;
public abstract fun getFqName ()Ljava/lang/String;
}

Expand Down
7 changes: 0 additions & 7 deletions core/src/commonMain/kotlin/kotlinx/rpc/RemoteService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,3 @@ import kotlinx.rpc.annotations.Rpc
* @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
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,7 @@ package kotlinx.rpc
* The field marked with this annotation will be initialized with the service creation.
*/
@Target(AnnotationTarget.PROPERTY)
public annotation class RPCEagerField
public annotation class RpcEagerField

@Deprecated("Use RpcEagerField instead", ReplaceWith("RpcEagerField"), level = DeprecationLevel.ERROR)
public typealias RPCEagerField = RpcEagerField
Loading