From 82a6cba922a64a450d52f3d4e36f6b33fb8932fb Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Wed, 17 Apr 2024 22:17:19 +0200
Subject: [PATCH 01/17] Introduce common IR backend plugin (1/2) (#44)
* [IR] preparation for IR plugin
* Introduce common IR backend plugin (2/2) (#45)
* [IR] replace part of KSP with IR plugin
* review comments
---
...CompilerPlugin.kt => RPCCompilerPlugin.kt} | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 35 +
...CompilerPlugin.kt => RPCCompilerPlugin.kt} | 2 +-
.../rpc/codegen/VersionSpecificApiImpl.kt | 42 +
...CompilerPlugin.kt => RPCCompilerPlugin.kt} | 4 +-
.../rpc/codegen/VersionSpecificApiImpl.kt | 45 +
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 4 +-
.../rpc/codegen/VersionSpecificApiImpl.kt | 44 +
.../kotlinx/rpc/codegen/VersionSpecificApi.kt | 33 +
.../kotlinx/rpc/codegen/extension/IrUtils.kt | 108 ++
.../extension/RPCDeclarationScanner.kt | 78 ++
.../rpc/codegen/extension/RPCIrContext.kt | 219 ++-
.../rpc/codegen/extension/RPCIrExtension.kt | 8 +-
.../extension/RPCIrServiceProcessor.kt | 61 +-
.../rpc/codegen/extension/RPCStubGenerator.kt | 1205 +++++++++++++++++
.../codegen/extension/ServiceDeclaration.kt | 41 +
.../{RPCClientObject.kt => RPCStubObject.kt} | 6 +-
...pcClientObject.kt => WithRPCStubObject.kt} | 0
.../rpc/internal/WithRPCStubObject.js.kt} | 8 +-
...Object.jvm.kt => WithRPCStubObject.jvm.kt} | 2 +-
.../rpc/internal/WithRPCStubObject.native.kt} | 8 +-
.../kotlin/kotlinx/rpc/client/KRPCClient.kt | 22 +-
.../kotlinx/rpc/client/RPCClientUtils.kt | 4 +-
.../rpc/codegen/RPCClientServiceGenerator.kt | 117 +-
.../rpc/codegen/RPCServiceDeclaration.kt | 1 +
.../kotlinx/rpc/codegen/RPCSymbolProcessor.kt | 1 +
26 files changed, 1963 insertions(+), 135 deletions(-)
rename compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/{KRPCCompilerPlugin.kt => RPCCompilerPlugin.kt} (100%)
rename compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/{KRPCCompilerPlugin.kt => RPCCompilerPlugin.kt} (96%)
rename compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/{KRPCCompilerPlugin.kt => RPCCompilerPlugin.kt} (96%)
create mode 100644 compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/IrUtils.kt
create mode 100644 compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
create mode 100644 compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
create mode 100644 compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
rename core/src/commonMain/kotlin/kotlinx/rpc/internal/{RPCClientObject.kt => RPCStubObject.kt} (84%)
rename core/src/commonMain/kotlin/kotlinx/rpc/internal/{WithRpcClientObject.kt => WithRPCStubObject.kt} (100%)
rename core/src/{nativeMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.native.kt => jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt} (75%)
rename core/src/jvmMain/kotlin/kotlinx/rpc/internal/{WithRPCClientObject.jvm.kt => WithRPCStubObject.jvm.kt} (90%)
rename core/src/{jsMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.js.kt => nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt} (75%)
diff --git a/compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/KRPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/KRPCCompilerPlugin.kt
rename to compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
diff --git a/compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
index 367827de..0aa1ffb9 100644
--- a/compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
+++ b/compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -5,7 +5,19 @@
package kotlinx.rpc.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.backend.common.ir.copyTo
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
+import org.jetbrains.kotlin.ir.builders.declarations.addExtensionReceiver
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
+import org.jetbrains.kotlin.ir.declarations.IrFunction
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.js.isJs
@@ -14,8 +26,31 @@ object VersionSpecificApiImpl : VersionSpecificApi {
override fun isJs(platform: TargetPlatform?): Boolean {
return platform.isJs()
}
+ override var IrFieldBuilder.modalityVS: Modality
+ get() = undefinedAPI()
+ set(_) {}
+
+ override var IrCall.originVS: IrStatementOrigin?
+ get() = origin
+ set(_) {}
override fun referenceClass(context: IrPluginContext, packageName: String, name: String): IrClassSymbol? {
return context.referenceClass(FqName("$packageName.$name"))
}
+
+ override fun referenceFunctions(
+ context: IrPluginContext,
+ packageName: String,
+ name: String
+ ): Collection {
+ return context.referenceFunctions(FqName("$packageName.$name"))
+ }
+
+ override fun IrValueParameter.copyToVS(irFunction: IrFunction, origin: IrDeclarationOrigin): IrValueParameter {
+ return copyTo(irFunction, origin)
+ }
+
+ override fun IrSimpleFunction.addExtensionReceiverVS(type: IrType, origin: IrDeclarationOrigin): IrValueParameter {
+ return addExtensionReceiver(type, origin)
+ }
}
diff --git a/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/KRPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 96%
rename from compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/KRPCCompilerPlugin.kt
rename to compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index 3c5dcae9..55e1830b 100644
--- a/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/KRPCCompilerPlugin.kt
+++ b/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -22,7 +22,7 @@ class RPCCompilerPlugin : ComponentRegistrar {
VersionSpecificApi.INSTANCE = VersionSpecificApiImpl
}
- override val supportsK2: Boolean = false
+ override val supportsK2: Boolean = true
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
val extension = RPCCompilerPluginCore.provideExtension(configuration)
diff --git a/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
index c44ba19a..5373cc6f 100644
--- a/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
+++ b/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -5,9 +5,23 @@
package kotlinx.rpc.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.backend.common.ir.addExtensionReceiver
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
+import org.jetbrains.kotlin.ir.declarations.IrFunction
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.types.IrType
+import org.jetbrains.kotlin.ir.util.copyTo
+import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.js.isJs
@@ -15,6 +29,13 @@ object VersionSpecificApiImpl : VersionSpecificApi {
override fun isJs(platform: TargetPlatform?): Boolean {
return platform.isJs()
}
+ override var IrFieldBuilder.modalityVS: Modality
+ get() = undefinedAPI()
+ set(_) {}
+
+ override var IrCall.originVS: IrStatementOrigin?
+ get() = origin
+ set(_) {}
override fun referenceClass(context: IrPluginContext, packageName: String, name: String): IrClassSymbol? {
return context.referenceClass(
@@ -25,4 +46,25 @@ object VersionSpecificApiImpl : VersionSpecificApi {
)
)
}
+
+ override fun referenceFunctions(
+ context: IrPluginContext,
+ packageName: String,
+ name: String
+ ): Collection {
+ return context.referenceFunctions(
+ CallableId(
+ FqName(packageName),
+ Name.identifier(name),
+ )
+ )
+ }
+
+ override fun IrValueParameter.copyToVS(irFunction: IrFunction, origin: IrDeclarationOrigin): IrValueParameter {
+ return copyTo(irFunction, origin)
+ }
+
+ override fun IrSimpleFunction.addExtensionReceiverVS(type: IrType, origin: IrDeclarationOrigin): IrValueParameter {
+ return addExtensionReceiver(type, origin)
+ }
}
diff --git a/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/KRPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 96%
rename from compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/KRPCCompilerPlugin.kt
rename to compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index c4fe1b34..5910422c 100644
--- a/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/KRPCCompilerPlugin.kt
+++ b/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -24,11 +24,11 @@ class RPCCompilerPlugin : CompilerPluginRegistrar() {
VersionSpecificApi.INSTANCE = VersionSpecificApiImpl
}
- override val supportsK2: Boolean = false
+ override val supportsK2: Boolean = true
override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
val extension = RPCCompilerPluginCore.provideExtension(configuration)
IrGenerationExtension.registerExtension(extension)
}
-}
+}
\ No newline at end of file
diff --git a/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
index c44ba19a..0ec5b4fa 100644
--- a/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
+++ b/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -5,9 +5,23 @@
package kotlinx.rpc.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.backend.common.ir.addExtensionReceiver
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
+import org.jetbrains.kotlin.ir.declarations.IrFunction
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.types.IrType
+import org.jetbrains.kotlin.ir.util.copyTo
+import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.js.isJs
@@ -15,6 +29,13 @@ object VersionSpecificApiImpl : VersionSpecificApi {
override fun isJs(platform: TargetPlatform?): Boolean {
return platform.isJs()
}
+ override var IrFieldBuilder.modalityVS: Modality
+ get() = undefinedAPI()
+ set(_) {}
+
+ override var IrCall.originVS: IrStatementOrigin?
+ get() = origin
+ set(_) {}
override fun referenceClass(context: IrPluginContext, packageName: String, name: String): IrClassSymbol? {
return context.referenceClass(
@@ -25,4 +46,28 @@ object VersionSpecificApiImpl : VersionSpecificApi {
)
)
}
+
+ override fun referenceFunctions(
+ context: IrPluginContext,
+ packageName: String,
+ name: String
+ ): Collection {
+ return context.referenceFunctions(
+ CallableId(
+ FqName(packageName),
+ Name.identifier(name),
+ )
+ )
+ }
+
+ override fun IrValueParameter.copyToVS(
+ irFunction: IrFunction,
+ origin: IrDeclarationOrigin,
+ ): IrValueParameter {
+ return copyTo(irFunction)
+ }
+
+ override fun IrSimpleFunction.addExtensionReceiverVS(type: IrType, origin: IrDeclarationOrigin): IrValueParameter {
+ return addExtensionReceiver(type, origin)
+ }
}
diff --git a/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index c4fe1b34..1fe7c5d0 100644
--- a/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
+++ b/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.config.CompilerConfiguration
@OptIn(ExperimentalCompilerApi::class)
class RPCCommandLineProcessor : CommandLineProcessor {
- override val pluginId = "kotlinx.rpc.compiler-plugin"
+ override val pluginId = "kotlinx.rpc.codegen"
override val pluginOptions = emptyList()
}
@@ -24,7 +24,7 @@ class RPCCompilerPlugin : CompilerPluginRegistrar() {
VersionSpecificApi.INSTANCE = VersionSpecificApiImpl
}
- override val supportsK2: Boolean = false
+ override val supportsK2: Boolean = true
override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
val extension = RPCCompilerPluginCore.provideExtension(configuration)
diff --git a/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
index c7006b9a..7898e1f0 100644
--- a/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
+++ b/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -5,9 +5,24 @@
package kotlinx.rpc.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.backend.common.ir.addExtensionReceiver
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
+import org.jetbrains.kotlin.ir.declarations.IrFunction
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.types.IrType
+import org.jetbrains.kotlin.ir.types.impl.IrErrorClassImpl.modality
+import org.jetbrains.kotlin.ir.util.copyTo
+import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.isJs
@@ -16,6 +31,14 @@ object VersionSpecificApiImpl : VersionSpecificApi {
return platform.isJs()
}
+ override var IrFieldBuilder.modalityVS: Modality
+ get() = modality
+ set(value) { modality = value }
+
+ override var IrCall.originVS: IrStatementOrigin?
+ get() = origin
+ set(value) { origin = value }
+
override fun referenceClass(context: IrPluginContext, packageName: String, name: String): IrClassSymbol? {
return context.referenceClass(
ClassId(
@@ -25,4 +48,25 @@ object VersionSpecificApiImpl : VersionSpecificApi {
)
)
}
+
+ override fun referenceFunctions(
+ context: IrPluginContext,
+ packageName: String,
+ name: String
+ ): Collection {
+ return context.referenceFunctions(
+ CallableId(
+ FqName(packageName),
+ Name.identifier(name),
+ )
+ )
+ }
+
+ override fun IrValueParameter.copyToVS(irFunction: IrFunction, origin: IrDeclarationOrigin): IrValueParameter {
+ return copyTo(irFunction, origin)
+ }
+
+ override fun IrSimpleFunction.addExtensionReceiverVS(type: IrType, origin: IrDeclarationOrigin): IrValueParameter {
+ return addExtensionReceiver(type, origin)
+ }
}
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApi.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApi.kt
index 2f374ad2..2d105c97 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApi.kt
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApi.kt
@@ -5,7 +5,17 @@
package kotlinx.rpc.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
+import org.jetbrains.kotlin.ir.declarations.IrFunction
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.platform.TargetPlatform
interface VersionSpecificApi {
@@ -13,7 +23,30 @@ interface VersionSpecificApi {
fun referenceClass(context: IrPluginContext, packageName: String, name: String): IrClassSymbol?
+ fun referenceFunctions(
+ context: IrPluginContext,
+ packageName: String,
+ name: String,
+ ): Collection
+
+ fun IrValueParameter.copyToVS(
+ irFunction: IrFunction,
+ origin: IrDeclarationOrigin = this.origin,
+ ): IrValueParameter
+
+ fun IrSimpleFunction.addExtensionReceiverVS(
+ type: IrType,
+ origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED,
+ ): IrValueParameter
+
+ var IrFieldBuilder.modalityVS: Modality
+
+ var IrCall.originVS: IrStatementOrigin?
+
companion object {
lateinit var INSTANCE: VersionSpecificApi
}
}
+
+@Suppress("unused")
+fun undefinedAPI(): Nothing = error("This API is not defined in current Kotlin version")
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/IrUtils.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/IrUtils.kt
new file mode 100644
index 00000000..bd777f55
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/IrUtils.kt
@@ -0,0 +1,108 @@
+/*
+ * 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.extension
+
+import org.jetbrains.kotlin.ir.IrBuiltIns
+import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
+import org.jetbrains.kotlin.ir.builders.declarations.addDefaultGetter
+import org.jetbrains.kotlin.ir.builders.declarations.buildField
+import org.jetbrains.kotlin.ir.declarations.*
+import org.jetbrains.kotlin.ir.expressions.IrExpression
+import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
+import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
+import org.jetbrains.kotlin.ir.types.IrType
+import org.jetbrains.kotlin.ir.types.IrTypeArgument
+import org.jetbrains.kotlin.ir.types.IrTypeProjection
+import org.jetbrains.kotlin.ir.types.SimpleTypeNullability
+import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
+import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
+import org.jetbrains.kotlin.ir.util.dump
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.types.Variance
+import java.util.*
+
+fun String.capitalized(): String {
+ return replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }
+}
+
+fun IrClassifierSymbol.typeWith(type: IrType, variance: Variance): IrType {
+ return IrSimpleTypeImpl(
+ classifier = this,
+ nullability = SimpleTypeNullability.NOT_SPECIFIED,
+ arguments = listOf(makeTypeProjection(type, variance)),
+ annotations = emptyList(),
+ )
+}
+
+val IrProperty.getterOrFail: IrSimpleFunction get () {
+ return getter ?: error("'getter' should be present, but was null: ${dump()}")
+}
+
+fun IrProperty.addDefaultGetter(
+ parentClass: IrClass,
+ builtIns: IrBuiltIns,
+ configure: IrSimpleFunction.() -> Unit = {},
+) {
+ addDefaultGetter(parentClass, builtIns)
+
+ getterOrFail.apply {
+ dispatchReceiverParameter!!.origin = IrDeclarationOrigin.DEFINED
+
+ configure()
+ }
+}
+
+// A collection of functions that proved to be useful,
+// but appeared only in the latest Kotlin versions.
+// Copied and placed here as is
+
+val IrTypeArgument.typeOrFail: IrType
+ get() {
+ require(this is IrTypeProjection) {
+ "Type argument should be of type `IrTypeProjection`, but was `${this::class}` instead"
+ }
+
+ return this.type
+ }
+
+// originally named 'addBackingField'
+inline fun IrProperty.addBackingFieldUtil(builder: IrFieldBuilder.() -> Unit = {}): IrField {
+ return factory.buildField {
+ name = this@addBackingFieldUtil.name
+ origin = IrDeclarationOrigin.PROPERTY_BACKING_FIELD
+ builder()
+ }.also { field ->
+ this@addBackingFieldUtil.backingField = field
+ field.correspondingPropertySymbol = this@addBackingFieldUtil.symbol
+ field.parent = this@addBackingFieldUtil.parent
+ }
+}
+
+// originally appeared as 'NameUtils.propertyDelegateName'
+fun propertyDelegateName(propertyName: Name): Name {
+ return Name.identifier("${propertyName.asString()}\$delegate")
+}
+
+inline fun Collection.memoryOptimizedMap(transform: (T) -> R): List {
+ return mapTo(ArrayList(size), transform).compactIfPossible()
+}
+
+
+inline fun Collection.memoryOptimizedMapIndexed(transform: (index: Int, T) -> R): List {
+ return mapIndexedTo(ArrayList(size), transform).compactIfPossible()
+}
+
+fun List.compactIfPossible(): List =
+ when (size) {
+ 0 -> emptyList()
+ 1 -> listOf(first())
+ else -> apply {
+ if (this is ArrayList<*>) trimToSize()
+ }
+ }
+
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER") // TODO(KTIJ-26314): Remove this suppression
+fun IrFactory.createExpressionBody(expression: IrExpression): IrExpressionBody =
+ createExpressionBody(expression.startOffset, expression.endOffset, expression)
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
new file mode 100644
index 00000000..c58a5db4
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
@@ -0,0 +1,78 @@
+/*
+ * 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.extension
+
+import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrDeclaration
+import org.jetbrains.kotlin.ir.declarations.IrProperty
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.types.classOrNull
+import org.jetbrains.kotlin.ir.util.dumpKotlinLike
+import org.jetbrains.kotlin.ir.util.packageFqName
+
+/**
+ * This class scans user declared RPC service
+ * 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): ServiceDeclaration {
+ val declarations = service.declarations.memoryOptimizedMap { declaration ->
+ when (declaration) {
+ is IrSimpleFunction -> {
+ if (declaration.isFakeOverride) {
+ return@memoryOptimizedMap null
+ }
+
+ ServiceDeclaration.Method(
+ function = declaration,
+ argumentTypes = declaration.valueParameters.memoryOptimizedMap { param ->
+ ServiceDeclaration.Method.Argument(param, param.type)
+ },
+ )
+ }
+
+ is IrProperty -> {
+ if (declaration.isFakeOverride) {
+ return@memoryOptimizedMap null
+ }
+
+ val symbol = declaration.getter!!.returnType.classOrNull
+
+ val flowType = when (symbol) {
+ ctx.flow -> ServiceDeclaration.FlowField.Kind.Plain
+ ctx.sharedFlow -> ServiceDeclaration.FlowField.Kind.Shared
+ ctx.stateFlow -> ServiceDeclaration.FlowField.Kind.State
+ else -> unsupportedDeclaration(service, declaration)
+ }
+
+ ServiceDeclaration.FlowField(declaration, flowType)
+ }
+
+ else -> {
+ unsupportedDeclaration(service, declaration)
+ }
+ }
+ }
+
+ val stubClass = ctx.getIrClassSymbol(
+ packageName = service.packageFqName!!.asString(),
+ name = "${service.name.asString()}$STUB_SUFFIX",
+ )
+
+ return ServiceDeclaration(
+ service = service,
+ stubClass = stubClass.owner,
+ methods = declarations.filterIsInstance(),
+ fields = declarations.filterIsInstance(),
+ )
+ }
+}
+
+private fun unsupportedDeclaration(service: IrClass, declaration: IrDeclaration): Nothing {
+ error("Unsupported declaration in RPC interface ${service.name}: ${declaration.dumpKotlinLike()}")
+}
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt
index a7072398..85e29f92 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt
@@ -6,35 +6,230 @@ package kotlinx.rpc.codegen.extension
import kotlinx.rpc.codegen.VersionSpecificApi
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
-import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
+import org.jetbrains.kotlin.ir.declarations.IrProperty
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
-import org.jetbrains.kotlin.ir.util.kotlinFqName
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.types.classOrNull
+import org.jetbrains.kotlin.ir.types.makeNullable
+import org.jetbrains.kotlin.ir.util.functions
+import org.jetbrains.kotlin.ir.util.isVararg
+import org.jetbrains.kotlin.ir.util.properties
+import org.jetbrains.kotlin.platform.konan.isNative
internal class RPCIrContext(
- private val pluginContext: IrPluginContext,
- private val versionSpecificApi: VersionSpecificApi,
+ val pluginContext: IrPluginContext,
+ val versionSpecificApi: VersionSpecificApi,
) {
val irBuiltIns = pluginContext.irBuiltIns
- fun generatedClientCompanionObject(serviceDeclaration: IrClass): IrClassSymbol {
- val name = serviceDeclaration.kotlinFqName.shortName()
- return getRpcIrClassSymbol("${name}Client.Companion")
+ val anyNullable by lazy {
+ irBuiltIns.anyType.makeNullable()
}
val optInAnnotation by lazy {
getIrClassSymbol("kotlin", "OptIn")
}
+ val extensionFunctionType by lazy {
+ getIrClassSymbol("kotlin", "ExtensionFunctionType")
+ }
+
+ val coroutineScope by lazy {
+ getIrClassSymbol("kotlinx.coroutines", "CoroutineScope")
+ }
+
+ val coroutineContext by lazy {
+ getIrClassSymbol("kotlin.coroutines", "CoroutineContext")
+ }
+
+ val completableJob by lazy {
+ getIrClassSymbol("kotlinx.coroutines", "CompletableJob")
+ }
+
+ val kTypeClass by lazy {
+ getIrClassSymbol("kotlin.reflect", "KType")
+ }
+
+ val lazy by lazy {
+ getIrClassSymbol("kotlin", "Lazy")
+ }
+
+ val function0 by lazy {
+ getIrClassSymbol("kotlin", "Function0")
+ }
+
+ val suspendFunction1 by lazy {
+ getIrClassSymbol("kotlin.coroutines", "SuspendFunction1")
+ }
+
+ val flow by lazy {
+ getIrClassSymbol("kotlinx.coroutines.flow", "Flow")
+ }
+
+ val sharedFlow by lazy {
+ getIrClassSymbol("kotlinx.coroutines.flow", "SharedFlow")
+ }
+
+ val stateFlow by lazy {
+ getIrClassSymbol("kotlinx.coroutines.flow", "StateFlow")
+ }
+
+ val kProperty1 by lazy {
+ getIrClassSymbol("kotlin.reflect", "KProperty1")
+ }
+
+ val pair by lazy {
+ getIrClassSymbol("kotlin", "Pair")
+ }
+
val rpc by lazy {
getRpcIrClassSymbol("RPC")
}
- val withRPCClientObjectAnnotation by lazy {
- getRpcIrClassSymbol("WithRPCClientObject", "internal")
+ val rpcClient by lazy {
+ getRpcIrClassSymbol("RPCClient")
+ }
+
+ val rpcCall by lazy {
+ getRpcIrClassSymbol("RPCCall")
+ }
+
+ val rpcCallType by lazy {
+ getRpcIrClassSymbol("RPCCall.Type")
+ }
+
+ val rpcCallTypeMethod by lazy {
+ rpcCallType.owner.declarations.filterIsInstance().single {
+ it.name.asString() == "Method"
+ }.symbol
+ }
+
+ val rpcField by lazy {
+ getRpcIrClassSymbol("RPCField")
}
- val internalRPCApiAnnotation by lazy {
- getRpcIrClassSymbol("InternalRPCApi", "internal")
+ val withRPCStubObjectAnnotation by lazy {
+ getRpcIrClassSymbol("WithRPCStubObject", "internal")
+ }
+
+ val rpcEagerFieldAnnotation by lazy {
+ getRpcIrClassSymbol("RPCEagerField")
+ }
+
+ val rpcStubObject by lazy {
+ getRpcIrClassSymbol("RPCStubObject", "internal")
+ }
+
+ val rpcDeferredField by lazy {
+ getRpcIrClassSymbol("RPCDeferredField", "internal")
+ }
+
+ fun isJsTarget(): Boolean {
+ return versionSpecificApi.isJs(pluginContext.platform)
+ }
+
+ fun isNativeTarget(): Boolean {
+ return pluginContext.platform.isNative()
+ }
+
+ val functions = Functions()
+
+ inner class Functions {
+ val registerPlainFlowField by lazy {
+ rpcClient.namedFunction("registerPlainFlowField")
+ }
+
+ val registerSharedFlowField by lazy {
+ rpcClient.namedFunction("registerSharedFlowField")
+ }
+
+ val registerStateFlowField by lazy {
+ rpcClient.namedFunction("registerStateFlowField")
+ }
+
+ val rpcClientCall by lazy {
+ rpcClient.namedFunction("call")
+ }
+
+ val typeOf by lazy {
+ namedFunction("kotlin.reflect", "typeOf")
+ }
+
+ val lazy by lazy {
+ namedFunction("kotlin", "lazy") {
+ it.owner.valueParameters.size == 1
+ }
+ }
+
+ val lazyGetValue by lazy {
+ namedFunction("kotlin", "getValue") {
+ it.owner.extensionReceiverParameter?.type?.classOrNull == this@RPCIrContext.lazy
+ }
+ }
+
+ val listOf by lazy {
+ namedFunction("kotlin.collections", "listOf") {
+ it.owner.valueParameters.singleOrNull()?.isVararg ?: false
+ }
+ }
+
+ val emptyList by lazy {
+ namedFunction("kotlin.collections", "emptyList")
+ }
+
+ val mapOf by lazy {
+ namedFunction("kotlin.collections", "mapOf") {
+ it.owner.valueParameters.singleOrNull()?.isVararg ?: false
+ }
+ }
+
+ val mapGet by lazy {
+ irBuiltIns.mapClass.namedFunction("get")
+ }
+
+ val emptyMap by lazy {
+ namedFunction("kotlin.collections", "emptyMap")
+ }
+
+ val to by lazy {
+ namedFunction("kotlin", "to")
+ }
+
+ val withContext by lazy {
+ namedFunction("kotlinx.coroutines", "withContext")
+ }
+
+ val job by lazy {
+ namedFunction("kotlinx.coroutines", "Job")
+ }
+
+ private fun IrClassSymbol.namedFunction(name: String): IrSimpleFunction {
+ return owner.functions.single { it.name.asString() == name }
+ }
+
+ private fun namedFunction(
+ packageName: String,
+ name: String,
+ filterOverloads: ((IrSimpleFunctionSymbol) -> Boolean)? = null
+ ): IrSimpleFunctionSymbol {
+ val found = versionSpecificApi.referenceFunctions(pluginContext, packageName, name)
+
+ return if (filterOverloads == null) found.first() else found.first(filterOverloads)
+ }
+ }
+
+ val properties = Properties()
+
+ inner class Properties {
+ val rpcClientCoroutineContext by lazy {
+ rpcClient.namedProperty("coroutineContext")
+ }
+
+ private fun IrClassSymbol.namedProperty(name: String): IrProperty {
+ return owner.properties.single { it.name.asString() == name }
+ }
}
private fun getRpcIrClassSymbol(name: String, subpackage: String? = null): IrClassSymbol {
@@ -42,7 +237,7 @@ internal class RPCIrContext(
return getIrClassSymbol("kotlinx.rpc$suffix", name)
}
- private fun getIrClassSymbol(packageName: String, name: String): IrClassSymbol {
+ fun getIrClassSymbol(packageName: String, name: String): IrClassSymbol {
return versionSpecificApi.referenceClass(pluginContext, packageName, name)
?: error("Unable to find symbol. Package: $packageName, name: $name")
}
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrExtension.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
index a27c4636..a2235cf6 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
-import org.jetbrains.kotlin.platform.konan.isNative
internal class RPCIrExtension(
private val logger: MessageCollector,
@@ -19,10 +18,9 @@ internal class RPCIrExtension(
moduleFragment: IrModuleFragment,
pluginContext: IrPluginContext,
) {
- if (versionSpecificApi.isJs(pluginContext.platform) || pluginContext.platform.isNative()) {
- val context = RPCIrContext(pluginContext, versionSpecificApi)
+ val context = RPCIrContext(pluginContext, versionSpecificApi)
- moduleFragment.transform(RPCIrServiceProcessor(logger), context)
- }
+ val processor = RPCIrServiceProcessor(logger)
+ moduleFragment.transform(processor, context)
}
}
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
index 7c1088b0..899644a7 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
@@ -7,11 +7,8 @@ package kotlinx.rpc.codegen.extension
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.expressions.impl.IrClassReferenceImpl
-import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.types.classFqName
import org.jetbrains.kotlin.ir.types.typeWith
-import org.jetbrains.kotlin.ir.util.constructors
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -19,65 +16,23 @@ internal class RPCIrServiceProcessor(
@Suppress("unused")
private val logger: MessageCollector,
) : IrElementTransformer {
- override fun visitClass(declaration: IrClass, data: RPCIrContext): IrStatement {
+ @Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
+ override fun visitClass(declaration: IrClass, context: RPCIrContext): IrStatement {
if (declaration.isInterface &&
// data.rpc is resolved lazily, so first check is rather heuristic
declaration.maybeRPC() &&
- declaration.superTypes.contains(data.rpc.typeWith())
+ declaration.superTypes.contains(context.rpc.typeWith())
) {
- addAssociatedObjectAnnotation(declaration, data)
+ processService(declaration, context)
}
- return super.visitClass(declaration, data)
+ return super.visitClass(declaration, context)
}
private fun IrClass.maybeRPC() = superTypes.any { it.classFqName?.asString()?.contains("RPC") == true }
- private fun addAssociatedObjectAnnotation(declaration: IrClass, data: RPCIrContext) {
- declaration.annotations += IrConstructorCallImpl(
- startOffset = declaration.startOffset,
- endOffset = declaration.endOffset,
- type = data.optInAnnotation.typeWith(),
- symbol = data.optInAnnotation.constructors.single(),
- typeArgumentsCount = 0,
- constructorTypeArgumentsCount = 0,
- valueArgumentsCount = 1,
- ).apply {
- val internalRPCApiClassReferenceType = data.internalRPCApiAnnotation.typeWith()
-
- putValueArgument(
- index = 0,
- valueArgument = IrClassReferenceImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- type = data.irBuiltIns.kClassClass.typeWith(internalRPCApiClassReferenceType),
- symbol = data.internalRPCApiAnnotation,
- classType = internalRPCApiClassReferenceType
- )
- )
- }
-
- declaration.annotations += IrConstructorCallImpl(
- startOffset = declaration.startOffset,
- endOffset = declaration.endOffset,
- type = data.withRPCClientObjectAnnotation.typeWith(),
- symbol = data.withRPCClientObjectAnnotation.constructors.single(),
- typeArgumentsCount = 0,
- constructorTypeArgumentsCount = 0,
- valueArgumentsCount = 1,
- ).apply {
- val companionObject = data.generatedClientCompanionObject(declaration)
- val companionObjectType = data.generatedClientCompanionObject(declaration).typeWith()
- putValueArgument(
- index = 0,
- valueArgument = IrClassReferenceImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- type = data.irBuiltIns.kClassClass.typeWith(companionObjectType),
- symbol = companionObject,
- classType = companionObjectType,
- )
- )
- }
+ private fun processService(service: IrClass, context: RPCIrContext) {
+ val declaration = RPCDeclarationScanner.scanServiceDeclaration(service, context)
+ RPCStubGenerator(declaration, context).generate()
}
}
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
new file mode 100644
index 00000000..1d76ba0d
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
@@ -0,0 +1,1205 @@
+/*
+ * 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.extension
+
+import kotlinx.rpc.codegen.VersionSpecificApi
+import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
+import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
+import org.jetbrains.kotlin.backend.jvm.functionByName
+import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
+import org.jetbrains.kotlin.ir.builders.*
+import org.jetbrains.kotlin.ir.builders.declarations.*
+import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
+import org.jetbrains.kotlin.ir.declarations.IrProperty
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrExpression
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
+import org.jetbrains.kotlin.ir.expressions.impl.*
+import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrSymbol
+import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
+import org.jetbrains.kotlin.ir.types.*
+import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
+import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
+import org.jetbrains.kotlin.ir.util.*
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.name.SpecialNames
+import org.jetbrains.kotlin.types.Variance
+import org.jetbrains.kotlin.util.OperatorNameConventions
+import kotlin.properties.Delegates
+
+const val STUB_SUFFIX = "Stub"
+private const val CLIENT_PROPERTY = "client"
+private const val METHOD_CLASS_SUFFIX_PROPERTY = "RPCData"
+private const val METHOD_NAMES_PROPERTY = "methodNames"
+private const val METHOD_TYPE_OF_FUNCTION = "methodTypeOf"
+private const val WITH_CLIENT_METHOD = "withClient"
+private const val RPC_FIELDS_METHOD = "rpcFields"
+
+@Suppress("detekt.LargeClass", "detekt.TooManyFunctions")
+internal class RPCStubGenerator(
+ private val declaration: ServiceDeclaration,
+ private val ctx: RPCIrContext,
+) {
+ private fun irBuilder(symbol: IrSymbol): DeclarationIrBuilder =
+ DeclarationIrBuilder(ctx.pluginContext, symbol, symbol.owner.startOffset, symbol.owner.endOffset)
+
+ private var stubClass: IrClass by Delegates.notNull()
+ private var stubClassThisReceiver: IrValueParameter by Delegates.notNull()
+
+ fun generate() {
+ generateStubClass()
+
+ addAssociatedObjectAnnotationIfPossible()
+ }
+
+ private fun generateStubClass() {
+ declaration.stubClass.apply {
+ declarations.removeAll { it !is IrClass } // preserve the companion object and method classes
+ annotations = emptyList()
+
+ stubClass = this
+ stubClassThisReceiver = thisReceiver
+ ?: error("Declared stub class must have thisReceiver: ${stubClass.name.asString()}")
+
+ superTypes = listOf(declaration.serviceType)
+
+ generateStubConstructor()
+ generateStubContent()
+ }
+ }
+
+ private var clientValueParameter: IrValueParameter by Delegates.notNull()
+
+ /**
+ * Constructor of a stub service:
+ *
+ * ```kotlin
+ * class MyServiceStub(private val client: RPCClient) : MyService
+ * ```
+ */
+ private fun IrClass.generateStubConstructor() {
+ addConstructor {
+ name = this@generateStubConstructor.name
+ isPrimary = true
+ }.apply {
+ clientValueParameter = addValueParameter {
+ name = Name.identifier(CLIENT_PROPERTY)
+ type = ctx.rpcClient.defaultType
+ }
+
+ // default constructor implementation
+ body = irBuilder(symbol).irBlockBody {
+ +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
+ +IrInstanceInitializerCallImpl(
+ startOffset = startOffset,
+ endOffset = endOffset,
+ classSymbol = this@generateStubConstructor.symbol,
+ type = context.irBuiltIns.unitType,
+ )
+ }
+ }
+ }
+
+ private fun IrClass.generateStubContent() {
+ generateProperties()
+
+ generateMethods()
+
+ generateCompanionObject()
+
+ addAnyOverrides(declaration.service)
+ }
+
+ private fun IrClass.generateProperties() {
+ clientProperty()
+
+ coroutineContextProperty()
+
+ declaration.fields.forEach {
+ rpcFlowField(it)
+ }
+ }
+
+ private var clientProperty: IrProperty by Delegates.notNull()
+
+ /**
+ * Client property from the constructor
+ *
+ * ```kotlin
+ * class MyServiceStub(private val client: RPCClient) : MyService
+ * ```
+ */
+ private fun IrClass.clientProperty() {
+ clientProperty = addProperty {
+ name = Name.identifier(CLIENT_PROPERTY)
+ visibility = DescriptorVisibilities.PRIVATE
+ }.apply {
+ addBackingFieldUtil {
+ visibility = DescriptorVisibilities.PRIVATE
+ type = ctx.rpcClient.defaultType
+ isFinal = true
+ }.apply {
+ initializer = factory.createExpressionBody(
+ IrGetValueImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = clientValueParameter.type,
+ symbol = clientValueParameter.symbol,
+ origin = IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER,
+ )
+ )
+ }
+
+ addDefaultGetter(this@clientProperty, ctx.irBuiltIns) {
+ visibility = DescriptorVisibilities.PRIVATE
+ }
+ }
+ }
+
+ private var coroutineContextProperty: IrProperty by Delegates.notNull()
+
+ /**
+ * `coroutineContext` property from `RPC` interface
+ *
+ * ```kotlin
+ * final override val coroutineContext: CoroutineContext = client.coroutineContext + Job()
+ * ```
+ */
+ private fun IrClass.coroutineContextProperty() {
+ coroutineContextProperty = addProperty {
+ name = Name.identifier("coroutineContext")
+ visibility = DescriptorVisibilities.PUBLIC
+ modality = Modality.FINAL
+ }.apply {
+ overriddenSymbols = listOf(ctx.properties.rpcClientCoroutineContext.symbol)
+
+ addBackingFieldUtil {
+ visibility = DescriptorVisibilities.PRIVATE
+ type = ctx.coroutineContext.defaultType
+ isFinal = true
+ }.apply {
+ val coroutineContextClass = ctx.coroutineContext.owner
+ val plusFunction = coroutineContextClass.getSimpleFunction(OperatorNameConventions.PLUS.identifier)
+ ?: error("Expected to find 'plus' function in 'kotlin.coroutines.CoroutineContext'")
+
+ initializer = factory.createExpressionBody(
+ IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = coroutineContextClass.typeWith(),
+ symbol = plusFunction,
+ origin = IrStatementOrigin.PLUS,
+ valueArgumentsCount = 1,
+ typeArgumentsCount = 0,
+ ).apply {
+ val contextGetter = ctx.properties.rpcClientCoroutineContext.getter
+ ?: error("Expected getter for 'coroutineContext' property in RPCClient")
+
+ dispatchReceiver = IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = coroutineContextClass.typeWith(),
+ symbol = contextGetter.symbol,
+ origin = IrStatementOrigin.GET_PROPERTY,
+ valueArgumentsCount = contextGetter.valueParameters.size,
+ typeArgumentsCount = contextGetter.typeParameters.size,
+ ).apply {
+ dispatchReceiver = irCallProperty(stubClass, clientProperty)
+ }
+
+ val job = IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.completableJob.defaultType,
+ symbol = ctx.functions.job,
+ valueArgumentsCount = 1,
+ typeArgumentsCount = 0,
+ ).apply {
+ putValueArgument(0, null)
+ }
+
+ putValueArgument(0, job)
+ }
+ )
+ }
+
+ addDefaultGetter(this@coroutineContextProperty, ctx.irBuiltIns) {
+ val serviceCoroutineContext = declaration.service.getPropertyGetter("coroutineContext")
+ ?: error(
+ "RPC services expected to have \"coroutineContext\" property with getter: " +
+ declaration.service.dump()
+ )
+
+ overriddenSymbols = listOf(serviceCoroutineContext)
+ }
+ }
+ }
+
+ /**
+ * RPC fields.
+ * Can be of two kinds: Lazy and Eager (defined by `@RPCEagerField` annotation)
+ *
+ * Lazy:
+ * ``` kotlin
+ * final override val : by lazy {
+ * client.registerFlowField(
+ * RPCField("", "", typeOf<>())
+ * )
+ * }
+ * ```
+ *
+ *
+ * Eager:
+ * ```kotlin
+ * final override val : =
+ * client.registerFlowField(
+ * RPCField("", "", typeOf<>())
+ * )
+ * ```
+ *
+ * Where:
+ * - `` - the name of the RPC field
+ * - `` - actual type of the field. Can be either Flot, SharedFlow or StateFlow
+ * - `` - [ServiceDeclaration.FlowField.Kind]
+ * - `` - FQ name of the RPC service
+ */
+ @Suppress("detekt.NestedBlockDepth", "detekt.LongMethod", "detekt.CyclomaticComplexMethod")
+ private fun IrClass.rpcFlowField(field: ServiceDeclaration.FlowField) {
+ val isLazy = !field.property.hasAnnotation(ctx.rpcEagerFieldAnnotation)
+
+ val servicePropertyGetter = field.property.getter
+ ?: error("RPC field declared in service interface expected to have getters: ${field.property.dump()}")
+
+ addProperty {
+ name = field.property.name
+ visibility = field.property.visibility
+ modality = Modality.FINAL
+ isDelegated = isLazy
+ }.apply {
+ val fieldProperty = this
+
+ overriddenSymbols = listOf(field.property.symbol)
+
+ val fieldType = servicePropertyGetter.returnType
+
+ val fieldTypeParameter = (fieldType as IrSimpleType).arguments.single()
+
+ val registerFunction = when (field.flowKind) {
+ ServiceDeclaration.FlowField.Kind.Plain -> ctx.functions.registerPlainFlowField
+ ServiceDeclaration.FlowField.Kind.Shared -> ctx.functions.registerSharedFlowField
+ ServiceDeclaration.FlowField.Kind.State -> ctx.functions.registerStateFlowField
+ }.symbol
+
+ val registerCall = IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = fieldType,
+ symbol = registerFunction,
+ typeArgumentsCount = 1,
+ valueArgumentsCount = 1,
+ ).apply {
+ dispatchReceiver = irCallProperty(stubClass, clientProperty)
+ putTypeArgument(0, fieldTypeParameter.typeOrFail)
+
+ val fieldArgument = IrConstructorCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.rpcField.defaultType,
+ symbol = ctx.rpcField.constructors.single(),
+ typeArgumentsCount = 0,
+ constructorTypeArgumentsCount = 0,
+ valueArgumentsCount = 3,
+ ).apply {
+ putValueArgument(0, stringConst(declaration.service.kotlinFqName.asString()))
+ putValueArgument(1, stringConst(field.property.name.asString()))
+
+ val typeOfCall = IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.kTypeClass.defaultType,
+ symbol = ctx.functions.typeOf,
+ typeArgumentsCount = 1,
+ valueArgumentsCount = 0,
+ ).apply {
+ putTypeArgument(0, fieldType)
+ }
+
+ putValueArgument(2, typeOfCall)
+ }
+
+ putValueArgument(0, fieldArgument)
+ }
+
+ if (!isLazy) {
+ addBackingFieldUtil {
+ type = fieldType
+ visibility = DescriptorVisibilities.PRIVATE
+ isFinal = true
+ }.apply {
+ initializer = factory.createExpressionBody(registerCall)
+ }
+
+ addDefaultGetter(this@rpcFlowField, ctx.irBuiltIns) {
+ visibility = field.property.visibility
+ overriddenSymbols = listOf(servicePropertyGetter.symbol)
+ }
+ } else {
+ val lazyFieldType = ctx.lazy.typeWith(fieldType)
+
+ val lazyField = addBackingFieldUtil {
+ origin = IrDeclarationOrigin.PROPERTY_DELEGATE
+ name = propertyDelegateName(this@apply.name)
+ visibility = DescriptorVisibilities.PRIVATE
+ type = lazyFieldType
+ isFinal = true
+ }.apply {
+ val propertyDelegate = this
+
+ // initializer for Lazy delegate with lambda
+ // inside lambda - 'registerCall' expression is used
+ initializer = factory.createExpressionBody(
+ IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = lazyFieldType,
+ symbol = ctx.functions.lazy,
+ typeArgumentsCount = 1,
+ valueArgumentsCount = 1,
+ ).apply {
+ putTypeArgument(0, fieldType)
+
+ val lambdaType = ctx.function0.typeWith(fieldType)
+
+ val lambdaFunction = factory.buildFun {
+ origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
+ name = SpecialNames.ANONYMOUS
+ visibility = DescriptorVisibilities.LOCAL
+ returnType = fieldType
+ }.apply {
+ parent = propertyDelegate
+
+ body = irBuilder(symbol).irBlockBody {
+ +irReturn(registerCall)
+ }
+ }
+
+ val lambda = IrFunctionExpressionImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = lambdaType,
+ origin = IrStatementOrigin.LAMBDA,
+ function = lambdaFunction,
+ )
+
+ putValueArgument(0, lambda)
+ }
+ )
+ }
+
+ // Invocation of `operator fun getValue(thisRef: Any?, property: KProperty<*>): T` for delegates
+ addGetter {
+ origin = IrDeclarationOrigin.DELEGATED_PROPERTY_ACCESSOR
+ visibility = this@apply.visibility
+ returnType = fieldType
+ }.apply {
+ val propertyGetter = this
+
+ overriddenSymbols = listOf(servicePropertyGetter.symbol)
+
+ val getterThisReceiver = vsApi {
+ stubClassThisReceiver.copyToVS(propertyGetter, origin = IrDeclarationOrigin.DEFINED)
+ }.also {
+ dispatchReceiverParameter = it
+ }
+
+ body = irBuilder(symbol).irBlockBody {
+ +irReturn(
+ irCall(
+ type = fieldType,
+ callee = ctx.functions.lazyGetValue,
+ typeArgumentsCount = 1,
+ valueArgumentsCount = 2,
+ ).apply {
+ putTypeArgument(0, fieldType)
+
+ extensionReceiver = IrGetFieldImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ symbol = lazyField.symbol,
+ type = lazyFieldType,
+ receiver = IrGetValueImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = stubClass.defaultType,
+ symbol = getterThisReceiver.symbol,
+ ),
+ )
+
+ putValueArgument(
+ index = 0,
+ valueArgument = IrGetValueImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = stubClass.defaultType,
+ symbol = getterThisReceiver.symbol,
+ )
+ )
+
+ putValueArgument(
+ index = 1,
+ valueArgument = IrPropertyReferenceImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.kProperty1.typeWith(stubClass.defaultType, fieldType),
+ symbol = fieldProperty.symbol,
+ typeArgumentsCount = 0,
+ field = null,
+ getter = propertyGetter.symbol,
+ setter = null,
+ origin = IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE,
+ )
+ )
+ }
+ )
+ }
+ }
+ }
+ }
+ }
+
+ private fun IrClass.generateMethods() {
+ declaration.methods.forEach {
+ generateRpcMethod(it)
+ }
+ }
+
+ private val methodClasses = mutableListOf()
+
+ /**
+ * RPC Methods generation
+ *
+ * All method classes MUST be already generated, so this plugin can use them.
+ *
+ * ```kotlin
+ * final override suspend fun (): {
+ * return withContext(coroutineContext) {
+ * client.call(RPCCall(
+ * "",
+ * "",
+ * RPCCall.Type.Method,
+ * (()|),
+ * typeOf<>(),
+ * typeOf<>(),
+ * ))
+ * }
+ * }
+ * ```
+ *
+ * Where:
+ * - `` - the name of the RPC method
+ * - `` - array of arguments for the method
+ * - `` - the return type of the method
+ * - `` - FQ name of the RPC service
+ * - ``/`` - generated class or object for this method
+ */
+ @Suppress(
+ "detekt.NestedBlockDepth",
+ "detekt.LongMethod",
+ )
+ private fun IrClass.generateRpcMethod(method: ServiceDeclaration.Method) {
+ val isMethodObject = method.argumentTypes.isEmpty()
+ val methodClassName = "${method.function.name.asString().capitalized()}_" + METHOD_CLASS_SUFFIX_PROPERTY
+
+ val methodClass: IrClass = findDeclaration { it.name.asString() == methodClassName }
+ ?: error("Expected $methodClassName class to be present in stub class ${declaration.simpleName}")
+
+ methodClasses.add(methodClass)
+
+ addFunction {
+ name = method.function.name
+ visibility = method.function.visibility
+ returnType = method.function.returnType
+ modality = Modality.OPEN
+
+ isSuspend = true
+ }.apply {
+ val functionThisReceiver = vsApi {
+ stubClassThisReceiver.copyToVS(this@apply, origin = IrDeclarationOrigin.DEFINED)
+ }.also {
+ dispatchReceiverParameter = it
+ }
+
+ val declaredFunction = this
+
+ val arguments = method.argumentTypes.memoryOptimizedMap { arg ->
+ addValueParameter {
+ name = arg.value.name
+ type = arg.type
+ }
+ }
+
+ overriddenSymbols = listOf(method.function.symbol)
+
+ body = irBuilder(symbol).irBlockBody {
+ +irReturn(
+ irCall(
+ callee = ctx.functions.withContext,
+ type = method.function.returnType,
+ ).apply {
+ putTypeArgument(0, method.function.returnType)
+
+ putValueArgument(
+ index = 0,
+ valueArgument = irCallProperty(
+ clazz = stubClass,
+ property = coroutineContextProperty,
+ symbol = functionThisReceiver.symbol,
+ )
+ )
+
+ // suspend lambda
+ // it's type is not available at runtime, but in fact exists
+ val lambdaType = IrSimpleTypeImpl(
+ ctx.suspendFunction1,
+ SimpleTypeNullability.NOT_SPECIFIED,
+ listOf(
+ makeTypeProjection(ctx.coroutineScope.defaultType, Variance.INVARIANT),
+ makeTypeProjection(method.function.returnType, Variance.INVARIANT),
+ ),
+ listOf(
+ IrConstructorCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.extensionFunctionType.defaultType,
+ symbol = ctx.extensionFunctionType.constructors.single(),
+ typeArgumentsCount = 0,
+ constructorTypeArgumentsCount = 0,
+ valueArgumentsCount = 0,
+ ),
+ ),
+ )
+
+ val functionLambda = factory.buildFun {
+ origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
+ name = SpecialNames.ANONYMOUS
+ visibility = DescriptorVisibilities.LOCAL
+ modality = Modality.FINAL
+ returnType = method.function.returnType
+ isSuspend = true
+ }.apply {
+ parent = declaredFunction
+
+ vsApi {
+ addExtensionReceiverVS(ctx.coroutineScope.defaultType)
+ }.apply {
+ // this name is picked up from the dump of test data
+ name = Name.identifier("this".synthesizedString + "withContext".synthesizedString)
+ }
+
+ body = irBuilder(symbol).irBlockBody {
+ val call = irRPCMethodClientCall(
+ method = method,
+ functionThisReceiver = functionThisReceiver,
+ isMethodObject = isMethodObject,
+ methodClass = methodClass,
+ arguments = arguments,
+ )
+
+ if (method.function.returnType == ctx.irBuiltIns.unitType) {
+ +call
+ } else {
+ +irReturn(call)
+ }
+ }
+ }
+
+ val lambda = IrFunctionExpressionImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = lambdaType,
+ origin = IrStatementOrigin.LAMBDA,
+ function = functionLambda,
+ )
+
+ putValueArgument(1, lambda)
+ }
+ )
+ }
+ }
+ }
+
+ /**
+ * Part of [generateRpcMethod] that generates next call:
+ *
+ * ```kotlin
+ * client.call(RPCCall(
+ * "",
+ * "",
+ * RPCCall.Type.Method,
+ * (()|),
+ * typeOf<>(),
+ * typeOf<>(),
+ * ))
+ * ```
+ */
+ @Suppress(
+ "detekt.NestedBlockDepth",
+ "detekt.MagicNumber",
+ )
+ private fun IrBlockBodyBuilder.irRPCMethodClientCall(
+ method: ServiceDeclaration.Method,
+ functionThisReceiver: IrValueParameter,
+ isMethodObject: Boolean,
+ methodClass: IrClass,
+ arguments: List
+ ): IrCall {
+ val call = irCall(
+ callee = ctx.functions.rpcClientCall.symbol,
+ type = method.function.returnType,
+ typeArgumentsCount = 1,
+ valueArgumentsCount = 1,
+ ).apply {
+ dispatchReceiver = irCallProperty(
+ clazz = stubClass,
+ property = clientProperty,
+ symbol = functionThisReceiver.symbol,
+ )
+
+ putTypeArgument(0, method.function.returnType)
+
+ val rpcCallConstructor = irCallConstructor(
+ callee = ctx.rpcCall.constructors.single(),
+ typeArguments = emptyList(),
+ ).apply {
+ putValueArgument(
+ index = 0,
+ valueArgument = stringConst(declaration.service.kotlinFqName.asString()),
+ )
+
+ putValueArgument(
+ index = 1,
+ valueArgument = stringConst(method.function.name.asString()),
+ )
+
+ putValueArgument(
+ index = 2,
+ valueArgument = IrGetEnumValueImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.rpcCallType.defaultType,
+ symbol = ctx.rpcCallTypeMethod,
+ ),
+ )
+
+ val dataParameter = if (isMethodObject) {
+ irGetObject(methodClass.symbol)
+ } else {
+ irCallConstructor(
+ // serialization plugin adds additional constructor with more arguments
+ callee = methodClass.constructors.single {
+ it.valueParameters.size == method.argumentTypes.size
+ }.symbol,
+ typeArguments = emptyList(),
+ ).apply {
+ arguments.forEachIndexed { i, valueParameter ->
+ putValueArgument(i, irGet(valueParameter))
+ }
+ }
+ }
+
+ putValueArgument(3, dataParameter)
+
+ putValueArgument(
+ index = 4,
+ valueArgument = irCall(
+ ctx.functions.typeOf,
+ ).apply {
+ putTypeArgument(0, methodClass.defaultType)
+ },
+ )
+
+ putValueArgument(
+ index = 5,
+ valueArgument = irCall(
+ ctx.functions.typeOf,
+ ).apply {
+ putTypeArgument(0, method.function.returnType)
+ },
+ )
+ }
+
+ putValueArgument(0, rpcCallConstructor)
+ }
+ return call
+ }
+
+ private fun irCallProperty(
+ clazz: IrClass,
+ property: IrProperty,
+ type: IrType? = null,
+ symbol: IrValueSymbol? = null,
+ ): IrCall {
+ return irCallProperty(
+ receiver = IrGetValueImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = type ?: clazz.defaultType,
+ symbol = symbol
+ ?: clazz.thisReceiver?.symbol
+ ?: error("Expected thisReceiver for ${clazz.name.asString()}"),
+ ),
+ property = property,
+ )
+ }
+
+ private fun irCallProperty(receiver: IrExpression, property: IrProperty): IrCall {
+ val getter = property.getter
+ ?: error("Expected property getter to call it: ${property.dump()}")
+
+ return IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = getter.returnType,
+ symbol = getter.symbol,
+ origin = IrStatementOrigin.GET_PROPERTY,
+ valueArgumentsCount = getter.valueParameters.size,
+ typeArgumentsCount = getter.typeParameters.size,
+ ).apply {
+ dispatchReceiver = receiver
+ }
+ }
+
+ private var stubCompanionObject: IrClassSymbol by Delegates.notNull()
+ private var stubCompanionObjectThisReceiver: IrValueParameter by Delegates.notNull()
+
+ /**
+ * Companion object for the RPC service stub.
+ * The empty object should already be generated
+ *
+ * ```kotlin
+ * companion object : RPCStubObject
+ * ```
+ */
+ private fun IrClass.generateCompanionObject() {
+ companionObject()?.apply {
+ // clearing previous declarations, as they may break with the ones added here
+ declarations.clear()
+
+ stubCompanionObject = symbol
+ stubCompanionObjectThisReceiver = thisReceiver
+ ?: error("Stub companion object expected to have thisReceiver: ${name.asString()}")
+
+ superTypes = listOf(ctx.rpcStubObject.typeWith(declaration.serviceType))
+
+ generateCompanionObjectConstructor()
+
+ generateCompanionObjectContent()
+
+ addAnyOverrides(ctx.rpcStubObject.owner)
+ } ?: error("Expected companion object to be present")
+ }
+
+ private fun IrClass.generateCompanionObjectConstructor() {
+ // default object constructor
+ addConstructor {
+ name = this@generateCompanionObjectConstructor.name
+ isPrimary = true
+ visibility = DescriptorVisibilities.PRIVATE
+ }.apply {
+ body = irBuilder(symbol).irBlockBody {
+ +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
+ +IrInstanceInitializerCallImpl(
+ startOffset = startOffset,
+ endOffset = endOffset,
+ classSymbol = this@generateCompanionObjectConstructor.symbol,
+ type = context.irBuiltIns.unitType,
+ )
+ }
+ }
+ }
+
+ private fun IrClass.generateCompanionObjectContent() {
+ generateMethodNamesProperty()
+
+ generateMethodTypeOfFunction()
+
+ generateWithClientFunction()
+
+ generateRpcFieldsFunction()
+ }
+
+ private var methodNamesMap: IrProperty by Delegates.notNull()
+
+ /**
+ * Method names property.
+ * A map that holds a KType of the method class by method string name
+ *
+ * ```kotlin
+ * private val methodNames: Map = mapOf(
+ * Pair("", typeOf<>()),
+ * ...
+ * Pair("", typeOf<>()),
+ * )
+ *
+ * // when n=0:
+ * private val methodNames: Map = emptyMap()
+ * ```
+ *
+ * Where:
+ * - `` - the name of the k-th method in the service
+ * - `` - the method class for the k-th method in the service
+ */
+ private fun IrClass.generateMethodNamesProperty() {
+ methodNamesMap = addProperty {
+ name = Name.identifier(METHOD_NAMES_PROPERTY)
+ visibility = DescriptorVisibilities.PRIVATE
+ modality = Modality.FINAL
+ }.apply {
+ val mapType = ctx.irBuiltIns.mapClass.typeWith(
+ ctx.irBuiltIns.stringType,
+ ctx.kTypeClass.defaultType,
+ )
+
+ addBackingFieldUtil {
+ type = mapType
+ isFinal = true
+ vsApi { modalityVS = Modality.FINAL }
+ visibility = DescriptorVisibilities.PRIVATE
+ }.apply {
+ val isEmpty = declaration.methods.isEmpty()
+
+ initializer = factory.createExpressionBody(
+ IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = mapType,
+ symbol = if (isEmpty) ctx.functions.emptyMap else ctx.functions.mapOf,
+ valueArgumentsCount = if (isEmpty) 0 else 1,
+ typeArgumentsCount = 2,
+ ).apply mapApply@{
+ putTypeArgument(0, ctx.irBuiltIns.stringType)
+ putTypeArgument(1, ctx.kTypeClass.defaultType)
+
+ if (isEmpty) {
+ return@mapApply
+ }
+
+ val pairType = ctx.pair.typeWith(
+ ctx.irBuiltIns.stringType,
+ ctx.kTypeClass.defaultType,
+ )
+
+ val varargType = ctx.irBuiltIns.arrayClass.typeWith(pairType, Variance.OUT_VARIANCE)
+
+ val vararg = IrVarargImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = varargType,
+ varargElementType = pairType,
+ elements = declaration.methods.memoryOptimizedMapIndexed { i, method ->
+ IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = pairType,
+ symbol = ctx.functions.to,
+ typeArgumentsCount = 2,
+ valueArgumentsCount = 1,
+ ).apply {
+ putTypeArgument(0, ctx.irBuiltIns.stringType)
+ putTypeArgument(1, ctx.kTypeClass.defaultType)
+
+ extensionReceiver = stringConst(method.function.name.asString())
+
+ val type = IrCallImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.kTypeClass.defaultType,
+ symbol = ctx.functions.typeOf,
+ typeArgumentsCount = 1,
+ valueArgumentsCount = 0,
+ ).apply {
+ putTypeArgument(0, methodClasses[i].defaultType)
+ }
+
+ putValueArgument(0, type)
+ }
+ },
+ )
+
+ putValueArgument(0, vararg)
+ }
+ )
+ }
+
+ addDefaultGetter(this@generateMethodNamesProperty, ctx.irBuiltIns) {
+ visibility = DescriptorVisibilities.PRIVATE
+ }
+ }
+ }
+
+ /**
+ * Accessor function for `methodNames` map
+ * Defined in `RPCStubObject`
+ *
+ * ```kotlin
+ * final override fun methodTypeOf(methodName: String): KType? = methodNames[methodName]
+ * ```
+ */
+ private fun IrClass.generateMethodTypeOfFunction() {
+ val kTypeNullable = ctx.kTypeClass.createType(hasQuestionMark = true, emptyList())
+
+ addFunction {
+ name = Name.identifier(METHOD_TYPE_OF_FUNCTION)
+ visibility = DescriptorVisibilities.PUBLIC
+ modality = Modality.OPEN
+ returnType = kTypeNullable
+ }.apply {
+ overriddenSymbols = listOf(ctx.rpcStubObject.functionByName(METHOD_TYPE_OF_FUNCTION))
+
+ val functionThisReceiver = vsApi {
+ stubCompanionObjectThisReceiver.copyToVS(this@apply, origin = IrDeclarationOrigin.DEFINED)
+ }.also {
+ dispatchReceiverParameter = it
+ }
+
+ val methodName = addValueParameter {
+ name = Name.identifier("methodName")
+ type = ctx.irBuiltIns.stringType
+ }
+
+ body = irBuilder(symbol).irBlockBody {
+ +irReturn(
+ irCall(ctx.functions.mapGet.symbol, kTypeNullable).apply {
+ vsApi { originVS = IrStatementOrigin.GET_ARRAY_ELEMENT }
+
+ dispatchReceiver = irCallProperty(
+ clazz = this@generateMethodTypeOfFunction,
+ property = methodNamesMap,
+ symbol = functionThisReceiver.symbol,
+ )
+
+ putValueArgument(0, irGet(methodName))
+ }
+ )
+ }
+ }
+ }
+
+ /**
+ * Factory method for creating a new instance of RPC service
+ *
+ * ```kotlin
+ * final override fun withClient(client: RPCClient): MyService {
+ * return MyServiceStub(client)
+ * }
+ * ```
+ */
+ private fun IrClass.generateWithClientFunction() {
+ addFunction {
+ name = Name.identifier(WITH_CLIENT_METHOD)
+ visibility = DescriptorVisibilities.PUBLIC
+ modality = Modality.OPEN
+ returnType = declaration.serviceType
+ }.apply {
+ overriddenSymbols = listOf(ctx.rpcStubObject.functionByName(WITH_CLIENT_METHOD))
+
+ dispatchReceiverParameter = vsApi {
+ stubCompanionObjectThisReceiver.copyToVS(this@apply, origin = IrDeclarationOrigin.DEFINED)
+ }
+
+ val client = addValueParameter {
+ name = Name.identifier("client")
+ type = ctx.rpcClient.defaultType
+ }
+
+ body = irBuilder(symbol).irBlockBody {
+ +irReturn(
+ irCallConstructor(
+ callee = stubClass.constructors.single().symbol,
+ typeArguments = emptyList(),
+ ).apply {
+ putValueArgument(0, irGet(client))
+ }
+ )
+ }
+ }
+ }
+
+ /**
+ * Function for obtaining a list of all RPC fields in a given service as [RPCDeferredField<*>]
+ *
+ * ```kotlin
+ * final override fun rpcFields(service: MyService): List> {
+ * return listOf( // or emptyList() if no fields
+ * service.,
+ * ...
+ * service.,
+ * ) as List>
+ * }
+ * ```
+ *
+ * Where:
+ * - `` - k-th field of a given service
+ */
+ private fun IrClass.generateRpcFieldsFunction() {
+ val listType = ctx.irBuiltIns.listClass.typeWith(ctx.rpcDeferredField.starProjectedType)
+
+ addFunction {
+ name = Name.identifier(RPC_FIELDS_METHOD)
+ visibility = DescriptorVisibilities.PUBLIC
+ modality = Modality.OPEN
+
+ returnType = listType
+ }.apply {
+ overriddenSymbols = listOf(ctx.rpcStubObject.functionByName(RPC_FIELDS_METHOD))
+
+ dispatchReceiverParameter = vsApi {
+ stubCompanionObjectThisReceiver.copyToVS(this@apply, origin = IrDeclarationOrigin.DEFINED)
+ }
+
+ val service = addValueParameter {
+ name = Name.identifier("service")
+ type = declaration.serviceType
+ }
+
+ body = irBuilder(symbol).irBlockBody {
+ val isEmpty = declaration.fields.isEmpty()
+
+ val anyListType = ctx.irBuiltIns.listClass.typeWith(ctx.anyNullable)
+
+ val listCall = irCall(
+ callee = if (isEmpty) ctx.functions.emptyList else ctx.functions.listOf,
+ type = anyListType,
+ ).apply listApply@{
+ putTypeArgument(0, ctx.anyNullable)
+
+ if (isEmpty) {
+ return@listApply
+ }
+
+ val anyArrayType = ctx.irBuiltIns.arrayClass.typeWith(ctx.anyNullable, Variance.OUT_VARIANCE)
+
+ val vararg = IrVarargImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = anyArrayType,
+ varargElementType = ctx.anyNullable,
+ elements = declaration.fields.memoryOptimizedMap {
+ irCallProperty(irGet(service), it.property)
+ }
+ )
+
+ putValueArgument(0, vararg)
+ }
+
+ +irReturn(irAs(listCall, listType))
+ }
+ }
+ }
+
+ // Associated object annotation works on JS and Native platforms.
+ // See https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/find-associated-object.html
+ private fun addAssociatedObjectAnnotationIfPossible() {
+ if (ctx.isJsTarget() || ctx.isNativeTarget()) {
+ addAssociatedObjectAnnotation()
+ }
+ }
+
+ private fun addAssociatedObjectAnnotation() {
+ val service = declaration.service
+
+ service.annotations += IrConstructorCallImpl(
+ startOffset = service.startOffset,
+ endOffset = service.endOffset,
+ type = ctx.withRPCStubObjectAnnotation.defaultType,
+ symbol = ctx.withRPCStubObjectAnnotation.constructors.single(),
+ typeArgumentsCount = 0,
+ constructorTypeArgumentsCount = 0,
+ valueArgumentsCount = 1,
+ ).apply {
+ val companionObjectType = stubCompanionObject.defaultType
+ putValueArgument(
+ index = 0,
+ valueArgument = IrClassReferenceImpl(
+ startOffset = startOffset,
+ endOffset = endOffset,
+ type = ctx.irBuiltIns.kClassClass.typeWith(companionObjectType),
+ symbol = stubCompanionObject,
+ classType = companionObjectType,
+ )
+ )
+ }
+ }
+
+ // adds fake overrides for toString(), equals(), hashCode() for a class
+ private fun IrClass.addAnyOverrides(parent: IrClass? = null) {
+ val anyClass = ctx.irBuiltIns.anyClass.owner
+ val overridenClass = parent ?: anyClass
+
+ addFunction {
+ name = OperatorNameConventions.EQUALS
+ visibility = DescriptorVisibilities.PUBLIC
+ modality = Modality.OPEN
+ origin = IrDeclarationOrigin.FAKE_OVERRIDE
+
+ isOperator = true
+ isFakeOverride = true
+ returnType = ctx.irBuiltIns.booleanType
+ }.apply {
+ overriddenSymbols += overridenClass.functions.single { it.name == OperatorNameConventions.EQUALS }.symbol
+
+ dispatchReceiverParameter = anyClass.thisReceiver
+
+ addValueParameter {
+ name = Name.identifier("other")
+ type = ctx.anyNullable
+ }
+ }
+
+ addFunction {
+ name = OperatorNameConventions.HASH_CODE
+ visibility = DescriptorVisibilities.PUBLIC
+ modality = Modality.OPEN
+ origin = IrDeclarationOrigin.FAKE_OVERRIDE
+
+ isFakeOverride = true
+ returnType = ctx.irBuiltIns.intType
+ }.apply {
+ overriddenSymbols += overridenClass.functions.single { it.name == OperatorNameConventions.HASH_CODE }.symbol
+
+ dispatchReceiverParameter = anyClass.thisReceiver
+ }
+
+ addFunction {
+ name = OperatorNameConventions.TO_STRING
+ visibility = DescriptorVisibilities.PUBLIC
+ modality = Modality.OPEN
+ origin = IrDeclarationOrigin.FAKE_OVERRIDE
+
+ isFakeOverride = true
+ returnType = ctx.irBuiltIns.stringType
+ }.apply {
+ overriddenSymbols += overridenClass.functions.single { it.name == OperatorNameConventions.TO_STRING }.symbol
+
+ dispatchReceiverParameter = anyClass.thisReceiver
+ }
+ }
+
+ private fun stringConst(value: String) = IrConstImpl.string(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.irBuiltIns.stringType,
+ value = value,
+ )
+
+ private fun vsApi(body: VersionSpecificApi.() -> T): T {
+ return ctx.versionSpecificApi.body()
+ }
+}
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
new file mode 100644
index 00000000..81a8ab32
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.extension
+
+import org.jetbrains.kotlin.ir.declarations.IrClass
+import org.jetbrains.kotlin.ir.declarations.IrProperty
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.types.IrType
+import org.jetbrains.kotlin.ir.util.defaultType
+
+class ServiceDeclaration(
+ val service: IrClass,
+ val stubClass: IrClass,
+ val methods: List,
+ val fields: List,
+) {
+ val simpleName: String = service.name.asString()
+ val serviceType = service.defaultType
+
+ class Method(
+ val function: IrSimpleFunction,
+ val argumentTypes: List,
+ ) {
+ class Argument(
+ val value: IrValueParameter,
+ val type: IrType,
+ )
+ }
+
+ class FlowField(
+ val property: IrProperty,
+ val flowKind: Kind,
+ ) {
+ enum class Kind {
+ Plain, Shared, State;
+ }
+ }
+}
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCClientObject.kt b/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCStubObject.kt
similarity index 84%
rename from core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCClientObject.kt
rename to core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCStubObject.kt
index 66e3cec1..bb6b4a17 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCClientObject.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCStubObject.kt
@@ -9,13 +9,13 @@ import kotlinx.rpc.RPCClient
import kotlin.reflect.KType
@InternalRPCApi
-public interface RPCClientObject :
- RPCClientProvider,
+public interface RPCStubObject :
+ RPCStubServiceProvider,
RPCServiceMethodSerializationTypeProvider,
RPCServiceFieldsProvider
@InternalRPCApi
-public interface RPCClientProvider {
+public interface RPCStubServiceProvider {
public fun withClient(serviceId: Long, client: RPCClient) : T
}
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRpcClientObject.kt b/core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.kt
similarity index 100%
rename from core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRpcClientObject.kt
rename to core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.kt
diff --git a/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.native.kt b/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
similarity index 75%
rename from core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.native.kt
rename to core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
index eac89d5a..9e4f061a 100644
--- a/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.native.kt
+++ b/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
@@ -16,15 +16,15 @@ import kotlin.reflect.findAssociatedObject
@AssociatedObjectKey
@OptIn(ExperimentalAssociatedObjects::class)
@Target(AnnotationTarget.CLASS)
-public annotation class WithRPCClientObject(
+public annotation class WithRPCStubObject(
@Suppress("unused")
- val client: KClass>
+ val stub: KClass>
)
@InternalRPCApi
@OptIn(ExperimentalAssociatedObjects::class)
public actual fun findRPCProviderInCompanion(kClass: KClass<*>): R {
@Suppress("UNCHECKED_CAST")
- return kClass.findAssociatedObject() as? R
- ?: internalError("unable to find $kClass rpc client object")
+ return kClass.findAssociatedObject() as? R
+ ?: internalError("unable to find $kClass rpc stub object")
}
diff --git a/core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.jvm.kt b/core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.jvm.kt
similarity index 90%
rename from core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.jvm.kt
rename to core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.jvm.kt
index 62614b35..941fbc4b 100644
--- a/core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.jvm.kt
+++ b/core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.jvm.kt
@@ -13,7 +13,7 @@ import kotlin.reflect.full.companionObjectInstance
public actual fun findRPCProviderInCompanion(kClass: KClass<*>): R {
@Suppress("UNCHECKED_CAST")
return kClass.java.classLoader
- .loadClass("kotlinx.rpc.${kClass.simpleName}Client")
+ .loadClass("${kClass.qualifiedName}Stub")
?.kotlin
?.companionObjectInstance as? R
?: internalError("unable to find $kClass rpc client object")
diff --git a/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.js.kt b/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt
similarity index 75%
rename from core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.js.kt
rename to core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt
index eac89d5a..9e4f061a 100644
--- a/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCClientObject.js.kt
+++ b/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt
@@ -16,15 +16,15 @@ import kotlin.reflect.findAssociatedObject
@AssociatedObjectKey
@OptIn(ExperimentalAssociatedObjects::class)
@Target(AnnotationTarget.CLASS)
-public annotation class WithRPCClientObject(
+public annotation class WithRPCStubObject(
@Suppress("unused")
- val client: KClass>
+ val stub: KClass>
)
@InternalRPCApi
@OptIn(ExperimentalAssociatedObjects::class)
public actual fun findRPCProviderInCompanion(kClass: KClass<*>): R {
@Suppress("UNCHECKED_CAST")
- return kClass.findAssociatedObject() as? R
- ?: internalError("unable to find $kClass rpc client object")
+ return kClass.findAssociatedObject() as? R
+ ?: internalError("unable to find $kClass rpc stub object")
}
diff --git a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/KRPCClient.kt b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/KRPCClient.kt
index 51615e8d..e2b02446 100644
--- a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/KRPCClient.kt
+++ b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/KRPCClient.kt
@@ -22,6 +22,7 @@ import kotlinx.serialization.SerialFormat
import kotlinx.serialization.StringFormat
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.cancellation.CancellationException
+import kotlin.reflect.KType
import kotlin.reflect.typeOf
/**
@@ -255,7 +256,14 @@ public abstract class KRPCClient(
awaitHandshakeCompletion()
val id = callCounter.incrementAndGet()
- val callId = "$connectionId:${callInfo.dataType}:$id"
+
+ val dataTypeString = if (callInfo.data == FieldDataObject) {
+ callInfo.dataType.toString()
+ } else {
+ callInfo.dataType.transformFQNameToCompatible()
+ }
+
+ val callId = "$connectionId:$dataTypeString:$id"
logger.trace { "start a call[$callId] ${callInfo.callableName}" }
@@ -288,6 +296,18 @@ public abstract class KRPCClient(
val callId: String,
)
+ // compatibility transformation
+ // from new: org.jetbrains.krpc.some.other.subpackage.MyServiceStub.Empty_RPCData
+ // to old: org.jetbrains.krpc.MyServiceClient.Empty_RPCData
+ private fun KType.transformFQNameToCompatible(): String {
+ return toString()
+ .split(".")
+ .takeLast(2)
+ .joinToString(".")
+ .replace("Stub.", "Client.")
+ .let { "org.jetbrains.krpc.$it" }
+ }
+
private suspend fun executeCall(
callId: String,
streamContext: LazyRPCStreamContext,
diff --git a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/RPCClientUtils.kt b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/RPCClientUtils.kt
index 2496b37d..29bffe22 100644
--- a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/RPCClientUtils.kt
+++ b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/RPCClientUtils.kt
@@ -7,7 +7,7 @@ package kotlinx.rpc.client
import kotlinx.atomicfu.atomic
import kotlinx.rpc.RPC
import kotlinx.rpc.RPCClient
-import kotlinx.rpc.internal.RPCClientProvider
+import kotlinx.rpc.internal.RPCStubServiceProvider
import kotlinx.rpc.internal.findRPCProviderInCompanion
import kotlinx.rpc.internal.kClass
import kotlin.reflect.KClass
@@ -54,7 +54,7 @@ private val SERVICE_ID = atomic(0L)
* @return instance of the generated service.
*/
public fun RPCClient.withService(serviceKClass: KClass): T {
- val provider = findRPCProviderInCompanion>(serviceKClass)
+ val provider = findRPCProviderInCompanion>(serviceKClass)
val id = SERVICE_ID.incrementAndGet()
return provider.withClient(id, this)
diff --git a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCClientServiceGenerator.kt b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCClientServiceGenerator.kt
index f53e9ca1..e550fcd4 100644
--- a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCClientServiceGenerator.kt
+++ b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCClientServiceGenerator.kt
@@ -24,8 +24,8 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
fun generate(service: RPCServiceDeclaration) {
val writer = codegen.createNewFile(
dependencies = Dependencies(aggregating = true, service.file),
- packageName = "kotlinx.rpc",
- fileName = service.simpleName.withClientImplSuffix(),
+ packageName = service.packageName,
+ fileName = service.simpleName.withStubImplSuffix(useKSPSuffix = false),
extensionName = "kt",
).bufferedWriter(charset = Charsets.UTF_8).codeWriter()
@@ -40,45 +40,71 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
writer.writeLine("@file:OptIn(InternalRPCApi::class)")
writer.newLine()
- writer.writeLine("package kotlinx.rpc")
- writer.newLine()
+ if (service.packageName.isNotBlank()) {
+ writer.writeLine("package ${service.packageName}")
+ writer.newLine()
+ }
generateImports(writer, service)
- writer.writeLine("@Suppress(\"unused\")")
- writer.writeLine("class ${service.simpleName.withClientImplSuffix()}(")
- with(writer.nested()) {
- writeLine("private val $ID_PROPERTY_NAME: Long,")
- writeLine("private val $CLIENT_PROPERTY_NAME: RPCClient,")
- }
- writer.writeLine(") : ${service.fullName} {")
+ // todo remove after all compiler parts are done
+ // left commented out for further debugging
+// writer.write("class ${service.simpleName.withClientImplSuffix()}(")
+// writer.newLine()
+// with(writer.nested()) {
+// write("private val $ID_PROPERTY_NAME: Long,")
+// newLine()
+// write("private val $CLIENT_PROPERTY_NAME: RPCClient,")
+// newLine()
+// }
+// writer.write(") : ${service.fullName} {")
+// writer.newLine()
+//
+// val nested = writer.nested()
+//
+// nested.write("override val coroutineContext: CoroutineContext = $CLIENT_PROPERTY_NAME.provideStubContext($ID_PROPERTY_NAME)")
+// nested.newLine()
+// nested.newLine()
+//
+// nested.write("private val $SCOPE_PROPERTY_NAME: CoroutineScope = this")
+// nested.newLine()
+// nested.newLine()
+//
+// service.fields.forEach {
+// it.toCode(service.fullName, nested)
+// }
+//
+// service.functions.forEach {
+// it.toCode(service.fullName, nested)
+// }
+// generateProviders(writer.nested(), service)
+// writer.write("}")
+
+ generateStubClass(service, writer)
- val nested = writer.nested()
+ writer.flush()
+ }
- nested.writeLine("override val coroutineContext: CoroutineContext = $CLIENT_PROPERTY_NAME.provideStubContext($ID_PROPERTY_NAME)")
- nested.newLine()
+ private fun generateStubClass(service: RPCServiceDeclaration, writer: CodeWriter) {
+ writer.writeLine("@Deprecated(level = DeprecationLevel.HIDDEN, message = \"Internal kotlinx.rpc API, do not use!\")")
+ writer.writeLine("class ${service.simpleName.withStubImplSuffix(useKSPSuffix = false)} {")
- nested.writeLine("private val $SCOPE_PROPERTY_NAME: CoroutineScope = this")
- nested.newLine()
+ with(writer.nested()) {
+ service.functions.forEach {
+ it.generateFunctionClass(this)
+ }
- service.fields.forEach {
- it.toCode(service.fullName, nested)
+ writeLine("companion object")
}
- service.functions.forEach {
- it.toCode(service.fullName, nested)
- }
- generateProviders(writer.nested(), service)
writer.writeLine("}")
-
- writer.flush()
}
private fun generateImports(writer: CodeWriter, service: RPCServiceDeclaration) {
writer.writeLine("import kotlinx.coroutines.*")
- writer.writeLine("import kotlinx.serialization.Serializable")
- writer.writeLine("import kotlinx.serialization.Contextual")
+ writer.writeLine("import kotlinx.serialization.*")
writer.writeLine("import kotlinx.rpc.internal.*")
+ writer.writeLine("import kotlinx.rpc.*")
writer.writeLine("import kotlin.reflect.typeOf")
writer.writeLine("import kotlin.coroutines.CoroutineContext")
service.collectRootImports().forEach {
@@ -88,12 +114,10 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
writer.newLine()
}
- private fun RPCServiceDeclaration.Function.toCode(serviceType: String, writer: CodeWriter) {
- generateFunctionClass(writer)
-
+ private fun RPCServiceDeclaration.Function.toCode(service: RPCServiceDeclaration, writer: CodeWriter) {
val returnTypeGenerated = if (returnType.isUnit()) ": Unit" else ": ${returnType.toCode()}"
writer.writeLine("override suspend fun ${name}(${argumentTypes.joinToString { it.toCode() }})$returnTypeGenerated = scopedClientCall($SCOPE_PROPERTY_NAME) {")
- generateBody(serviceType, writer.nested())
+ generateBody(service, writer.nested())
writer.writeLine("}")
writer.newLine()
}
@@ -119,7 +143,7 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
val rpcFiled = "RPCField(\"$serviceType\", $ID_PROPERTY_NAME, \"$name\", typeOf<$codeType>())"
- val codeDeclaration = "override val $name: $codeType $prefix $CLIENT_PROPERTY_NAME.$method($SCOPE_PROPERTY_NAME, $rpcFiled)$suffix"
+ val codeDeclaration = "final override val $name: $codeType $prefix $CLIENT_PROPERTY_NAME.$method($SCOPE_PROPERTY_NAME, $rpcFiled)$suffix"
writer.writeLine(codeDeclaration)
writer.newLine()
@@ -149,10 +173,7 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
return this == null || this.declaration.simpleName.getShortName() == "Unit"
}
- private fun RPCServiceDeclaration.Function.generateBody(serviceType: String, writer: CodeWriter) {
- writer.writeLine("val returnType = typeOf<${returnType.toCode()}>()")
- writer.writeLine("val dataType = typeOf<${name.functionGeneratedClass()}>()")
-
+ private fun RPCServiceDeclaration.Function.generateBody(service: RPCServiceDeclaration, writer: CodeWriter) {
val data = "${name.functionGeneratedClass()}${
if (argumentTypes.isEmpty()) "" else "(${
argumentTypes.joinToString {
@@ -164,13 +185,15 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
})"
}"
- val rpcCall = "RPCCall(\"$serviceType\", $ID_PROPERTY_NAME, \"$name\", RPCCall.Type.Method, $data, dataType, returnType)"
+ val rpcCall =
+ "RPCCall(\"${service.fullName}\", $ID_PROPERTY_NAME, \"$name\", RPCCall.Type.Method, $data, typeOf<${
+ name.functionGeneratedClass()
+ }>(), typeOf<${returnType.toCode()}>())"
writer.writeLine("$CLIENT_PROPERTY_NAME.call($rpcCall)")
}
private fun RPCServiceDeclaration.Function.generateFunctionClass(writer: CodeWriter) {
writer.writeLine("@Serializable")
- writer.writeLine("@Suppress(\"unused\")")
val classOrObject = if (argumentTypes.isEmpty()) "object" else "class"
writer.writeLine("internal $classOrObject ${name.functionGeneratedClass()}${if (argumentTypes.isEmpty()) " : RPCMethodClassArguments {" else "("}")
if (argumentTypes.isNotEmpty()) {
@@ -198,36 +221,40 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
private fun generateProviders(writer: CodeWriter, service: RPCServiceDeclaration) {
writer.newLine()
- writer.writeLine("companion object : RPCClientObject<${service.fullName}> {")
+ writer.writeLine("companion object : RPCStubObject<${service.fullName}> {")
with(writer.nested()) {
val mapFunction = if (service.functions.isEmpty()) "emptyMap()" else "mapOf("
writeLine("private val methodNames: Map = $mapFunction")
if (service.functions.isNotEmpty()) {
with(nested()) {
service.functions.forEach { function ->
- writeLine("${service.fullName}::${function.name}.name to typeOf<${service.simpleName.withClientImplSuffix()}.${function.name.functionGeneratedClass()}>(),")
+ writeLine("\"${function.name}\" to typeOf<${function.name.functionGeneratedClass()}>(),")
}
}
writeLine(")")
}
newLine()
- writeLine("@Suppress(\"unused\")")
+ writeLine("override fun withClient(serviceId: Long, client: RPCClient): ${service.fullName} = ${service.simpleName.withClientImplSuffix()}(serviceId, client)")
+ newLine()
+
writeLine("override fun methodTypeOf(methodName: String): kotlin.reflect.KType? = methodNames[methodName]")
newLine()
- writeLine("override fun withClient(serviceId: Long, client: RPCClient): ${service.fullName} = ${service.simpleName.withClientImplSuffix()}(serviceId, client)")
+ writeLine("override fun withClient(serviceId: Long, client: RPCClient): ${service.fullName} = ${service.simpleName.withStubImplSuffix()}(client)")
newLine()
- writeLine("override fun rpcFields(service: ${service.fullName}): List> = with(service) {")
+ writeLine("override fun rpcFields(service: ${service.fullName}): List> {")
with(nested()) {
if (service.fields.isEmpty()) {
writeLine("return emptyList()")
} else {
- writeLine("return listOf(")
+ write("return listOf(")
+ newLine()
with(nested()) {
service.fields.forEach {
- writeLine("${it.name},")
+ write("service.${it.name},")
+ newLine()
}
}
writeLine(") as List>")
@@ -239,6 +266,6 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
}
}
-fun String.withClientImplSuffix() = "${this}Client"
+fun String.withStubImplSuffix(useKSPSuffix: Boolean = true) = "${this}Stub${if (useKSPSuffix) "_KSP" else ""}"
fun String.functionGeneratedClass() = "${replaceFirstChar { it.uppercaseChar() }}_RPCData"
diff --git a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCServiceDeclaration.kt b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCServiceDeclaration.kt
index 92c49101..8b27b23c 100644
--- a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCServiceDeclaration.kt
+++ b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCServiceDeclaration.kt
@@ -12,6 +12,7 @@ class RPCServiceDeclaration(
private val declaration: KSDeclaration,
val simpleName: String,
val fullName: String,
+ val packageName: String,
val functions: List,
val fields: List,
val file: KSFile,
diff --git a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCSymbolProcessor.kt b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCSymbolProcessor.kt
index 9028895b..05a8e308 100644
--- a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCSymbolProcessor.kt
+++ b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCSymbolProcessor.kt
@@ -68,6 +68,7 @@ class RPCSymbolProcessor(
simpleName = serviceDeclaration.simpleName.asString(),
fullName = serviceDeclaration.qualifiedName?.asString()
?: codegenError(serviceDeclaration),
+ packageName = serviceDeclaration.packageName.asString(),
functions = processedFunctions,
fields = processedProperties,
file = file,
From 5064c76e52d24cb68b5faf48417d5a02577e723f Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Thu, 16 May 2024 12:26:30 +0200
Subject: [PATCH 02/17] Update IR plugin to the latest library version
---
.../rpc/codegen/extension/RPCIrContext.kt | 32 +--
.../extension/RPCIrServiceProcessor.kt | 2 +-
.../rpc/codegen/extension/RPCStubGenerator.kt | 195 +++++++++---------
.../kotlin/kotlinx/rpc/client/KRPCClient.kt | 20 +-
.../kotlin/kotlinx/rpc/test/ProtocolTest.kt | 2 +-
.../rpc/codegen/RPCClientServiceGenerator.kt | 11 +-
.../0_1_1_SNAPSHOT/callException_json.gold | 8 +
.../wire_dumps/0_1_1_SNAPSHOT/echo_json.gold | 8 +
.../0_1_1_SNAPSHOT/echo_protobuf.gold | 16 ++
9 files changed, 145 insertions(+), 149 deletions(-)
create mode 100644 runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold
create mode 100644 runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold
create mode 100644 runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt
index 85e29f92..27a4ce03 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt
@@ -28,14 +28,6 @@ internal class RPCIrContext(
irBuiltIns.anyType.makeNullable()
}
- val optInAnnotation by lazy {
- getIrClassSymbol("kotlin", "OptIn")
- }
-
- val extensionFunctionType by lazy {
- getIrClassSymbol("kotlin", "ExtensionFunctionType")
- }
-
val coroutineScope by lazy {
getIrClassSymbol("kotlinx.coroutines", "CoroutineScope")
}
@@ -44,10 +36,6 @@ internal class RPCIrContext(
getIrClassSymbol("kotlin.coroutines", "CoroutineContext")
}
- val completableJob by lazy {
- getIrClassSymbol("kotlinx.coroutines", "CompletableJob")
- }
-
val kTypeClass by lazy {
getIrClassSymbol("kotlin.reflect", "KType")
}
@@ -60,8 +48,8 @@ internal class RPCIrContext(
getIrClassSymbol("kotlin", "Function0")
}
- val suspendFunction1 by lazy {
- getIrClassSymbol("kotlin.coroutines", "SuspendFunction1")
+ val suspendFunction0 by lazy {
+ getIrClassSymbol("kotlin.coroutines", "SuspendFunction0")
}
val flow by lazy {
@@ -153,10 +141,18 @@ internal class RPCIrContext(
rpcClient.namedFunction("call")
}
+ val provideStubContext by lazy {
+ rpcClient.namedFunction("provideStubContext")
+ }
+
val typeOf by lazy {
namedFunction("kotlin.reflect", "typeOf")
}
+ val scopedClientCall by lazy {
+ namedFunction("kotlinx.rpc.internal", "scopedClientCall")
+ }
+
val lazy by lazy {
namedFunction("kotlin", "lazy") {
it.owner.valueParameters.size == 1
@@ -197,14 +193,6 @@ internal class RPCIrContext(
namedFunction("kotlin", "to")
}
- val withContext by lazy {
- namedFunction("kotlinx.coroutines", "withContext")
- }
-
- val job by lazy {
- namedFunction("kotlinx.coroutines", "Job")
- }
-
private fun IrClassSymbol.namedFunction(name: String): IrSimpleFunction {
return owner.functions.single { it.name.asString() == name }
}
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
index 899644a7..696f3752 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
@@ -19,7 +19,7 @@ internal class RPCIrServiceProcessor(
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
override fun visitClass(declaration: IrClass, context: RPCIrContext): IrStatement {
if (declaration.isInterface &&
- // data.rpc is resolved lazily, so first check is rather heuristic
+ // context.rpc is resolved lazily, so first check is rather heuristic
declaration.maybeRPC() &&
declaration.superTypes.contains(context.rpc.typeWith())
) {
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
index 1d76ba0d..826284f9 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
+++ b/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
@@ -5,7 +5,6 @@
package kotlinx.rpc.codegen.extension
import kotlinx.rpc.codegen.VersionSpecificApi
-import org.jetbrains.kotlin.backend.common.descriptors.synthesizedString
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.backend.jvm.functionByName
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
@@ -25,8 +24,6 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.types.*
-import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
-import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames
@@ -35,7 +32,8 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
import kotlin.properties.Delegates
const val STUB_SUFFIX = "Stub"
-private const val CLIENT_PROPERTY = "client"
+private const val CLIENT_PROPERTY = "__rpc_client"
+private const val STUB_ID_PROPERTY = "__rpc_stub_id"
private const val METHOD_CLASS_SUFFIX_PROPERTY = "RPCData"
private const val METHOD_NAMES_PROPERTY = "methodNames"
private const val METHOD_TYPE_OF_FUNCTION = "methodTypeOf"
@@ -76,12 +74,13 @@ internal class RPCStubGenerator(
}
private var clientValueParameter: IrValueParameter by Delegates.notNull()
+ private var stubIdValueParameter: IrValueParameter by Delegates.notNull()
/**
* Constructor of a stub service:
*
* ```kotlin
- * class MyServiceStub(private val client: RPCClient) : MyService
+ * class MyServiceStub(private val __rpc_stub_id: Long, private val __rpc_client: RPCClient) : MyService
* ```
*/
private fun IrClass.generateStubConstructor() {
@@ -89,6 +88,11 @@ internal class RPCStubGenerator(
name = this@generateStubConstructor.name
isPrimary = true
}.apply {
+ stubIdValueParameter = addValueParameter {
+ name = Name.identifier(STUB_ID_PROPERTY)
+ type = ctx.irBuiltIns.longType
+ }
+
clientValueParameter = addValueParameter {
name = Name.identifier(CLIENT_PROPERTY)
type = ctx.rpcClient.defaultType
@@ -118,6 +122,8 @@ internal class RPCStubGenerator(
}
private fun IrClass.generateProperties() {
+ stubIdProperty()
+
clientProperty()
coroutineContextProperty()
@@ -127,37 +133,58 @@ internal class RPCStubGenerator(
}
}
+ private var stubIdProperty: IrProperty by Delegates.notNull()
+
+ /**
+ * __rpc_stub_id property from the constructor
+ *
+ * ```kotlin
+ * class MyServiceStub(private val __rpc_stub_id: Long, private val __rpc_client: RPCClient) : MyService
+ * ```
+ */
+ private fun IrClass.stubIdProperty() {
+ stubIdProperty = constructorProperty(STUB_ID_PROPERTY, ctx.irBuiltIns.longType, stubIdValueParameter)
+ }
+
private var clientProperty: IrProperty by Delegates.notNull()
/**
- * Client property from the constructor
+ * __rpc_client property from the constructor
*
* ```kotlin
- * class MyServiceStub(private val client: RPCClient) : MyService
+ * class MyServiceStub(private val __rpc_stub_id: Long, private val __rpc_client: RPCClient) : MyService
* ```
*/
private fun IrClass.clientProperty() {
- clientProperty = addProperty {
- name = Name.identifier(CLIENT_PROPERTY)
+ clientProperty = constructorProperty(CLIENT_PROPERTY, ctx.rpcClient.defaultType, clientValueParameter)
+ }
+
+ private fun IrClass.constructorProperty(
+ propertyName: String,
+ propertyType: IrType,
+ valueParameter: IrValueParameter,
+ ): IrProperty {
+ return addProperty {
+ name = Name.identifier(propertyName)
visibility = DescriptorVisibilities.PRIVATE
}.apply {
addBackingFieldUtil {
visibility = DescriptorVisibilities.PRIVATE
- type = ctx.rpcClient.defaultType
+ type = propertyType
isFinal = true
}.apply {
initializer = factory.createExpressionBody(
IrGetValueImpl(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
- type = clientValueParameter.type,
- symbol = clientValueParameter.symbol,
+ type = valueParameter.type,
+ symbol = valueParameter.symbol,
origin = IrStatementOrigin.INITIALIZE_PROPERTY_FROM_PARAMETER,
)
)
}
- addDefaultGetter(this@clientProperty, ctx.irBuiltIns) {
+ addDefaultGetter(this@constructorProperty, ctx.irBuiltIns) {
visibility = DescriptorVisibilities.PRIVATE
}
}
@@ -169,7 +196,7 @@ internal class RPCStubGenerator(
* `coroutineContext` property from `RPC` interface
*
* ```kotlin
- * final override val coroutineContext: CoroutineContext = client.coroutineContext + Job()
+ * final override val coroutineContext: CoroutineContext = __rpc_client.provideStubContext(__rpc_stub_id)
* ```
*/
private fun IrClass.coroutineContextProperty() {
@@ -186,46 +213,19 @@ internal class RPCStubGenerator(
isFinal = true
}.apply {
val coroutineContextClass = ctx.coroutineContext.owner
- val plusFunction = coroutineContextClass.getSimpleFunction(OperatorNameConventions.PLUS.identifier)
- ?: error("Expected to find 'plus' function in 'kotlin.coroutines.CoroutineContext'")
initializer = factory.createExpressionBody(
IrCallImpl(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
type = coroutineContextClass.typeWith(),
- symbol = plusFunction,
- origin = IrStatementOrigin.PLUS,
+ symbol = ctx.functions.provideStubContext.symbol,
valueArgumentsCount = 1,
typeArgumentsCount = 0,
).apply {
- val contextGetter = ctx.properties.rpcClientCoroutineContext.getter
- ?: error("Expected getter for 'coroutineContext' property in RPCClient")
+ dispatchReceiver = irCallProperty(stubClass, clientProperty)
- dispatchReceiver = IrCallImpl(
- startOffset = UNDEFINED_OFFSET,
- endOffset = UNDEFINED_OFFSET,
- type = coroutineContextClass.typeWith(),
- symbol = contextGetter.symbol,
- origin = IrStatementOrigin.GET_PROPERTY,
- valueArgumentsCount = contextGetter.valueParameters.size,
- typeArgumentsCount = contextGetter.typeParameters.size,
- ).apply {
- dispatchReceiver = irCallProperty(stubClass, clientProperty)
- }
-
- val job = IrCallImpl(
- startOffset = UNDEFINED_OFFSET,
- endOffset = UNDEFINED_OFFSET,
- type = ctx.completableJob.defaultType,
- symbol = ctx.functions.job,
- valueArgumentsCount = 1,
- typeArgumentsCount = 0,
- ).apply {
- putValueArgument(0, null)
- }
-
- putValueArgument(0, job)
+ putValueArgument(0, irCallProperty(stubClass, stubIdProperty))
}
)
}
@@ -250,7 +250,8 @@ internal class RPCStubGenerator(
* ``` kotlin
* final override val : by lazy {
* client.registerFlowField(
- * RPCField("", "", typeOf<>())
+ * this, // CoroutineScope
+ * RPCField("", __rpc_stub_id, "", typeOf<>())
* )
* }
* ```
@@ -260,7 +261,8 @@ internal class RPCStubGenerator(
* ```kotlin
* final override val : =
* client.registerFlowField(
- * RPCField("", "", typeOf<>())
+ * this, // CoroutineScope
+ * RPCField("", __rpc_stub_id, "", typeOf<>())
* )
* ```
*
@@ -270,7 +272,12 @@ internal class RPCStubGenerator(
* - `` - [ServiceDeclaration.FlowField.Kind]
* - `` - FQ name of the RPC service
*/
- @Suppress("detekt.NestedBlockDepth", "detekt.LongMethod", "detekt.CyclomaticComplexMethod")
+ @Suppress(
+ "detekt.NestedBlockDepth",
+ "detekt.LongMethod",
+ "detekt.CyclomaticComplexMethod",
+ "detekt.MagicNumber",
+ )
private fun IrClass.rpcFlowField(field: ServiceDeclaration.FlowField) {
val isLazy = !field.property.hasAnnotation(ctx.rpcEagerFieldAnnotation)
@@ -303,11 +310,21 @@ internal class RPCStubGenerator(
type = fieldType,
symbol = registerFunction,
typeArgumentsCount = 1,
- valueArgumentsCount = 1,
+ valueArgumentsCount = 2,
).apply {
dispatchReceiver = irCallProperty(stubClass, clientProperty)
putTypeArgument(0, fieldTypeParameter.typeOrFail)
+ putValueArgument(
+ index = 0,
+ valueArgument = IrGetValueImpl(
+ startOffset = UNDEFINED_OFFSET,
+ endOffset = UNDEFINED_OFFSET,
+ type = ctx.coroutineScope.defaultType,
+ symbol = stubClassThisReceiver.symbol,
+ ),
+ )
+
val fieldArgument = IrConstructorCallImpl(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
@@ -315,10 +332,11 @@ internal class RPCStubGenerator(
symbol = ctx.rpcField.constructors.single(),
typeArgumentsCount = 0,
constructorTypeArgumentsCount = 0,
- valueArgumentsCount = 3,
+ valueArgumentsCount = 4,
).apply {
putValueArgument(0, stringConst(declaration.service.kotlinFqName.asString()))
- putValueArgument(1, stringConst(field.property.name.asString()))
+ putValueArgument(1, irCallProperty(stubClass, stubIdProperty))
+ putValueArgument(2, stringConst(field.property.name.asString()))
val typeOfCall = IrCallImpl(
startOffset = UNDEFINED_OFFSET,
@@ -331,10 +349,10 @@ internal class RPCStubGenerator(
putTypeArgument(0, fieldType)
}
- putValueArgument(2, typeOfCall)
+ putValueArgument(3, typeOfCall)
}
- putValueArgument(0, fieldArgument)
+ putValueArgument(1, fieldArgument)
}
if (!isLazy) {
@@ -489,9 +507,10 @@ internal class RPCStubGenerator(
*
* ```kotlin
* final override suspend fun (): {
- * return withContext(coroutineContext) {
- * client.call(RPCCall(
+ * return scopedClientCall(this) { // this: CoroutineScope
+ * __rpc_client.call(RPCCall(
* "",
+ * __rpc_stub_id,
* "",
* RPCCall.Type.Method,
* (()|),
@@ -550,41 +569,16 @@ internal class RPCStubGenerator(
body = irBuilder(symbol).irBlockBody {
+irReturn(
irCall(
- callee = ctx.functions.withContext,
+ callee = ctx.functions.scopedClientCall,
type = method.function.returnType,
).apply {
putTypeArgument(0, method.function.returnType)
- putValueArgument(
- index = 0,
- valueArgument = irCallProperty(
- clazz = stubClass,
- property = coroutineContextProperty,
- symbol = functionThisReceiver.symbol,
- )
- )
+ putValueArgument(0, irGet(ctx.coroutineScope.defaultType, functionThisReceiver.symbol))
// suspend lambda
// it's type is not available at runtime, but in fact exists
- val lambdaType = IrSimpleTypeImpl(
- ctx.suspendFunction1,
- SimpleTypeNullability.NOT_SPECIFIED,
- listOf(
- makeTypeProjection(ctx.coroutineScope.defaultType, Variance.INVARIANT),
- makeTypeProjection(method.function.returnType, Variance.INVARIANT),
- ),
- listOf(
- IrConstructorCallImpl(
- startOffset = UNDEFINED_OFFSET,
- endOffset = UNDEFINED_OFFSET,
- type = ctx.extensionFunctionType.defaultType,
- symbol = ctx.extensionFunctionType.constructors.single(),
- typeArgumentsCount = 0,
- constructorTypeArgumentsCount = 0,
- valueArgumentsCount = 0,
- ),
- ),
- )
+ val lambdaType = ctx.suspendFunction0.typeWith(method.function.returnType)
val functionLambda = factory.buildFun {
origin = IrDeclarationOrigin.LOCAL_FUNCTION_FOR_LAMBDA
@@ -596,13 +590,6 @@ internal class RPCStubGenerator(
}.apply {
parent = declaredFunction
- vsApi {
- addExtensionReceiverVS(ctx.coroutineScope.defaultType)
- }.apply {
- // this name is picked up from the dump of test data
- name = Name.identifier("this".synthesizedString + "withContext".synthesizedString)
- }
-
body = irBuilder(symbol).irBlockBody {
val call = irRPCMethodClientCall(
method = method,
@@ -639,8 +626,9 @@ internal class RPCStubGenerator(
* Part of [generateRpcMethod] that generates next call:
*
* ```kotlin
- * client.call(RPCCall(
+ * __rpc_client.call(RPCCall(
* "",
+ * __rpc_stub_id,
* "",
* RPCCall.Type.Method,
* (()|),
@@ -685,11 +673,16 @@ internal class RPCStubGenerator(
putValueArgument(
index = 1,
- valueArgument = stringConst(method.function.name.asString()),
+ valueArgument = irCallProperty(stubClass, stubIdProperty, symbol = functionThisReceiver.symbol),
)
putValueArgument(
index = 2,
+ valueArgument = stringConst(method.function.name.asString()),
+ )
+
+ putValueArgument(
+ index = 3,
valueArgument = IrGetEnumValueImpl(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
@@ -714,10 +707,10 @@ internal class RPCStubGenerator(
}
}
- putValueArgument(3, dataParameter)
+ putValueArgument(4, dataParameter)
putValueArgument(
- index = 4,
+ index = 5,
valueArgument = irCall(
ctx.functions.typeOf,
).apply {
@@ -726,7 +719,7 @@ internal class RPCStubGenerator(
)
putValueArgument(
- index = 5,
+ index = 6,
valueArgument = irCall(
ctx.functions.typeOf,
).apply {
@@ -996,8 +989,8 @@ internal class RPCStubGenerator(
* Factory method for creating a new instance of RPC service
*
* ```kotlin
- * final override fun withClient(client: RPCClient): MyService {
- * return MyServiceStub(client)
+ * final override fun withClient(serviceId: Long, client: RPCClient): MyService {
+ * return MyServiceStub(serviceId, client)
* }
* ```
*/
@@ -1014,6 +1007,11 @@ internal class RPCStubGenerator(
stubCompanionObjectThisReceiver.copyToVS(this@apply, origin = IrDeclarationOrigin.DEFINED)
}
+ val serviceId = addValueParameter {
+ name = Name.identifier("serviceId")
+ type = ctx.irBuiltIns.longType
+ }
+
val client = addValueParameter {
name = Name.identifier("client")
type = ctx.rpcClient.defaultType
@@ -1025,7 +1023,8 @@ internal class RPCStubGenerator(
callee = stubClass.constructors.single().symbol,
typeArguments = emptyList(),
).apply {
- putValueArgument(0, irGet(client))
+ putValueArgument(0, irGet(serviceId))
+ putValueArgument(1, irGet(client))
}
)
}
@@ -1033,7 +1032,7 @@ internal class RPCStubGenerator(
}
/**
- * Function for obtaining a list of all RPC fields in a given service as [RPCDeferredField<*>]
+ * Function for getting a list of all RPC fields in a given service as [RPCDeferredField<*>]
*
* ```kotlin
* final override fun rpcFields(service: MyService): List> {
diff --git a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/KRPCClient.kt b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/KRPCClient.kt
index e2b02446..0e154d59 100644
--- a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/KRPCClient.kt
+++ b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/KRPCClient.kt
@@ -15,13 +15,11 @@ import kotlinx.rpc.client.internal.RPCClientConnector
import kotlinx.rpc.client.internal.RPCFlow
import kotlinx.rpc.internal.*
import kotlinx.rpc.internal.logging.CommonLogger
-import kotlinx.rpc.internal.map.ConcurrentHashMap
import kotlinx.rpc.internal.transport.*
import kotlinx.serialization.BinaryFormat
import kotlinx.serialization.SerialFormat
import kotlinx.serialization.StringFormat
import kotlin.coroutines.CoroutineContext
-import kotlin.coroutines.cancellation.CancellationException
import kotlin.reflect.KType
import kotlin.reflect.typeOf
@@ -257,11 +255,7 @@ public abstract class KRPCClient(
val id = callCounter.incrementAndGet()
- val dataTypeString = if (callInfo.data == FieldDataObject) {
- callInfo.dataType.toString()
- } else {
- callInfo.dataType.transformFQNameToCompatible()
- }
+ val dataTypeString = callInfo.dataType.toString()
val callId = "$connectionId:$dataTypeString:$id"
@@ -296,18 +290,6 @@ public abstract class KRPCClient(
val callId: String,
)
- // compatibility transformation
- // from new: org.jetbrains.krpc.some.other.subpackage.MyServiceStub.Empty_RPCData
- // to old: org.jetbrains.krpc.MyServiceClient.Empty_RPCData
- private fun KType.transformFQNameToCompatible(): String {
- return toString()
- .split(".")
- .takeLast(2)
- .joinToString(".")
- .replace("Stub.", "Client.")
- .let { "org.jetbrains.krpc.$it" }
- }
-
private suspend fun executeCall(
callId: String,
streamContext: LazyRPCStreamContext,
diff --git a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/test/ProtocolTest.kt b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/test/ProtocolTest.kt
index f9ccf38e..29f11c9f 100644
--- a/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/test/ProtocolTest.kt
+++ b/krpc/krpc-test/src/jvmTest/kotlin/kotlinx/rpc/test/ProtocolTest.kt
@@ -72,7 +72,7 @@ class ProtocolTest : ProtocolTestBase() {
transport.server.receive()
val serverResponseMessage = RPCTransportMessage.StringMessage(
- "{\"type\":\"org.jetbrains.krpc.RPCMessage.CallSuccess\",\"callId\":\"$connectionId:kotlinx.rpc.ProtocolTestServiceClient.SendRequest_RPCData:1\",\"serviceType\":\"kotlinx.rpc.test.ProtocolTestService\",\"data\":\"{}\"}"
+ "{\"type\":\"org.jetbrains.krpc.RPCMessage.CallSuccess\",\"callId\":\"$connectionId:kotlinx.rpc.test.ProtocolTestServiceStub.SendRequest_RPCData:1\",\"serviceType\":\"kotlinx.rpc.test.ProtocolTestService\",\"data\":\"{}\"}"
)
transport.server.send(serverResponseMessage)
diff --git a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCClientServiceGenerator.kt b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCClientServiceGenerator.kt
index e550fcd4..7272b56e 100644
--- a/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCClientServiceGenerator.kt
+++ b/ksp-plugin/src/main/kotlin/kotlinx/rpc/codegen/RPCClientServiceGenerator.kt
@@ -235,26 +235,21 @@ class RPCClientServiceGenerator(private val codegen: CodeGenerator) {
}
newLine()
- writeLine("override fun withClient(serviceId: Long, client: RPCClient): ${service.fullName} = ${service.simpleName.withClientImplSuffix()}(serviceId, client)")
+ writeLine("override fun withClient(serviceId: Long, client: RPCClient): ${service.fullName} = ${service.simpleName.withStubImplSuffix()}(serviceId, client)")
newLine()
writeLine("override fun methodTypeOf(methodName: String): kotlin.reflect.KType? = methodNames[methodName]")
newLine()
- writeLine("override fun withClient(serviceId: Long, client: RPCClient): ${service.fullName} = ${service.simpleName.withStubImplSuffix()}(client)")
- newLine()
-
writeLine("override fun rpcFields(service: ${service.fullName}): List> {")
with(nested()) {
if (service.fields.isEmpty()) {
writeLine("return emptyList()")
} else {
- write("return listOf(")
- newLine()
+ writeLine("return listOf(")
with(nested()) {
service.fields.forEach {
- write("service.${it.name},")
- newLine()
+ writeLine("service.${it.name},")
}
}
writeLine(") as List>")
diff --git a/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold b/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold
new file mode 100644
index 00000000..cf111516
--- /dev/null
+++ b/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold
@@ -0,0 +1,8 @@
+[Client] [Send] $ {"type":"org.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake","supportedPlugins":[-32767,-32766]}
+[Server] [Receive] $ {"type":"org.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake","supportedPlugins":[-32767,-32766]}
+[Server] [Send] $ {"type":"org.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake","supportedPlugins":[-32767,-32766],"connectionId":1}
+[Client] [Receive] $ {"type":"org.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake","supportedPlugins":[-32767,-32766],"connectionId":1}
+[Client] [Send] $ {"type":"org.jetbrains.krpc.RPCMessage.CallData","callId":"1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.CallException_RPCData:1","serviceType":"org.jetbrains.krpc.test.api.util.SamplingService","method":"callException","callType":"Method","data":"{}","connectionId":1,"serviceId":1}
+[Server] [Receive] $ {"type":"org.jetbrains.krpc.RPCMessage.CallData","callId":"1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.CallException_RPCData:1","serviceType":"org.jetbrains.krpc.test.api.util.SamplingService","method":"callException","callType":"Method","data":"{}","connectionId":1,"serviceId":1}
+[Server] [Send] $ {"type":"org.jetbrains.krpc.RPCMessage.CallException","callId":"1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.CallException_RPCData:1","serviceType":"org.jetbrains.krpc.test.api.util.SamplingService","cause":{"toStringMessage":"java.lang.IllegalStateException: Server exception","message":"Server exception","stacktrace":[],"cause":null,"className":"java.lang.IllegalStateException"},"connectionId":1,"serviceId":1}
+[Client] [Receive] $ {"type":"org.jetbrains.krpc.RPCMessage.CallException","callId":"1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.CallException_RPCData:1","serviceType":"org.jetbrains.krpc.test.api.util.SamplingService","cause":{"toStringMessage":"java.lang.IllegalStateException: Server exception","message":"Server exception","stacktrace":[],"cause":null,"className":"java.lang.IllegalStateException"},"connectionId":1,"serviceId":1}
\ No newline at end of file
diff --git a/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold b/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold
new file mode 100644
index 00000000..dca8a1db
--- /dev/null
+++ b/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold
@@ -0,0 +1,8 @@
+[Client] [Send] $ {"type":"org.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake","supportedPlugins":[-32767,-32766]}
+[Server] [Receive] $ {"type":"org.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake","supportedPlugins":[-32767,-32766]}
+[Server] [Send] $ {"type":"org.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake","supportedPlugins":[-32767,-32766],"connectionId":1}
+[Client] [Receive] $ {"type":"org.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake","supportedPlugins":[-32767,-32766],"connectionId":1}
+[Client] [Send] $ {"type":"org.jetbrains.krpc.RPCMessage.CallData","callId":"1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.Echo_RPCData:1","serviceType":"org.jetbrains.krpc.test.api.util.SamplingService","method":"echo","callType":"Method","data":"{\"arg1\":\"Hello\",\"data\":{\"data\":\"data\"}}","connectionId":1,"serviceId":1}
+[Server] [Receive] $ {"type":"org.jetbrains.krpc.RPCMessage.CallData","callId":"1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.Echo_RPCData:1","serviceType":"org.jetbrains.krpc.test.api.util.SamplingService","method":"echo","callType":"Method","data":"{\"arg1\":\"Hello\",\"data\":{\"data\":\"data\"}}","connectionId":1,"serviceId":1}
+[Server] [Send] $ {"type":"org.jetbrains.krpc.RPCMessage.CallSuccess","callId":"1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.Echo_RPCData:1","serviceType":"org.jetbrains.krpc.test.api.util.SamplingService","data":"{\"data\":\"data\"}","connectionId":1,"serviceId":1}
+[Client] [Receive] $ {"type":"org.jetbrains.krpc.RPCMessage.CallSuccess","callId":"1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.Echo_RPCData:1","serviceType":"org.jetbrains.krpc.test.api.util.SamplingService","data":"{\"data\":\"data\"}","connectionId":1,"serviceId":1}
\ No newline at end of file
diff --git a/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold b/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold
new file mode 100644
index 00000000..730238d7
--- /dev/null
+++ b/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold
@@ -0,0 +1,16 @@
+// decoded: ?Borg.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake????????????????????????
+[Client] [Send] $ 0a426f72672e6a6574627261696e732e6b7270632e696e7465726e616c2e7472616e73706f72742e52504350726f746f636f6c4d6573736167652e48616e647368616b651216088180feffffffffffff01088280feffffffffffff01
+// decoded: ?Borg.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake????????????????????????
+[Server] [Receive] $ 0a426f72672e6a6574627261696e732e6b7270632e696e7465726e616c2e7472616e73706f72742e52504350726f746f636f6c4d6573736167652e48616e647368616b651216088180feffffffffffff01088280feffffffffffff01
+// decoded: ?Borg.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake??????????????????????????
+[Server] [Send] $ 0a426f72672e6a6574627261696e732e6b7270632e696e7465726e616c2e7472616e73706f72742e52504350726f746f636f6c4d6573736167652e48616e647368616b651218088180feffffffffffff01088280feffffffffffff011001
+// decoded: ?Borg.jetbrains.krpc.internal.transport.RPCProtocolMessage.Handshake??????????????????????????
+[Client] [Receive] $ 0a426f72672e6a6574627261696e732e6b7270632e696e7465726e616c2e7472616e73706f72742e52504350726f746f636f6c4d6573736167652e48616e647368616b651218088180feffffffffffff01088280feffffffffffff011001
+// decoded: ??org.jetbrains.krpc.internal.transport.RPCMessage.CallDataBinary????E1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.Echo_RPCData:1?0org.jetbrains.krpc.test.api.util.SamplingService??echo ?*???Hello????data0?8?
+[Client] [Send] $ 0a3f6f72672e6a6574627261696e732e6b7270632e696e7465726e616c2e7472616e73706f72742e5250434d6573736167652e43616c6c4461746142696e6172791296010a45313a6f72672e6a6574627261696e732e6b7270632e746573742e6170692e7574696c2e53616d706c696e6753657276696365537475622e4563686f5f525043446174613a3112306f72672e6a6574627261696e732e6b7270632e746573742e6170692e7574696c2e53616d706c696e67536572766963651a046563686f20002a0f0a0548656c6c6f12060a046461746130013801
+// decoded: ??org.jetbrains.krpc.internal.transport.RPCMessage.CallDataBinary????E1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.Echo_RPCData:1?0org.jetbrains.krpc.test.api.util.SamplingService??echo ?*???Hello????data0?8?
+[Server] [Receive] $ 0a3f6f72672e6a6574627261696e732e6b7270632e696e7465726e616c2e7472616e73706f72742e5250434d6573736167652e43616c6c4461746142696e6172791296010a45313a6f72672e6a6574627261696e732e6b7270632e746573742e6170692e7574696c2e53616d706c696e6753657276696365537475622e4563686f5f525043446174613a3112306f72672e6a6574627261696e732e6b7270632e746573742e6170692e7574696c2e53616d706c696e67536572766963651a046563686f20002a0f0a0548656c6c6f12060a046461746130013801
+// decoded: ?Borg.jetbrains.krpc.internal.transport.RPCMessage.CallSuccessBinary????E1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.Echo_RPCData:1?0org.jetbrains.krpc.test.api.util.SamplingService????data ?(?
+[Server] [Send] $ 0a426f72672e6a6574627261696e732e6b7270632e696e7465726e616c2e7472616e73706f72742e5250434d6573736167652e43616c6c5375636365737342696e6172791285010a45313a6f72672e6a6574627261696e732e6b7270632e746573742e6170692e7574696c2e53616d706c696e6753657276696365537475622e4563686f5f525043446174613a3112306f72672e6a6574627261696e732e6b7270632e746573742e6170692e7574696c2e53616d706c696e67536572766963651a060a046461746120012801
+// decoded: ?Borg.jetbrains.krpc.internal.transport.RPCMessage.CallSuccessBinary????E1:org.jetbrains.krpc.test.api.util.SamplingServiceStub.Echo_RPCData:1?0org.jetbrains.krpc.test.api.util.SamplingService????data ?(?
+[Client] [Receive] $ 0a426f72672e6a6574627261696e732e6b7270632e696e7465726e616c2e7472616e73706f72742e5250434d6573736167652e43616c6c5375636365737342696e6172791285010a45313a6f72672e6a6574627261696e732e6b7270632e746573742e6170692e7574696c2e53616d706c696e6753657276696365537475622e4563686f5f525043446174613a3112306f72672e6a6574627261696e732e6b7270632e746573742e6170692e7574696c2e53616d706c696e67536572766963651a060a046461746120012801
\ No newline at end of file
From 54dee8379a0b6397af0e8784a27f979ac0d763d6 Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Fri, 31 May 2024 13:40:00 +0200
Subject: [PATCH 03/17] Replaced compiler-specific modules with
version-specific source sets (#84)
---
compiler-plugin/build.gradle.kts | 19 ++-
.../compiler-plugin-1_7/build.gradle.kts | 11 --
.../compiler-plugin-1_7_2/build.gradle.kts | 11 --
.../compiler-plugin-1_8/build.gradle.kts | 11 --
.../compiler-plugin-1_9/build.gradle.kts | 11 --
.../compiler-plugin-core/build.gradle.kts | 11 --
compiler-plugin/gradle.properties | 5 -
compiler-plugin/settings.gradle.kts | 1 -
.../rpc/codegen/RPCCompilerPluginCore.kt | 0
.../kotlinx/rpc/codegen/VersionSpecificApi.kt | 0
.../kotlinx/rpc/codegen/extension/IrUtils.kt | 0
.../extension/RPCDeclarationScanner.kt | 0
.../rpc/codegen/extension/RPCIrContext.kt | 0
.../rpc/codegen/extension/RPCIrExtension.kt | 0
.../extension/RPCIrServiceProcessor.kt | 2 +-
.../rpc/codegen/extension/RPCStubGenerator.kt | 5 +
.../codegen/extension/ServiceDeclaration.kt | 0
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
...otlin.compiler.plugin.CommandLineProcessor | 0
...in.compiler.plugin.CompilerPluginRegistrar | 0
...otlin.compiler.plugin.CommandLineProcessor | 0
....kotlin.compiler.plugin.ComponentRegistrar | 0
...otlin.compiler.plugin.CommandLineProcessor | 0
....kotlin.compiler.plugin.ComponentRegistrar | 0
...otlin.compiler.plugin.CommandLineProcessor | 0
...in.compiler.plugin.CompilerPluginRegistrar | 0
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
.../compiler-specific-module.gradle.kts | 135 ++++++++++-------
.../src/main/kotlin/dependency.kt | 18 +++
.../src/main/kotlin/util.kt | 25 +++
.../src/main/kotlin/version.kt | 44 ++++++
.../kotlin/kotlinx/rpc/RPCGradlePlugin.kt | 2 +-
.../kotlin/kotlinx/rpc/compilerPlugins.kt | 57 ++++---
...piler-specific-modules.settings.gradle.kts | 142 ------------------
.../0_1_1_SNAPSHOT/callException_json.gold | 0
.../wire_dumps/0_1_1_SNAPSHOT/echo_json.gold | 0
.../0_1_1_SNAPSHOT/echo_protobuf.gold | 0
settings.gradle.kts | 1 -
.../codegen-tests-mpp/build.gradle.kts | 4 +
45 files changed, 214 insertions(+), 301 deletions(-)
delete mode 100644 compiler-plugin/compiler-plugin-1_7/build.gradle.kts
delete mode 100644 compiler-plugin/compiler-plugin-1_7_2/build.gradle.kts
delete mode 100644 compiler-plugin/compiler-plugin-1_8/build.gradle.kts
delete mode 100644 compiler-plugin/compiler-plugin-1_9/build.gradle.kts
delete mode 100644 compiler-plugin/compiler-plugin-core/build.gradle.kts
delete mode 100644 compiler-plugin/gradle.properties
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt (100%)
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/VersionSpecificApi.kt (100%)
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/extension/IrUtils.kt (100%)
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt (100%)
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/extension/RPCIrContext.kt (100%)
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/extension/RPCIrExtension.kt (100%)
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt (95%)
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt (99%)
rename compiler-plugin/{compiler-plugin-core/src/main/kotlin => src/main/core}/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt (100%)
rename compiler-plugin/{compiler-plugin-1_9/src/main/kotlin => src/main/latest}/kotlinx/rpc/codegen/RPCCompilerPlugin.kt (100%)
rename compiler-plugin/{compiler-plugin-1_9/src/main/kotlin => src/main/latest}/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
rename compiler-plugin/{compiler-plugin-1_7/src/main/resources => src/main/resources/latest}/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/{compiler-plugin-1_8/src/main/resources => src/main/resources/latest}/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar (100%)
rename compiler-plugin/{compiler-plugin-1_7_2/src/main/resources => src/main/resources/v_1_7}/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/{compiler-plugin-1_7/src/main/resources => src/main/resources/v_1_7}/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar (100%)
rename compiler-plugin/{compiler-plugin-1_8/src/main/resources => src/main/resources/v_1_7_2}/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/{compiler-plugin-1_7_2/src/main/resources => src/main/resources/v_1_7_2}/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar (100%)
rename compiler-plugin/{compiler-plugin-1_9/src/main/resources => src/main/resources/v_1_8}/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/{compiler-plugin-1_9/src/main/resources => src/main/resources/v_1_8}/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar (100%)
rename compiler-plugin/{compiler-plugin-1_7/src/main/kotlin => src/main/v_1_7}/kotlinx/rpc/codegen/RPCCompilerPlugin.kt (100%)
rename compiler-plugin/{compiler-plugin-1_7/src/main/kotlin => src/main/v_1_7}/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
rename compiler-plugin/{compiler-plugin-1_7_2/src/main/kotlin => src/main/v_1_7_2}/kotlinx/rpc/codegen/RPCCompilerPlugin.kt (100%)
rename compiler-plugin/{compiler-plugin-1_7_2/src/main/kotlin => src/main/v_1_7_2}/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
rename compiler-plugin/{compiler-plugin-1_8/src/main/kotlin => src/main/v_1_8}/kotlinx/rpc/codegen/RPCCompilerPlugin.kt (100%)
rename compiler-plugin/{compiler-plugin-1_8/src/main/kotlin => src/main/v_1_8}/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
create mode 100644 gradle-conventions/compiler-specific-module/src/main/kotlin/dependency.kt
create mode 100644 gradle-conventions/compiler-specific-module/src/main/kotlin/util.kt
create mode 100644 gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt
delete mode 100644 gradle-settings-conventions/src/main/kotlin/compiler-specific-modules.settings.gradle.kts
rename {runtime => krpc/krpc-test}/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold (100%)
rename {runtime => krpc/krpc-test}/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold (100%)
rename {runtime => krpc/krpc-test}/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold (100%)
diff --git a/compiler-plugin/build.gradle.kts b/compiler-plugin/build.gradle.kts
index 04ea1d47..196cd9f1 100644
--- a/compiler-plugin/build.gradle.kts
+++ b/compiler-plugin/build.gradle.kts
@@ -3,9 +3,13 @@
*/
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
-import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
import util.configureMetaTasks
+plugins {
+ alias(libs.plugins.conventions.jvm)
+ alias(libs.plugins.compiler.specific.module)
+}
+
val kotlinVersion: String by extra
val rpcVersion: String = libs.versions.kotlinx.rpc.get()
@@ -14,17 +18,12 @@ allprojects {
version = "$kotlinVersion-$rpcVersion"
}
-plugins {
- alias(libs.plugins.conventions.jvm)
- alias(libs.plugins.compiler.specific.module)
+kotlin {
+ explicitApi = ExplicitApiMode.Disabled
}
-subprojects {
- afterEvaluate {
- configure {
- explicitApi = ExplicitApiMode.Disabled
- }
- }
+dependencies {
+ compileOnly(libs.kotlin.compiler.embeddable)
}
configureMetaTasks("cleanTest", "test")
diff --git a/compiler-plugin/compiler-plugin-1_7/build.gradle.kts b/compiler-plugin/compiler-plugin-1_7/build.gradle.kts
deleted file mode 100644
index df08eab9..00000000
--- a/compiler-plugin/compiler-plugin-1_7/build.gradle.kts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
- */
-
-plugins {
- alias(libs.plugins.conventions.jvm)
-}
-
-dependencies {
- compileOnly(libs.kotlin.compiler.embeddable)
-}
diff --git a/compiler-plugin/compiler-plugin-1_7_2/build.gradle.kts b/compiler-plugin/compiler-plugin-1_7_2/build.gradle.kts
deleted file mode 100644
index df08eab9..00000000
--- a/compiler-plugin/compiler-plugin-1_7_2/build.gradle.kts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
- */
-
-plugins {
- alias(libs.plugins.conventions.jvm)
-}
-
-dependencies {
- compileOnly(libs.kotlin.compiler.embeddable)
-}
diff --git a/compiler-plugin/compiler-plugin-1_8/build.gradle.kts b/compiler-plugin/compiler-plugin-1_8/build.gradle.kts
deleted file mode 100644
index df08eab9..00000000
--- a/compiler-plugin/compiler-plugin-1_8/build.gradle.kts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
- */
-
-plugins {
- alias(libs.plugins.conventions.jvm)
-}
-
-dependencies {
- compileOnly(libs.kotlin.compiler.embeddable)
-}
diff --git a/compiler-plugin/compiler-plugin-1_9/build.gradle.kts b/compiler-plugin/compiler-plugin-1_9/build.gradle.kts
deleted file mode 100644
index df08eab9..00000000
--- a/compiler-plugin/compiler-plugin-1_9/build.gradle.kts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
- */
-
-plugins {
- alias(libs.plugins.conventions.jvm)
-}
-
-dependencies {
- compileOnly(libs.kotlin.compiler.embeddable)
-}
diff --git a/compiler-plugin/compiler-plugin-core/build.gradle.kts b/compiler-plugin/compiler-plugin-core/build.gradle.kts
deleted file mode 100644
index df08eab9..00000000
--- a/compiler-plugin/compiler-plugin-core/build.gradle.kts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
- */
-
-plugins {
- alias(libs.plugins.conventions.jvm)
-}
-
-dependencies {
- compileOnly(libs.kotlin.compiler.embeddable)
-}
diff --git a/compiler-plugin/gradle.properties b/compiler-plugin/gradle.properties
deleted file mode 100644
index be31bf3c..00000000
--- a/compiler-plugin/gradle.properties
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
-#
-
-compiler-specific-module=true
diff --git a/compiler-plugin/settings.gradle.kts b/compiler-plugin/settings.gradle.kts
index b24e1cc2..13d26bde 100644
--- a/compiler-plugin/settings.gradle.kts
+++ b/compiler-plugin/settings.gradle.kts
@@ -13,7 +13,6 @@ pluginManagement {
plugins {
id("settings-conventions")
- id("compiler-specific-modules")
}
includeRootAsPublic()
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApi.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApi.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/IrUtils.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/IrUtils.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/IrUtils.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/IrUtils.kt
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrContext.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrExtension.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
similarity index 95%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
index 696f3752..6f7e1e3b 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
+++ b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
@@ -33,6 +33,6 @@ internal class RPCIrServiceProcessor(
private fun processService(service: IrClass, context: RPCIrContext) {
val declaration = RPCDeclarationScanner.scanServiceDeclaration(service, context)
- RPCStubGenerator(declaration, context).generate()
+ RPCStubGenerator(declaration, context, logger).generate()
}
}
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
similarity index 99%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
index 826284f9..7c95932f 100644
--- a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
+++ b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
@@ -7,6 +7,8 @@ package kotlinx.rpc.codegen.extension
import kotlinx.rpc.codegen.VersionSpecificApi
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.backend.jvm.functionByName
+import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -44,6 +46,7 @@ private const val RPC_FIELDS_METHOD = "rpcFields"
internal class RPCStubGenerator(
private val declaration: ServiceDeclaration,
private val ctx: RPCIrContext,
+ private val logger: MessageCollector,
) {
private fun irBuilder(symbol: IrSymbol): DeclarationIrBuilder =
DeclarationIrBuilder(ctx.pluginContext, symbol, symbol.owner.startOffset, symbol.owner.endOffset)
@@ -55,6 +58,8 @@ internal class RPCStubGenerator(
generateStubClass()
addAssociatedObjectAnnotationIfPossible()
+
+ logger.report(CompilerMessageSeverity.WARNING, declaration.service.dump())
}
private fun generateStubClass() {
diff --git a/compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-core/src/main/kotlin/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
rename to compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
diff --git a/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
rename to compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
diff --git a/compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_9/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/compiler-plugin/compiler-plugin-1_7/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/compiler-plugin-1_8/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar b/compiler-plugin/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_8/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
rename to compiler-plugin/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
diff --git a/compiler-plugin/compiler-plugin-1_7_2/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7_2/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/compiler-plugin-1_7/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/compiler-plugin/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
rename to compiler-plugin/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
diff --git a/compiler-plugin/compiler-plugin-1_8/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_8/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/compiler-plugin-1_7_2/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/compiler-plugin/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7_2/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
rename to compiler-plugin/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
diff --git a/compiler-plugin/compiler-plugin-1_9/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_9/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/compiler-plugin-1_9/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar b/compiler-plugin/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_9/src/main/resources/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
rename to compiler-plugin/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
diff --git a/compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
rename to compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
diff --git a/compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
rename to compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
diff --git a/compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_7_2/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
rename to compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
diff --git a/compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/compiler-plugin-1_8/src/main/kotlin/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts b/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
index ea8138ce..96b8ac19 100644
--- a/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
+++ b/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
@@ -2,77 +2,100 @@
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
-import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
+import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
+import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
+import java.nio.file.Files
+import java.nio.file.Path
+
+val kotlinVersion: String by extra
+
+fun NamedDomainObjectContainer.applyCompilerSpecificSourceSets() {
+ forEach { set ->
+ val sourceDirs = set.kotlin.sourceDirectories.toList()
+ val path = sourceDirs.firstOrNull() // one is ok in most cases because we need its parent directory
+ ?: error(
+ "Expected at least one source set dir for '${set.name}' source set (kotlin dir). " +
+ "Review the case and adjust the script"
+ )
+
+ val sourceSetPath = path.toPath().parent
+ if (!Files.exists(sourceSetPath)) {
+ return@forEach
+ }
-// ### Utils ###
+ val core = sourceSetPath.resolve(Const.CORE_SOURCE_SET).toFile()
+
+ // version-specific source sets
+ val vsSets = Files.newDirectoryStream(sourceSetPath).use { it.toList() }.filter {
+ Files.isDirectory(it) && it.name().matches(directoryNameRegex)
+ }.map { it.toFile() }
+
+ // choose 'latest' if there are no more specific ones
+ val mostSpecificApplicable = vsSets.mostSpecificByVersionOrNull(kotlinVersion)
+ ?: vsSets.singleOrNull { it.name == Const.LATEST_SOURCE_SET }
+ ?: run {
+ logger.info("No version specific sources sets, but '${core.name}'")
+ set.kotlin.setSrcDirs(listOf(core)) // 'core' source set instead of 'kotlin'
+ set.configureResources(sourceSetPath, core.name)
+ return@forEach
+ }
-fun capitalize(string: String): String {
- if (string.isEmpty()) {
- return ""
- }
- val firstChar = string[0]
- return string.replaceFirst(firstChar, Character.toTitleCase(firstChar))
-}
+ logger.info(
+ "${project.name}: included version specific source sets: " +
+ "${core.name}, ${mostSpecificApplicable.name}"
+ )
-object CSM {
- const val KOTLIN_MULTIPLATFORM_PLUGIN_ID = "org.jetbrains.kotlin.multiplatform"
- const val KOTLIN_JVM_PLUGIN_ID = "org.jetbrains.kotlin.jvm"
-}
+ set.kotlin.setSrcDirs(listOf(core, mostSpecificApplicable)) // 'core' source set instead of 'kotlin'
+ set.configureResources(sourceSetPath, core.name, mostSpecificApplicable.name)
-val kotlinVersion = getKotlinPluginVersion()
+ val excluded = vsSets.filter { it != mostSpecificApplicable }
+ logger.info("${project.name}: excluded version specific source sets: [${excluded.joinToString { it.name }}]")
+ }
+}
-// ### Plugin Logic ###
-// What happens here, is that root module is being made a complete compile specific module for current version of Kotlin
-// We take -core submodule that contains compiler version independent code, add to it version specific module
-// and the summary is presented to the outer world as a complete module,
-// which is the root module for these two submodules.
-// Root module takes its submodules as `api` gradle configurations, and root's jar will consist of
-// two submodules' artifacts and will be presented to the world as it was always a one complete module.
+fun KotlinSourceSet.configureResources(sourceSetPath: Path, vararg versionNames: String) {
+ val vsResources = sourceSetPath.resolve(Const.RESOURCES).toFile()
+ resources.setSrcDirs(
+ versionNames.map { vsResources.resolve(it) }
+ )
-val rootProjectPrefix = "$name-"
-val coreProjectName = "${rootProjectPrefix}core"
+ // 'resources' property does not work alone in gradle 7.5.1 with kotlin 1.7.0 (no idea why),
+ // so we adjust task contents as well
+ tasks.withType().configureEach {
+ duplicatesStrategy = DuplicatesStrategy.EXCLUDE
-// configurations are available only when kotlin plugin is applied, so we use lazy resolving
-fun Project.lazyDependency(baseConfigurationName: String, notation: Any) {
- val kmpConfigurationName = "commonMain${capitalize(baseConfigurationName)}"
- this.configurations.matching { it.name == kmpConfigurationName }.all {
- this@lazyDependency.dependencies.add(kmpConfigurationName, notation)
+ from(versionNames.map { vsResources.resolve(it) })
+ include { it.file.parentInAllowList(versionNames) }
}
+}
- this.configurations.matching { it.name == baseConfigurationName }.all {
- this@lazyDependency.dependencies.add(baseConfigurationName, notation)
+fun File.parentInAllowList(allowList: Array): Boolean {
+ val parent = toPath().parent?.toFile()
+ // will skip v_1_7 for 1.7.0, as it's parent is resources
+ // but will allow META-INF, as it's parent is v_1_7
+ if (parent?.name in allowList) {
+ return true
}
-}
-fun Project.lazyApi(notation: Any) {
- lazyDependency("api", notation)
+ // allow META-INF contents
+ return untilAllowedParentOrNull(allowList) != null
}
-val root = project
-
-subprojects {
- afterEvaluate {
- println("Compiler-specific module $name, version: $version")
+tailrec fun File.untilAllowedParentOrNull(allowList: Array): File? {
+ if (name in allowList) {
+ return null
}
- when {
- name == coreProjectName -> {
- root.lazyApi(this)
- }
-
- name.startsWith(rootProjectPrefix) -> {
- val semVer = name
- .removePrefix(rootProjectPrefix)
- .replace('_', '.')
+ val parent = toPath().parent?.toFile()
+ return if (parent?.name in allowList) this else parent?.untilAllowedParentOrNull(allowList)
+}
- // resolve compiler specific submodule, for example compiler-plugin-1_7 for Kotlin version 1.7.22
- if (kotlinVersion.startsWith(semVer)) {
- val coreProject = root.subprojects.singleOrNull { it.name == coreProjectName }
- ?: error("Expected to find subproject with name '$coreProjectName'")
- lazyApi(coreProject)
+plugins.withId(Const.KOTLIN_JVM_PLUGIN_ID) {
+ the().sourceSets.applyCompilerSpecificSourceSets()
+}
- root.lazyApi(this)
- }
- }
- }
+plugins.withId(Const.KOTLIN_MULTIPLATFORM_PLUGIN_ID) {
+ the().sourceSets.applyCompilerSpecificSourceSets()
}
+
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/dependency.kt b/gradle-conventions/compiler-specific-module/src/main/kotlin/dependency.kt
new file mode 100644
index 00000000..3e5338ac
--- /dev/null
+++ b/gradle-conventions/compiler-specific-module/src/main/kotlin/dependency.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.
+ */
+
+import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
+import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
+
+/**
+ * Use this to add a specific dependency to a source set, depending on a Kotlin version
+ */
+fun KotlinSourceSet.vsDependencies(
+ vsSourceSetDir: String,
+ configure: KotlinDependencyHandler.() -> Unit,
+) {
+ kotlin.srcDirs.find { it.name == vsSourceSetDir }?.apply {
+ dependencies(configure)
+ }
+}
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/util.kt b/gradle-conventions/compiler-specific-module/src/main/kotlin/util.kt
new file mode 100644
index 00000000..cda3e63f
--- /dev/null
+++ b/gradle-conventions/compiler-specific-module/src/main/kotlin/util.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.
+ */
+
+import java.nio.file.Path
+
+object Const {
+ const val KOTLIN_MULTIPLATFORM_PLUGIN_ID = "org.jetbrains.kotlin.multiplatform"
+ const val KOTLIN_JVM_PLUGIN_ID = "org.jetbrains.kotlin.jvm"
+
+ const val CORE_SOURCE_SET = "core"
+ const val LATEST_SOURCE_SET = "latest"
+
+ const val RESOURCES = "resources"
+}
+
+fun capitalize(string: String): String {
+ if (string.isEmpty()) {
+ return ""
+ }
+ val firstChar = string[0]
+ return string.replaceFirst(firstChar, Character.toTitleCase(firstChar))
+}
+
+fun Path.name() = fileName?.toString().orEmpty()
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt b/gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt
new file mode 100644
index 00000000..c1d2d3fc
--- /dev/null
+++ b/gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+import java.io.File
+
+// Versioning is used to sort version-specific source sets in the 'first comes more specific' order
+// By 'more specific' we mean that '1.7.10' is more specific than '1.7'.
+// So [1.7, 1.7.10, 1.9.10, 1.7.22, 1.9, 1, 1.7.0, latest, 1.8]
+// will be sorted as [1.7.0, 1.7.10, 1.7.22, 1.7, 1.8, 1.9.10, 1.9, 1, latest]
+// It's ok to have version '1'.
+// For example, we may have '1.7' and '1' specific source sets.
+// That would mean that all 1.7.* versions we compile with the '1.7' source set,
+// and 1.8.+ up to 1.9.24 will be with the '1' source set
+class CompilerModuleVersion(fullName: String, prefix: String) : Comparable {
+ // For example, "v_1_7_10" -> "1.7.10"
+ val version = fullName
+ .removePrefix(prefix)
+ .replace('_', '.')
+
+ override fun compareTo(other: CompilerModuleVersion): Int {
+ return when {
+ version.length == other.version.length -> version.compareTo(other.version)
+ version.length < other.version.length -> 1
+ else -> -1
+ }
+ }
+}
+
+fun Collection.mostSpecificByVersionOrNull(kotlinVersion: String): File? {
+ return map { it to CompilerModuleVersion(it.name, "v_") }
+ .sortedBy { (_, semVer) -> semVer }
+ .firstOrNull { (_, semVer) ->
+ kotlinVersion.startsWith(semVer.version)
+ }?.first
+}
+
+// matches:
+// - latest
+// - v_1
+// - v_1_9
+// - v_1_9_2
+// - v_1_9_24
+val directoryNameRegex = "^(latest|v(_\\d){1,3}\\d?)$".toRegex()
diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
index 65058afa..4073a5a4 100644
--- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
+++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
@@ -32,7 +32,7 @@ class RPCGradlePlugin : Plugin {
private fun applyCompilerPlugin(target: Project) {
target.plugins.apply(CompilerPluginCore::class.java)
- target.plugins.apply(compilerPluginForKotlin(kotlinVersion))
+// target.plugins.apply(compilerPluginForKotlin(kotlinVersion))
}
private fun applyKspPlugin(target: Project, config: RPCConfig) {
diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
index 1007bef3..dff89ba9 100644
--- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
+++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
@@ -6,37 +6,36 @@
package kotlinx.rpc
-import org.gradle.api.Plugin
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin
class CompilerPluginCore : KotlinCompilerPluginSupportPlugin by compilerPlugin({
- pluginSuffix = "-core"
+// pluginSuffix = "-core"
})
-class CompilerPlugin1_9 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
- pluginSuffix = "-1_9"
-})
-
-class CompilerPlugin1_8 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
- pluginSuffix = "-1_8"
-})
-
-class CompilerPlugin1_7_2 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
- pluginSuffix = "-1_7_2"
-})
-
-class CompilerPlugin1_7 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
- pluginSuffix = "-1_7"
-})
-
-// Transitive dependencies do not work for Kotlin/Native
-// https://youtrack.jetbrains.com/issue/KT-53477/Native-Gradle-plugin-doesnt-add-compiler-plugin-transitive-dependencies-to-compiler-plugin-classpath
-fun compilerPluginForKotlin(kotlin: String): Class> {
- return when {
- kotlin == "1.7.0" || kotlin == "1.7.10" -> CompilerPlugin1_7::class.java
- kotlin.startsWith("1.7.2") -> CompilerPlugin1_7_2::class.java
- kotlin.startsWith("1.8") -> CompilerPlugin1_8::class.java
- kotlin.startsWith("1.9") -> CompilerPlugin1_9::class.java
- else -> error("Unsupported kotlin version: $kotlin")
- }
-}
+//class CompilerPlugin1_9 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
+// pluginSuffix = "-1_9"
+//})
+//
+//class CompilerPlugin1_8 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
+// pluginSuffix = "-1_8"
+//})
+//
+//class CompilerPlugin1_7_2 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
+// pluginSuffix = "-1_7_2"
+//})
+//
+//class CompilerPlugin1_7 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
+// pluginSuffix = "-1_7"
+//})
+
+//// Transitive dependencies do not work for Kotlin/Native
+//// https://youtrack.jetbrains.com/issue/KT-53477/Native-Gradle-plugin-doesnt-add-compiler-plugin-transitive-dependencies-to-compiler-plugin-classpath
+//fun compilerPluginForKotlin(kotlin: String): Class> {
+// return when {
+// kotlin == "1.7.0" || kotlin == "1.7.10" -> CompilerPlugin1_7::class.java
+// kotlin.startsWith("1.7.2") -> CompilerPlugin1_7_2::class.java
+// kotlin.startsWith("1.8") -> CompilerPlugin1_8::class.java
+// kotlin.startsWith("1.9") -> CompilerPlugin1_9::class.java
+// else -> error("Unsupported kotlin version: $kotlin")
+// }
+//}
diff --git a/gradle-settings-conventions/src/main/kotlin/compiler-specific-modules.settings.gradle.kts b/gradle-settings-conventions/src/main/kotlin/compiler-specific-modules.settings.gradle.kts
deleted file mode 100644
index 8b1c7cb7..00000000
--- a/gradle-settings-conventions/src/main/kotlin/compiler-specific-modules.settings.gradle.kts
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
- */
-
-object CSM {
- const val SETTINGS_FILE = "settings.gradle.kts"
- const val BUILD_FILE = "build.gradle.kts"
- const val PROPERTIES_FILE = "gradle.properties"
-
- const val CSM_PROPERTY_NAME = "compiler-specific-module"
-
- const val KOTLIN_VERSION_EXTRA = "kotlinVersion"
-}
-
-// SemVer is used to sort compiler version specific submodules in the 'first comes more specific' order
-// By 'more specific' we mean that '1.7.10' is more specific than '1.7'.
-// So [1.7, 1.7.10, 1.9.10, 1.7.22, 1.9, 1, 1.7.0, 1.8]
-// will be sorted as [1.7.0, 1.7.10, 1.7.22, 1.7, 1.8, 1.9.10, 1.9, 1]
-// It's ok to have version '1'. For example, we may have '1.7' and '1' specific modules.
-// That would mean, that all 1.7.* versions we compile with '1.7' module, and 1.8.+ up to 1.9.24 will be with '1' module
-class CompilerModuleSemVer(fullName: String, prefix: String) : Comparable {
- // For example, "compiler-plugin-1_7_10" -> "1.7.10"
- val version = fullName
- .removePrefix(prefix)
- .replace('_', '.')
-
- override fun compareTo(other: CompilerModuleSemVer): Int {
- return when {
- version.length == other.version.length -> version.compareTo(other.version)
- version.length < other.version.length -> 1
- else -> -1
- }
- }
-}
-
-// Passed from the `settings-conventions.settings.gradle.kts` plugin
-val kotlinVersion = extra[CSM.KOTLIN_VERSION_EXTRA] as? String
- ?: error("Expected `${CSM.KOTLIN_VERSION_EXTRA}` extra property to be provided by `settings-conventions` plugin")
-
-// dir - root dir for compiler specific module
-// files - list of all files in that directory
-//
-// This function includes exactly two submodules of the root compiler specific module:
-// 1. core submodule
-// 2. version specific submodule that is the best suitable for the current Kotlin compiler version.
-//
-// IMPORTANT: it is expected that the root submodule is already included to the project,
-// otherwise the exception will be thrown
-fun includeCSM(dir: File, files: Array) {
- val rootProjectName = dir.name
-
- val submodules = files.filter {
- it.isDirectory && it.name.startsWith(rootProjectName)
- }.toMutableSet()
-
- val core = submodules.singleOrNull { it.name == "$rootProjectName-core" }
- if (core == null) {
- error("Compiler Specific Module $rootProjectName should have `-core` module defined")
- }
- val compilerSubmodules = submodules - core
-
- val basePath = dir.absoluteFile
- .relativeTo(settingsDir.absoluteFile).path
- .replace(File.separator, ":")
- .takeIf { it.isNotEmpty() }?.let { ":$it" } ?: ""
-
- includePublic("$basePath:$rootProjectName-core")
-
- val prefix = "$rootProjectName-"
-
- val currentCompilerModuleDirName = compilerSubmodules
- .map { it.name to CompilerModuleSemVer(it.name, prefix) }
- // example after sorted: [1.7.0, 1.7.10, 1.7.22, 1.7, 1.8, 1.9.10, 1.9, 1]
- .sortedBy { (_, semVer) -> semVer }
- .firstOrNull { (_, semVer) ->
- kotlinVersion.startsWith(semVer.version)
- }?.first
- ?: error("""
- Unable to find compiler specific submodule for $rootProjectName and Kotlin $kotlinVersion.
- Available modules: ${compilerSubmodules.joinToString { it.name }}
- """.trimIndent())
-
- includePublic("$basePath:$currentCompilerModuleDirName")
-
- gradle.projectsLoaded {
- if (rootProject.name == rootProjectName) {
- return@projectsLoaded
- }
-
- rootProject.subprojects.find { it.name == rootProjectName }
- ?: error("Expected root project '$rootProjectName' to be included to the build manually")
- }
-}
-
-// search through all gradle modules for compiler specific ones
-//
-// IMPORTANT: compiler specific modules MUST NOT have any nested modules other than core and version specific ones,
-// otherwise, they will be skipped
-settingsDir.walkTopDown().onEnter { dir ->
- val isExcluded = dir.name.run {
- startsWith(".") ||
- startsWith("build") ||
- startsWith("src") ||
- equals("gradle") ||
- equals("kotlin-js-store") ||
- equals("karma") ||
- equals("gradle") ||
- equals("sample")
- }
-
- if (isExcluded) {
- return@onEnter false
- }
-
- val files = dir.listFiles() ?: return@onEnter false
- val propertiesFile = files.singleOrNull { it.name == CSM.PROPERTIES_FILE }
-
- when {
- // standalone projects are excluded unless they are root
- files.any { it.name == CSM.SETTINGS_FILE && dir != settingsDir } -> false
-
- // check if it is a gradle module
- propertiesFile != null && files.find { it.name == CSM.BUILD_FILE } != null -> {
- val isCompilerSpecificModule = propertiesFile.readLines(Charsets.UTF_8)
- .singleOrNull { it.startsWith(CSM.CSM_PROPERTY_NAME) }
- ?.substringAfter("=")
- ?.substringBefore("#") // avoid comments
- ?.trim()
- ?.toBoolean()
- ?: return@onEnter true // continue traversing
-
- if (isCompilerSpecificModule) {
- includeCSM(dir, files)
- }
-
- // proper CS module or not, there should not be any nested modules
- false
- }
-
- else -> true // continue traversing
- }
-}.toList()
diff --git a/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold b/krpc/krpc-test/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold
similarity index 100%
rename from runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold
rename to krpc/krpc-test/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/callException_json.gold
diff --git a/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold b/krpc/krpc-test/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold
similarity index 100%
rename from runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold
rename to krpc/krpc-test/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_json.gold
diff --git a/runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold b/krpc/krpc-test/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold
similarity index 100%
rename from runtime/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold
rename to krpc/krpc-test/src/jvmTest/resources/wire_dumps/0_1_1_SNAPSHOT/echo_protobuf.gold
diff --git a/settings.gradle.kts b/settings.gradle.kts
index e3008554..9fc991c9 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -28,7 +28,6 @@ pluginManagement {
plugins {
id("settings-conventions")
- id("compiler-specific-modules")
}
dependencyResolutionManagement {
diff --git a/tests/codegen-tests/codegen-tests-mpp/build.gradle.kts b/tests/codegen-tests/codegen-tests-mpp/build.gradle.kts
index edb053ec..ebfcf33f 100644
--- a/tests/codegen-tests/codegen-tests-mpp/build.gradle.kts
+++ b/tests/codegen-tests/codegen-tests-mpp/build.gradle.kts
@@ -3,6 +3,7 @@
*/
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
+import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
plugins {
alias(libs.plugins.conventions.kmp)
@@ -39,5 +40,8 @@ kotlin {
}
explicitApi = ExplicitApiMode.Disabled
+ compilerOptions {
+ languageVersion.set(KotlinVersion.KOTLIN_2_0)
+ }
}
From e0ce7b855f2d7076181f7b0601674889be8098ea Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Tue, 6 Aug 2024 15:45:21 +0200
Subject: [PATCH 04/17] K2 plugin (#116)
* Introduce K2 plugin
* Update IR backend
* Update to 2.0
* Fix for KT-70132
---
.gitignore | 1 +
compiler-plugin/build.gradle.kts | 2 +
.../compiler-plugin-common/build.gradle.kts | 18 +
.../core/kotlinx/rpc/codegen/common/Names.kt | 29 ++
.../compiler-plugin-k2/build.gradle.kts | 24 +
.../kotlinx/rpc/codegen/FirGenerationKeys.kt | 48 ++
.../rpc/codegen/FirRPCExtensionRegistrar.kt | 19 +
.../rpc/codegen/FirRPCServiceGenerator.kt | 433 ++++++++++++++++++
...erializationFirResolveExtensionDelegate.kt | 31 ++
.../rpc/codegen/serialization/annotation.kt | 44 ++
compiler-plugin/settings.gradle.kts | 3 +
.../kotlinx/rpc/codegen/VersionSpecificApi.kt | 3 +-
.../extension/RPCDeclarationScanner.kt | 23 +-
.../rpc/codegen/extension/RPCIrContext.kt | 19 +-
.../extension/RPCIrServiceProcessor.kt | 11 +-
.../rpc/codegen/extension/RPCStubGenerator.kt | 234 +++++++---
.../codegen/extension/ServiceDeclaration.kt | 2 +-
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 2 +
.../rpc/codegen/VersionSpecificApiImpl.kt | 10 +-
.../rpc/codegen/VersionSpecificApiImpl.kt | 2 +-
.../rpc/codegen/VersionSpecificApiImpl.kt | 2 +-
.../rpc/codegen/VersionSpecificApiImpl.kt | 2 +-
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 36 ++
.../rpc/codegen/VersionSpecificApiImpl.kt | 73 +++
core/build.gradle.kts | 9 +-
.../kotlinx/rpc/internal/ExceptionUtils.kt | 4 +-
.../rpc/internal/RPCMethodClassArguments.kt | 2 +-
.../kotlinx/rpc/internal/WithRPCStubObject.kt | 2 +-
.../rpc/internal/transport/RPCPluginKey.kt | 2 +-
.../kotlinx/rpc/internal/ExceptionUtils.js.kt | 2 +-
.../rpc/internal/WithRPCStubObject.js.kt | 53 ++-
.../rpc/internal/ExceptionUtils.jvm.kt | 2 +-
.../rpc/internal/WithRPCStubObject.jvm.kt | 17 +-
.../rpc/internal/ExceptionUtils.native.kt | 2 +-
.../rpc/internal/WithRPCStubObject.native.kt | 16 +-
.../compiler-specific-module.gradle.kts | 14 +-
.../src/main/kotlin/util/TargetUtils.kt | 9 +-
.../conventions-kotlin-version-jvm.gradle.kts | 5 +-
.../conventions-kotlin-version-kmp.gradle.kts | 5 +-
.../src/main/kotlin/util/CompilerOptions.kt | 11 +-
.../conventions-kotlin-version-jvm.gradle.kts | 5 +-
.../conventions-kotlin-version-kmp.gradle.kts | 5 +-
.../src/main/kotlin/util/CompilerOptions.kt | 11 +-
.../rpc/KotlinCompilerPluginBuilder.kt | 2 +-
.../kotlin/kotlinx/rpc/RPCGradlePlugin.kt | 12 +-
.../kotlin/kotlinx/rpc/compilerPlugins.kt | 36 +-
gradle.properties | 6 +
gradle/kotlin-versions-lookup.csv | 1 +
gradle/libs.versions.toml | 5 +-
.../kotlinx/rpc/client/RPCClientUtils.kt | 9 +-
.../rpc/client/awaitFieldInitialization.kt | 5 +-
.../rpc/server/internal/RPCServiceUtils.kt | 5 +-
.../codegen-tests-mpp/build.gradle.kts | 14 +-
.../src/jsMain/resources/index.html | 14 +
.../kotlinx/rpc/internal/kClassSafeCast.kt | 10 +
55 files changed, 1192 insertions(+), 174 deletions(-)
create mode 100644 compiler-plugin/compiler-plugin-common/build.gradle.kts
create mode 100644 compiler-plugin/compiler-plugin-common/src/main/core/kotlinx/rpc/codegen/common/Names.kt
create mode 100644 compiler-plugin/compiler-plugin-k2/build.gradle.kts
create mode 100644 compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirGenerationKeys.kt
create mode 100644 compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRPCExtensionRegistrar.kt
create mode 100644 compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRPCServiceGenerator.kt
create mode 100644 compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/serialization/SerializationFirResolveExtensionDelegate.kt
create mode 100644 compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/serialization/annotation.kt
create mode 100644 compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
create mode 100644 compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
create mode 100644 tests/codegen-tests/codegen-tests-mpp/src/jsMain/resources/index.html
create mode 100644 utils/src/commonMain/kotlin/kotlinx/rpc/internal/kClassSafeCast.kt
diff --git a/.gitignore b/.gitignore
index 69965f44..caac4238 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@
# Ignore Gradle build output directory
build
+.kotlin
# idea files
.idea/*
diff --git a/compiler-plugin/build.gradle.kts b/compiler-plugin/build.gradle.kts
index 196cd9f1..f64434c4 100644
--- a/compiler-plugin/build.gradle.kts
+++ b/compiler-plugin/build.gradle.kts
@@ -24,6 +24,8 @@ kotlin {
dependencies {
compileOnly(libs.kotlin.compiler.embeddable)
+ implementation(projects.compilerPluginK2)
+ implementation(projects.compilerPluginCommon)
}
configureMetaTasks("cleanTest", "test")
diff --git a/compiler-plugin/compiler-plugin-common/build.gradle.kts b/compiler-plugin/compiler-plugin-common/build.gradle.kts
new file mode 100644
index 00000000..5c1f0a66
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-common/build.gradle.kts
@@ -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.
+ */
+
+import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
+
+plugins {
+ alias(libs.plugins.conventions.jvm)
+ alias(libs.plugins.compiler.specific.module)
+}
+
+kotlin {
+ explicitApi = ExplicitApiMode.Disabled
+}
+
+dependencies {
+ compileOnly(libs.kotlin.compiler.embeddable)
+}
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
new file mode 100644
index 00000000..f01c7bc8
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-common/src/main/core/kotlinx/rpc/codegen/common/Names.kt
@@ -0,0 +1,29 @@
+/*
+ * 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.common
+
+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"))
+
+ val serializableAnnotation = ClassId(FqName("kotlinx.serialization"), Name.identifier("Serializable"))
+ val contextualAnnotation = ClassId(FqName("kotlinx.serialization"), Name.identifier("Contextual"))
+
+ val flow = ClassId(FqName("kotlinx.coroutines.flow"), Name.identifier("Flow"))
+ val sharedFlow = ClassId(FqName("kotlinx.coroutines.flow"), Name.identifier("SharedFlow"))
+ val stateFlow = ClassId(FqName("kotlinx.coroutines.flow"), Name.identifier("StateFlow"))
+}
+
+object RpcNames {
+ val SERVICE_STUB_NAME: Name = Name.identifier("\$rpcServiceStub")
+
+ const val METHOD_CLASS_NAME_SUFFIX = "\$rpcMethod"
+}
+
+val Name.rpcMethodClassName: Name get() = Name.identifier("$identifier${RpcNames.METHOD_CLASS_NAME_SUFFIX}")
+val Name.rpcMethodName: Name get() = Name.identifier(identifier.removeSuffix(RpcNames.METHOD_CLASS_NAME_SUFFIX))
diff --git a/compiler-plugin/compiler-plugin-k2/build.gradle.kts b/compiler-plugin/compiler-plugin-k2/build.gradle.kts
new file mode 100644
index 00000000..342cf67c
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/build.gradle.kts
@@ -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.
+ */
+
+import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
+
+plugins {
+ alias(libs.plugins.conventions.jvm)
+ alias(libs.plugins.compiler.specific.module)
+}
+
+kotlin {
+ explicitApi = ExplicitApiMode.Disabled
+
+ compilerOptions {
+ freeCompilerArgs.add("-Xcontext-receivers")
+ }
+}
+
+dependencies {
+ compileOnly(libs.kotlin.compiler.embeddable)
+ compileOnly(libs.serialization.plugin)
+ implementation(projects.compilerPluginCommon)
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirGenerationKeys.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirGenerationKeys.kt
new file mode 100644
index 00000000..ebe25d34
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirGenerationKeys.kt
@@ -0,0 +1,48 @@
+/*
+ * 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 org.jetbrains.kotlin.GeneratedDeclarationKey
+import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
+import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
+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(
+ private val serviceName: Name,
+ val functions: List>,
+) : GeneratedDeclarationKey() {
+ override fun toString(): String {
+ return "RPCGeneratedStubKey.$serviceName"
+ }
+}
+
+internal val FirBasedSymbol<*>.generatedRpcServiceStubKey: RPCGeneratedStubKey? get() =
+ (origin as? FirDeclarationOrigin.Plugin)?.key as? RPCGeneratedStubKey
+
+internal class RPCGeneratedRpcMethodClassKey(
+ val rpcMethod: FirFunctionSymbol<*>,
+) : GeneratedDeclarationKey() {
+ val isObject = rpcMethod.valueParameterSymbols.isEmpty()
+
+ override fun toString(): String {
+ return "RPCGeneratedRpcMethodClassKey.${rpcMethod.name}"
+ }
+}
+
+internal val FirBasedSymbol<*>.generatedRpcMethodClassKey: RPCGeneratedRpcMethodClassKey? get() =
+ (origin as? FirDeclarationOrigin.Plugin)?.key as? RPCGeneratedRpcMethodClassKey
+
+internal object FirRpcServiceStubCompanionObject : GeneratedDeclarationKey() {
+ override fun toString(): String {
+ return "FirRpcServiceStubCompanionObject"
+ }
+}
+
+internal val FirClassSymbol<*>.isFromSerializationPlugin: Boolean get() {
+ return (origin as? FirDeclarationOrigin.Plugin)?.key is SerializationPluginKey
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRPCExtensionRegistrar.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRPCExtensionRegistrar.kt
new file mode 100644
index 00000000..40de0b36
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRPCExtensionRegistrar.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 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.extensions.FirDeclarationGenerationExtension.Factory as GFactory
+
+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) }
+ }
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRPCServiceGenerator.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRPCServiceGenerator.kt
new file mode 100644
index 00000000..136a0709
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/FirRPCServiceGenerator.kt
@@ -0,0 +1,433 @@
+/*
+ * 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.ClassDeclarations
+import kotlinx.rpc.codegen.common.RpcNames
+import kotlinx.rpc.codegen.common.rpcMethodClassName
+import kotlinx.rpc.codegen.common.rpcMethodName
+import kotlinx.rpc.codegen.serialization.addAnnotation
+import kotlinx.rpc.codegen.serialization.generateCompanionDeclaration
+import kotlinx.rpc.codegen.serialization.generateSerializerImplClass
+import org.jetbrains.kotlin.cli.common.messages.MessageCollector
+import org.jetbrains.kotlin.descriptors.ClassKind
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.descriptors.Visibilities
+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.moduleData
+import org.jetbrains.kotlin.fir.plugin.*
+import org.jetbrains.kotlin.fir.symbols.SymbolInternals
+import org.jetbrains.kotlin.fir.symbols.impl.*
+import org.jetbrains.kotlin.fir.types.*
+import org.jetbrains.kotlin.name.CallableId
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.name.SpecialNames
+import org.jetbrains.kotlin.platform.isJs
+import org.jetbrains.kotlin.platform.isWasm
+import org.jetbrains.kotlin.platform.konan.isNative
+import org.jetbrains.kotlinx.serialization.compiler.fir.SerializationFirResolveExtension
+import org.jetbrains.kotlinx.serialization.compiler.fir.SerializationFirSupertypesExtension
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerialEntityNames
+import org.jetbrains.kotlinx.serialization.compiler.resolve.SerializationPackages
+
+/**
+ * What is happening here:
+ *
+ * ## 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.
+ *
+ * ## Usage of kotlinx.serialization plugin
+ *
+ * Here is one more tricky part.
+ *
+ * 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]
+ *
+ * Not all the methods that we would like to call are public, so we access them via reflection:
+ * - [generateCompanionDeclaration]
+ * - [generateSerializerImplClass]
+ *
+ * This is basically copying the behavior of the actual plugin but isolated only for our generated classes.
+ */
+class FirRPCServiceGenerator(
+ session: FirSession,
+ @Suppress("unused")
+ private val logger: MessageCollector,
+) : FirDeclarationGenerationExtension(session) {
+ private val serializationExtension = SerializationFirResolveExtension(session)
+ private val isJvmOrMetadata = !session.moduleData.platform.run { isJs() || isWasm() || isNative() }
+
+ /**
+ * 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].
+ *
+ * - 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.
+ * 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].
+ * 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,
+ * the serialization plugin treats them like their own serializers,
+ * so no extra nested declarations are necessary.
+ * In the case of classes, serialization requires two additional nested declarations:
+ * [SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT] and [SerialEntityNames.SERIALIZER_CLASS_NAME].
+ */
+ override fun getNestedClassifiersNames(
+ classSymbol: FirClassSymbol<*>,
+ context: NestedClassGenerationContext,
+ ): Set {
+ val rpcServiceStubKey = classSymbol.generatedRpcServiceStubKey
+ val rpcMethodClassKey = classSymbol.generatedRpcMethodClassKey
+
+ return when {
+ rpcMethodClassKey != null -> {
+ when {
+ !rpcMethodClassKey.isObject -> setOf(
+ SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT,
+ SerialEntityNames.SERIALIZER_CLASS_NAME,
+ )
+
+ // otherwise an object is generated instead of a class
+ // serialization plugin has other logic for such declarations
+ else -> emptySet()
+ }
+ }
+
+ rpcServiceStubKey != null -> {
+ rpcServiceStubKey.functions.map { it.name.rpcMethodClassName }.toSet() +
+ SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT
+ }
+
+ classSymbol.isInterface -> {
+ setOf(RpcNames.SERVICE_STUB_NAME)
+ }
+
+ else -> {
+ emptySet()
+ }
+ }
+ }
+
+ /**
+ * Handles class names provided by the [getNestedClassifiersNames] with the same cases.
+ * For service stub classes checks if the generation is necessary (inside [generateRpcServiceStubClass]).
+ */
+ override fun generateNestedClassLikeDeclaration(
+ owner: FirClassSymbol<*>,
+ name: Name,
+ context: NestedClassGenerationContext
+ ): FirClassLikeSymbol<*>? {
+ val rpcServiceStubKey = owner.generatedRpcServiceStubKey
+ return when {
+ rpcServiceStubKey != null && name == SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT -> {
+ generateCompanionObjectForRpcServiceStub(owner)
+ }
+
+ rpcServiceStubKey != null -> {
+ generateRpcMethodClass(owner, name, rpcServiceStubKey)
+ }
+
+ owner.generatedRpcMethodClassKey != null -> {
+ generateNestedClassLikeDeclarationWithSerialization(owner, name)
+ }
+
+ name == RpcNames.SERVICE_STUB_NAME -> {
+ generateRpcServiceStubClass(owner)
+ }
+
+ else -> {
+ error("Cannot run generation for ${owner.classId.createNestedClassId(name).asSingleFqName()}")
+ }
+ }
+ }
+
+ private fun generateCompanionObjectForRpcServiceStub(
+ owner: FirClassSymbol<*>,
+ ): FirClassLikeSymbol<*> {
+ return createCompanionObject(owner, FirRpcServiceStubCompanionObject).symbol
+ }
+
+ /**
+ * Generates method class for the respectful function.
+ * Class is marked `@Serializable` for the backend processing.
+ */
+ private fun generateRpcMethodClass(
+ owner: FirClassSymbol<*>,
+ name: Name,
+ rpcServiceStubKey: RPCGeneratedStubKey,
+ ): FirClassLikeSymbol<*> {
+ val methodName = name.rpcMethodName
+ val rpcMethod = rpcServiceStubKey.functions.single { it.name == methodName }
+ val rpcMethodClassKey = RPCGeneratedRpcMethodClassKey(rpcMethod)
+ val classKind = if (rpcMethodClassKey.isObject) ClassKind.OBJECT else ClassKind.CLASS
+
+ val rpcMethodClass = createNestedClass(
+ owner = owner,
+ name = name,
+ key = rpcMethodClassKey,
+ classKind = classKind,
+ ) {
+ visibility = owner.visibility
+ modality = Modality.FINAL
+ }
+
+ rpcMethodClass.addAnnotation(ClassDeclarations.serializableAnnotation, session)
+
+ /**
+ * Required to pass isSerializableObjectAndNeedsFactory check
+ * from [SerializationFirSupertypesExtension].
+ */
+ if (!isJvmOrMetadata && rpcMethodClassKey.isObject) {
+ rpcMethodClass.replaceSuperTypeRefs(createSerializationFactorySupertype())
+ }
+
+ return rpcMethodClass.symbol
+ }
+
+ /**
+ * Instead of [SerializationFirSupertypesExtension]
+ *
+ * Also, it is not run for Companion objects, as [serializationExtension] does it when needed.
+ */
+ private fun createSerializationFactorySupertype(): List {
+ val serializerFactoryClassId = ClassId(
+ SerializationPackages.internalPackageFqName,
+ SerialEntityNames.SERIALIZER_FACTORY_INTERFACE_NAME,
+ )
+
+ val ref = serializerFactoryClassId
+ .constructClassLikeType(emptyArray(), false)
+ .toFirResolvedTypeRef()
+
+ return listOf(ref)
+ }
+
+ /**
+ * Mirrors [generateNestedClassLikeDeclaration] from [serializationExtension].
+ */
+ private fun generateNestedClassLikeDeclarationWithSerialization(
+ owner: FirClassSymbol<*>,
+ name: Name,
+ ): FirClassLikeSymbol<*>? {
+ if (owner !is FirRegularClassSymbol) {
+ error("Expected ${owner.name} to be FirRegularClassSymbol")
+ }
+
+ return when (name) {
+ SpecialNames.DEFAULT_NAME_FOR_COMPANION_OBJECT -> serializationExtension.generateCompanionDeclaration(owner)
+ SerialEntityNames.SERIALIZER_CLASS_NAME -> serializationExtension.generateSerializerImplClass(owner)
+ else -> error("Can't generate class ${owner.classId.createNestedClassId(name).asSingleFqName()}")
+ }
+ }
+
+ /**
+ * 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.
+ * 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()
+ .map { it.symbol }
+
+ return createNestedClass(owner, RpcNames.SERVICE_STUB_NAME, RPCGeneratedStubKey(owner.name, functions)) {
+ visibility = owner.visibility
+ modality = Modality.FINAL
+ }.symbol
+ }
+
+ override fun getCallableNamesForClass(classSymbol: FirClassSymbol<*>, context: MemberGenerationContext): Set {
+ val rpcMethodClassKey = classSymbol.generatedRpcMethodClassKey
+
+ return when {
+ rpcMethodClassKey != null -> {
+ getCallableNamesForRpcMethodClass(classSymbol, context, rpcMethodClassKey)
+ }
+
+ classSymbol.isFromSerializationPlugin -> {
+ serializationExtension.getCallableNamesForClass(classSymbol, context)
+ }
+
+ else -> {
+ emptySet()
+ }
+ }
+ }
+
+ /**
+ * If the method does not 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.
+ */
+ private fun getCallableNamesForRpcMethodClass(
+ classSymbol: FirClassSymbol<*>,
+ context: MemberGenerationContext,
+ rpcMethodClassKey: RPCGeneratedRpcMethodClassKey,
+ ): Set {
+ return if (rpcMethodClassKey.isObject) {
+ // add .serializer() method for a serializable object
+ serializationExtension.getCallableNamesForClass(classSymbol, context)
+ } else {
+ rpcMethodClassKey.rpcMethod.valueParameterSymbols.map { it.name }.toSet()
+ } + SpecialNames.INIT
+
+ // ^ init is necessary either way, as serialization does not add it for a serializable object
+ }
+
+ override fun generateConstructors(context: MemberGenerationContext): List {
+ val rpcMethodClassKey = context.owner.generatedRpcMethodClassKey
+ return when {
+ rpcMethodClassKey != null -> generateConstructorsForRpcMethodClass(context, rpcMethodClassKey)
+ context.owner.isFromSerializationPlugin -> serializationExtension.generateConstructors(context)
+ else -> emptyList()
+ }
+ }
+
+ /**
+ * An object needs only a default private constructor.
+ *
+ * A regular class constructor requires also value parameters of the respectful method.
+ */
+ private fun generateConstructorsForRpcMethodClass(
+ context: MemberGenerationContext,
+ rpcMethodClassKey: RPCGeneratedRpcMethodClassKey,
+ ): List {
+ if (rpcMethodClassKey.isObject) {
+ return createDefaultPrivateConstructor(context.owner, rpcMethodClassKey).symbol.let(::listOf)
+ }
+
+ return createConstructor(context.owner, rpcMethodClassKey) {
+ visibility = Visibilities.Public
+
+ rpcMethodClassKey.rpcMethod.valueParameterSymbols.forEach { valueParam ->
+ valueParameter(
+ name = valueParam.name,
+ type = valueParam.resolvedReturnType,
+ )
+ }
+ }.symbol.let(::listOf)
+ }
+
+ override fun generateProperties(
+ callableId: CallableId,
+ context: MemberGenerationContext?
+ ): List {
+ context ?: return emptyList()
+
+ val owner = context.owner
+ val rpcMethodClassKey = owner.generatedRpcMethodClassKey
+
+ return when {
+ rpcMethodClassKey != null -> {
+ generatePropertiesForRpcMethodClass(callableId, owner, rpcMethodClassKey)
+ }
+
+ owner.isFromSerializationPlugin -> {
+ serializationExtension.generateProperties(callableId, context)
+ }
+
+ else -> {
+ emptyList()
+ }
+ }
+ }
+
+ private fun generatePropertiesForRpcMethodClass(
+ callableId: CallableId,
+ owner: FirClassSymbol<*>,
+ rpcMethodClassKey: RPCGeneratedRpcMethodClassKey,
+ ): List {
+ val valueParam = rpcMethodClassKey.rpcMethod.valueParameterSymbols.find {
+ it.name == callableId.callableName
+ } ?: return emptyList()
+
+ return createMemberProperty(
+ owner = owner,
+ key = rpcMethodClassKey,
+ name = callableId.callableName,
+ returnType = valueParam.resolvedReturnType,
+ ).apply {
+ if (valueParam.resolvedReturnType.requiresContextual()) {
+ addAnnotation(ClassDeclarations.contextualAnnotation, session)
+ }
+ }.symbol.let(::listOf)
+ }
+
+ private fun ConeKotlinType.requiresContextual(): Boolean {
+ return when (classId) {
+ ClassDeclarations.flow, ClassDeclarations.sharedFlow, ClassDeclarations.stateFlow -> true
+ else -> false
+ }
+ }
+
+ /**
+ * Processes serialization related cases from [getCallableNamesForClass].
+ */
+ override fun generateFunctions(
+ callableId: CallableId,
+ context: MemberGenerationContext?
+ ): List {
+ val owner = context?.owner ?: return emptyList()
+
+ return when {
+ owner.isFromSerializationPlugin || owner.generatedRpcMethodClassKey?.isObject == true -> {
+ serializationExtension.generateFunctions(callableId, context)
+ }
+
+ else -> {
+ emptyList()
+ }
+ }
+ }
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/serialization/SerializationFirResolveExtensionDelegate.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/serialization/SerializationFirResolveExtensionDelegate.kt
new file mode 100644
index 00000000..45cb79b6
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/serialization/SerializationFirResolveExtensionDelegate.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.serialization
+
+import org.jetbrains.kotlin.fir.symbols.impl.FirClassLikeSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
+import org.jetbrains.kotlinx.serialization.compiler.fir.SerializationFirResolveExtension
+
+internal fun SerializationFirResolveExtension.generateSerializerImplClass(
+ owner: FirRegularClassSymbol,
+): FirClassLikeSymbol<*> {
+ return callPrivateMethod("generateSerializerImplClass", owner)
+}
+
+internal fun SerializationFirResolveExtension.generateCompanionDeclaration(
+ owner: FirRegularClassSymbol,
+): FirRegularClassSymbol? {
+ return callPrivateMethod("generateCompanionDeclaration", owner)
+}
+
+private fun SerializationFirResolveExtension.callPrivateMethod(name: String, arg: Any?): T {
+ val method = this::class.java.declaredMethods.find { it.name == name }
+ ?: error("Expected method with name $name in SerializationFirResolveExtension")
+
+ method.isAccessible = true
+
+ @Suppress("UNCHECKED_CAST")
+ return method.invoke(this, arg) as T
+}
diff --git a/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/serialization/annotation.kt b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/serialization/annotation.kt
new file mode 100644
index 00000000..9f82229e
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-k2/src/main/core/kotlinx/rpc/codegen/serialization/annotation.kt
@@ -0,0 +1,44 @@
+/*
+ * 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.serialization
+
+import org.jetbrains.kotlin.fir.FirAnnotationContainer
+import org.jetbrains.kotlin.fir.FirSession
+import org.jetbrains.kotlin.fir.expressions.buildResolvedArgumentList
+import org.jetbrains.kotlin.fir.expressions.builder.buildAnnotationCall
+import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference
+import org.jetbrains.kotlin.fir.resolve.defaultType
+import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider
+import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
+import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
+import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
+
+fun FirAnnotationContainer.addAnnotation(annotationId: ClassId, session: FirSession) {
+ val annotation = session
+ .symbolProvider
+ .getClassLikeSymbolByClassId(annotationId)
+ as? FirRegularClassSymbol ?: return
+
+ val annotationConstructor = annotation
+ .declarationSymbols
+ .firstIsInstanceOrNull() ?: return
+
+ val annotationCall = buildAnnotationCall {
+ argumentList = buildResolvedArgumentList(null, linkedMapOf())
+ annotationTypeRef = buildResolvedTypeRef {
+ type = annotation.defaultType()
+ }
+ calleeReference = buildResolvedNamedReference {
+ name = annotation.name
+ resolvedSymbol = annotationConstructor
+ }
+
+ containingDeclarationSymbol = annotationConstructor
+ }
+
+ replaceAnnotations(annotations + annotationCall)
+}
diff --git a/compiler-plugin/settings.gradle.kts b/compiler-plugin/settings.gradle.kts
index 13d26bde..2d2a6ddb 100644
--- a/compiler-plugin/settings.gradle.kts
+++ b/compiler-plugin/settings.gradle.kts
@@ -16,3 +16,6 @@ plugins {
}
includeRootAsPublic()
+
+includePublic(":compiler-plugin-k2")
+includePublic(":compiler-plugin-common")
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt
index 2d105c97..95f0da88 100644
--- a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt
+++ b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt
@@ -5,7 +5,6 @@
package kotlinx.rpc.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
-import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
@@ -39,7 +38,7 @@ interface VersionSpecificApi {
origin: IrDeclarationOrigin = IrDeclarationOrigin.DEFINED,
): IrValueParameter
- var IrFieldBuilder.modalityVS: Modality
+ var IrFieldBuilder.isFinalVS: Boolean
var IrCall.originVS: IrStatementOrigin?
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
index c58a5db4..e790bc3b 100644
--- a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
+++ b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
@@ -4,13 +4,13 @@
package kotlinx.rpc.codegen.extension
+import kotlinx.rpc.codegen.common.RpcNames
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.dumpKotlinLike
-import org.jetbrains.kotlin.ir.util.packageFqName
/**
* This class scans user declared RPC service
@@ -21,6 +21,8 @@ import org.jetbrains.kotlin.ir.util.packageFqName
*/
internal object RPCDeclarationScanner {
fun scanServiceDeclaration(service: IrClass, ctx: RPCIrContext): ServiceDeclaration {
+ var stubClass: IrClass? = null
+
val declarations = service.declarations.memoryOptimizedMap { declaration ->
when (declaration) {
is IrSimpleFunction -> {
@@ -30,7 +32,7 @@ internal object RPCDeclarationScanner {
ServiceDeclaration.Method(
function = declaration,
- argumentTypes = declaration.valueParameters.memoryOptimizedMap { param ->
+ arguments = declaration.valueParameters.memoryOptimizedMap { param ->
ServiceDeclaration.Method.Argument(param, param.type)
},
)
@@ -53,20 +55,27 @@ internal object RPCDeclarationScanner {
ServiceDeclaration.FlowField(declaration, flowType)
}
+ is IrClass -> {
+ if (declaration.name == RpcNames.SERVICE_STUB_NAME) {
+ stubClass = declaration
+ return@memoryOptimizedMap null
+ }
+
+ unsupportedDeclaration(service, declaration)
+ }
+
else -> {
unsupportedDeclaration(service, declaration)
}
}
}
- val stubClass = ctx.getIrClassSymbol(
- packageName = service.packageFqName!!.asString(),
- name = "${service.name.asString()}$STUB_SUFFIX",
- )
+ val stubClassNotNull = stubClass
+ ?: error("Expected ${RpcNames.SERVICE_STUB_NAME} nested declaration in ${service.name}")
return ServiceDeclaration(
service = service,
- stubClass = stubClass.owner,
+ stubClass = stubClassNotNull,
methods = declarations.filterIsInstance(),
fields = declarations.filterIsInstance(),
)
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
index 27a4ce03..5bc5b442 100644
--- a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
+++ b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.isVararg
import org.jetbrains.kotlin.ir.util.properties
import org.jetbrains.kotlin.platform.konan.isNative
+import org.jetbrains.kotlin.types.Variance
internal class RPCIrContext(
val pluginContext: IrPluginContext,
@@ -28,6 +29,10 @@ internal class RPCIrContext(
irBuiltIns.anyType.makeNullable()
}
+ val arrayOfAnyNullable by lazy {
+ irBuiltIns.arrayClass.typeWith(anyNullable, Variance.OUT_VARIANCE)
+ }
+
val coroutineScope by lazy {
getIrClassSymbol("kotlinx.coroutines", "CoroutineScope")
}
@@ -114,6 +119,10 @@ internal class RPCIrContext(
getRpcIrClassSymbol("RPCDeferredField", "internal")
}
+ val rpcMethodClassArguments by lazy {
+ getRpcIrClassSymbol("RPCMethodClassArguments", "internal")
+ }
+
fun isJsTarget(): Boolean {
return versionSpecificApi.isJs(pluginContext.platform)
}
@@ -145,10 +154,18 @@ internal class RPCIrContext(
rpcClient.namedFunction("provideStubContext")
}
+ val asArray by lazy {
+ rpcMethodClassArguments.namedFunction("asArray")
+ }
+
val typeOf by lazy {
namedFunction("kotlin.reflect", "typeOf")
}
+ val emptyArray by lazy {
+ namedFunction("kotlin", "emptyArray")
+ }
+
val scopedClientCall by lazy {
namedFunction("kotlinx.rpc.internal", "scopedClientCall")
}
@@ -225,7 +242,7 @@ internal class RPCIrContext(
return getIrClassSymbol("kotlinx.rpc$suffix", name)
}
- fun getIrClassSymbol(packageName: String, name: String): IrClassSymbol {
+ private fun getIrClassSymbol(packageName: String, name: String): IrClassSymbol {
return versionSpecificApi.referenceClass(pluginContext, packageName, name)
?: error("Unable to find symbol. Package: $packageName, name: $name")
}
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
index 6f7e1e3b..6a00fca6 100644
--- a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
+++ b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
@@ -7,8 +7,7 @@ package kotlinx.rpc.codegen.extension
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.classFqName
-import org.jetbrains.kotlin.ir.types.typeWith
+import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -18,19 +17,13 @@ internal class RPCIrServiceProcessor(
) : IrElementTransformer {
@Suppress("PARAMETER_NAME_CHANGED_ON_OVERRIDE")
override fun visitClass(declaration: IrClass, context: RPCIrContext): IrStatement {
- if (declaration.isInterface &&
- // context.rpc is resolved lazily, so first check is rather heuristic
- declaration.maybeRPC() &&
- declaration.superTypes.contains(context.rpc.typeWith())
- ) {
+ if (declaration.isInterface && declaration.superTypes.contains(context.rpc.defaultType)) {
processService(declaration, context)
}
return super.visitClass(declaration, context)
}
- private fun IrClass.maybeRPC() = superTypes.any { it.classFqName?.asString()?.contains("RPC") == true }
-
private fun processService(service: IrClass, context: RPCIrContext) {
val declaration = RPCDeclarationScanner.scanServiceDeclaration(service, context)
RPCStubGenerator(declaration, context, logger).generate()
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
index 7c95932f..4b07e2d3 100644
--- a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
+++ b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
@@ -2,22 +2,22 @@
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
+@file:OptIn(UnsafeDuringIrConstructionAPI::class)
+
package kotlinx.rpc.codegen.extension
import kotlinx.rpc.codegen.VersionSpecificApi
+import kotlinx.rpc.codegen.common.rpcMethodClassName
import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder
import org.jetbrains.kotlin.backend.jvm.functionByName
-import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
+import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.*
-import org.jetbrains.kotlin.ir.declarations.IrClass
-import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
-import org.jetbrains.kotlin.ir.declarations.IrProperty
-import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
+import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name
@@ -33,10 +34,8 @@ import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.util.OperatorNameConventions
import kotlin.properties.Delegates
-const val STUB_SUFFIX = "Stub"
private const val CLIENT_PROPERTY = "__rpc_client"
private const val STUB_ID_PROPERTY = "__rpc_stub_id"
-private const val METHOD_CLASS_SUFFIX_PROPERTY = "RPCData"
private const val METHOD_NAMES_PROPERTY = "methodNames"
private const val METHOD_TYPE_OF_FUNCTION = "methodTypeOf"
private const val WITH_CLIENT_METHOD = "withClient"
@@ -46,6 +45,7 @@ private const val RPC_FIELDS_METHOD = "rpcFields"
internal class RPCStubGenerator(
private val declaration: ServiceDeclaration,
private val ctx: RPCIrContext,
+ @Suppress("unused")
private val logger: MessageCollector,
) {
private fun irBuilder(symbol: IrSymbol): DeclarationIrBuilder =
@@ -58,8 +58,6 @@ internal class RPCStubGenerator(
generateStubClass()
addAssociatedObjectAnnotationIfPossible()
-
- logger.report(CompilerMessageSeverity.WARNING, declaration.service.dump())
}
private fun generateStubClass() {
@@ -103,16 +101,7 @@ internal class RPCStubGenerator(
type = ctx.rpcClient.defaultType
}
- // default constructor implementation
- body = irBuilder(symbol).irBlockBody {
- +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
- +IrInstanceInitializerCallImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- classSymbol = this@generateStubConstructor.symbol,
- type = context.irBuiltIns.unitType,
- )
- }
+ addDefaultConstructor(this)
}
}
@@ -148,7 +137,7 @@ internal class RPCStubGenerator(
* ```
*/
private fun IrClass.stubIdProperty() {
- stubIdProperty = constructorProperty(STUB_ID_PROPERTY, ctx.irBuiltIns.longType, stubIdValueParameter)
+ stubIdProperty = addConstructorProperty(STUB_ID_PROPERTY, ctx.irBuiltIns.longType, stubIdValueParameter)
}
private var clientProperty: IrProperty by Delegates.notNull()
@@ -161,17 +150,27 @@ internal class RPCStubGenerator(
* ```
*/
private fun IrClass.clientProperty() {
- clientProperty = constructorProperty(CLIENT_PROPERTY, ctx.rpcClient.defaultType, clientValueParameter)
+ clientProperty = addConstructorProperty(CLIENT_PROPERTY, ctx.rpcClient.defaultType, clientValueParameter)
}
- private fun IrClass.constructorProperty(
+ private fun IrClass.addConstructorProperty(
propertyName: String,
propertyType: IrType,
valueParameter: IrValueParameter,
+ propertyVisibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE
+ ): IrProperty {
+ return addConstructorProperty(Name.identifier(propertyName), propertyType, valueParameter, propertyVisibility)
+ }
+
+ private fun IrClass.addConstructorProperty(
+ propertyName: Name,
+ propertyType: IrType,
+ valueParameter: IrValueParameter,
+ propertyVisibility: DescriptorVisibility = DescriptorVisibilities.PRIVATE
): IrProperty {
return addProperty {
- name = Name.identifier(propertyName)
- visibility = DescriptorVisibilities.PRIVATE
+ name = propertyName
+ visibility = propertyVisibility
}.apply {
addBackingFieldUtil {
visibility = DescriptorVisibilities.PRIVATE
@@ -189,8 +188,8 @@ internal class RPCStubGenerator(
)
}
- addDefaultGetter(this@constructorProperty, ctx.irBuiltIns) {
- visibility = DescriptorVisibilities.PRIVATE
+ addDefaultGetter(this@addConstructorProperty, ctx.irBuiltIns) {
+ visibility = propertyVisibility
}
}
}
@@ -286,8 +285,7 @@ internal class RPCStubGenerator(
private fun IrClass.rpcFlowField(field: ServiceDeclaration.FlowField) {
val isLazy = !field.property.hasAnnotation(ctx.rpcEagerFieldAnnotation)
- val servicePropertyGetter = field.property.getter
- ?: error("RPC field declared in service interface expected to have getters: ${field.property.dump()}")
+ val servicePropertyGetter = field.property.getterOrFail
addProperty {
name = field.property.name
@@ -538,13 +536,10 @@ internal class RPCStubGenerator(
"detekt.LongMethod",
)
private fun IrClass.generateRpcMethod(method: ServiceDeclaration.Method) {
- val isMethodObject = method.argumentTypes.isEmpty()
- val methodClassName = "${method.function.name.asString().capitalized()}_" + METHOD_CLASS_SUFFIX_PROPERTY
-
- val methodClass: IrClass = findDeclaration { it.name.asString() == methodClassName }
- ?: error("Expected $methodClassName class to be present in stub class ${declaration.simpleName}")
+ val isMethodObject = method.arguments.isEmpty()
- methodClasses.add(methodClass)
+ val methodClassName = method.function.name.rpcMethodClassName
+ val methodClass: IrClass = initiateAndGetMethodClass(methodClassName, method)
addFunction {
name = method.function.name
@@ -562,7 +557,7 @@ internal class RPCStubGenerator(
val declaredFunction = this
- val arguments = method.argumentTypes.memoryOptimizedMap { arg ->
+ val arguments = method.arguments.memoryOptimizedMap { arg ->
addValueParameter {
name = arg.value.name
type = arg.type
@@ -596,7 +591,7 @@ internal class RPCStubGenerator(
parent = declaredFunction
body = irBuilder(symbol).irBlockBody {
- val call = irRPCMethodClientCall(
+ val call = irRpcMethodClientCall(
method = method,
functionThisReceiver = functionThisReceiver,
isMethodObject = isMethodObject,
@@ -627,6 +622,123 @@ internal class RPCStubGenerator(
}
}
+ /**
+ * Frontend plugins generate the following:
+ * ```kotlin
+ * // Given rpc method:
+ * suspend fun hello(arg1: String, arg2: Int)
+ *
+ * // Frontend generates:
+ * @Serializable
+ * class hello$rpcMethod {
+ * constructor(arg1: String, arg2: String)
+ *
+ * val arg1: String
+ * val arg2: Int
+ * }
+ * ```
+ *
+ * This method generates missing getters and backing fields' values.
+ * And adds RPCMethodClassArguments supertype with `asArray` method implemented.
+ *
+ * Resulting class:
+ * ```kotlin
+ * @Serializable
+ * class hello$rpcMethod(
+ * val arg1: String,
+ * val arg2: Int,
+ * ) : RPCMethodClassArguments {
+ * // or emptyArray when no arguments
+ * override fun asArray(): Array = arrayOf(arg1, arg2)
+ * }
+ * ```
+ */
+ private fun IrClass.initiateAndGetMethodClass(methodClassName: Name, method: ServiceDeclaration.Method): IrClass {
+ val methodClass = findDeclaration { it.name == methodClassName }
+ ?: error(
+ "Expected $methodClassName class to be present in stub class " +
+ "${declaration.service.name}${declaration.stubClass.name}"
+ )
+
+ methodClasses.add(methodClass)
+
+ val methodClassThisReceiver = methodClass.thisReceiver
+ ?: error("Expected $methodClassName of ${declaration.stubClass.name} to have a thisReceiver")
+
+ val properties = if (methodClass.isClass) {
+ val argNames = method.arguments.memoryOptimizedMap { it.value.name }.toSet()
+
+ // remove frontend generated properties
+ // new ones will be used instead
+ methodClass.declarations.removeAll { it is IrProperty && it.name in argNames }
+
+ // primary constructor, serialization may add another
+ val constructor = methodClass.constructors.single {
+ method.arguments.size == it.valueParameters.size
+ }
+
+ constructor.isPrimary = true
+ methodClass.addDefaultConstructor(constructor)
+
+ constructor.valueParameters.memoryOptimizedMap { valueParam ->
+ methodClass.addConstructorProperty(
+ propertyName = valueParam.name,
+ propertyType = valueParam.type,
+ valueParameter = valueParam,
+ propertyVisibility = DescriptorVisibilities.PUBLIC,
+ )
+ }
+ } else {
+ emptyList()
+ }
+
+ methodClass.superTypes = listOf(ctx.rpcMethodClassArguments.defaultType)
+
+ methodClass.addFunction {
+ name = ctx.functions.asArray.name
+ visibility = DescriptorVisibilities.PUBLIC
+ returnType = ctx.arrayOfAnyNullable
+ modality = Modality.OPEN
+ }.apply {
+ overriddenSymbols = listOf(ctx.functions.asArray.symbol)
+
+ val asArrayThisReceiver = vsApi {
+ methodClassThisReceiver.copyToVS(this@apply, origin = IrDeclarationOrigin.DEFINED)
+ }.also {
+ dispatchReceiverParameter = it
+ }
+
+ body = irBuilder(symbol).irBlockBody {
+ val callee = if (methodClass.isObject) {
+ ctx.functions.emptyArray
+ } else {
+ ctx.irBuiltIns.arrayOf
+ }
+
+ val arrayOfCall = irCall(callee, type = ctx.arrayOfAnyNullable).apply arrayOfCall@{
+ putTypeArgument(0, ctx.anyNullable)
+
+ if (methodClass.isObject) {
+ return@arrayOfCall
+ }
+
+ val vararg = irVararg(
+ elementType = ctx.anyNullable,
+ values = properties.memoryOptimizedMap { property ->
+ irCallProperty(methodClass, property, symbol = asArrayThisReceiver.symbol)
+ },
+ )
+
+ putValueArgument(0, vararg)
+ }
+
+ +irReturn(arrayOfCall)
+ }
+ }
+
+ return methodClass
+ }
+
/**
* Part of [generateRpcMethod] that generates next call:
*
@@ -646,7 +758,7 @@ internal class RPCStubGenerator(
"detekt.NestedBlockDepth",
"detekt.MagicNumber",
)
- private fun IrBlockBodyBuilder.irRPCMethodClientCall(
+ private fun IrBlockBodyBuilder.irRpcMethodClientCall(
method: ServiceDeclaration.Method,
functionThisReceiver: IrValueParameter,
isMethodObject: Boolean,
@@ -702,7 +814,7 @@ internal class RPCStubGenerator(
irCallConstructor(
// serialization plugin adds additional constructor with more arguments
callee = methodClass.constructors.single {
- it.valueParameters.size == method.argumentTypes.size
+ it.valueParameters.size == method.arguments.size
}.symbol,
typeArguments = emptyList(),
).apply {
@@ -758,8 +870,7 @@ internal class RPCStubGenerator(
}
private fun irCallProperty(receiver: IrExpression, property: IrProperty): IrCall {
- val getter = property.getter
- ?: error("Expected property getter to call it: ${property.dump()}")
+ val getter = property.getterOrFail
return IrCallImpl(
startOffset = UNDEFINED_OFFSET,
@@ -811,15 +922,7 @@ internal class RPCStubGenerator(
isPrimary = true
visibility = DescriptorVisibilities.PRIVATE
}.apply {
- body = irBuilder(symbol).irBlockBody {
- +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
- +IrInstanceInitializerCallImpl(
- startOffset = startOffset,
- endOffset = endOffset,
- classSymbol = this@generateCompanionObjectConstructor.symbol,
- type = context.irBuiltIns.unitType,
- )
- }
+ addDefaultConstructor(this)
}
}
@@ -868,7 +971,7 @@ internal class RPCStubGenerator(
addBackingFieldUtil {
type = mapType
isFinal = true
- vsApi { modalityVS = Modality.FINAL }
+ vsApi { isFinalVS = true }
visibility = DescriptorVisibilities.PRIVATE
}.apply {
val isEmpty = declaration.methods.isEmpty()
@@ -1088,12 +1191,10 @@ internal class RPCStubGenerator(
return@listApply
}
- val anyArrayType = ctx.irBuiltIns.arrayClass.typeWith(ctx.anyNullable, Variance.OUT_VARIANCE)
-
val vararg = IrVarargImpl(
startOffset = UNDEFINED_OFFSET,
endOffset = UNDEFINED_OFFSET,
- type = anyArrayType,
+ type = ctx.arrayOfAnyNullable,
varargElementType = ctx.anyNullable,
elements = declaration.fields.memoryOptimizedMap {
irCallProperty(irGet(service), it.property)
@@ -1142,10 +1243,23 @@ internal class RPCStubGenerator(
}
}
+ // default constructor implementation
+ private fun IrClass.addDefaultConstructor(constructor: IrConstructor) {
+ constructor.body = irBuilder(constructor.symbol).irBlockBody {
+ +irDelegatingConstructorCall(context.irBuiltIns.anyClass.owner.constructors.single())
+ +IrInstanceInitializerCallImpl(
+ startOffset = startOffset,
+ endOffset = endOffset,
+ classSymbol = this@addDefaultConstructor.symbol,
+ type = context.irBuiltIns.unitType,
+ )
+ }
+ }
+
// adds fake overrides for toString(), equals(), hashCode() for a class
private fun IrClass.addAnyOverrides(parent: IrClass? = null) {
val anyClass = ctx.irBuiltIns.anyClass.owner
- val overridenClass = parent ?: anyClass
+ val overriddenClass = parent ?: anyClass
addFunction {
name = OperatorNameConventions.EQUALS
@@ -1157,7 +1271,9 @@ internal class RPCStubGenerator(
isFakeOverride = true
returnType = ctx.irBuiltIns.booleanType
}.apply {
- overriddenSymbols += overridenClass.functions.single { it.name == OperatorNameConventions.EQUALS }.symbol
+ overriddenSymbols += overriddenClass.functions.single {
+ it.name == OperatorNameConventions.EQUALS
+ }.symbol
dispatchReceiverParameter = anyClass.thisReceiver
@@ -1176,7 +1292,9 @@ internal class RPCStubGenerator(
isFakeOverride = true
returnType = ctx.irBuiltIns.intType
}.apply {
- overriddenSymbols += overridenClass.functions.single { it.name == OperatorNameConventions.HASH_CODE }.symbol
+ overriddenSymbols += overriddenClass.functions.single {
+ it.name == OperatorNameConventions.HASH_CODE
+ }.symbol
dispatchReceiverParameter = anyClass.thisReceiver
}
@@ -1190,7 +1308,9 @@ internal class RPCStubGenerator(
isFakeOverride = true
returnType = ctx.irBuiltIns.stringType
}.apply {
- overriddenSymbols += overridenClass.functions.single { it.name == OperatorNameConventions.TO_STRING }.symbol
+ overriddenSymbols += overriddenClass.functions.single {
+ it.name == OperatorNameConventions.TO_STRING
+ }.symbol
dispatchReceiverParameter = anyClass.thisReceiver
}
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
index 81a8ab32..042cc6e3 100644
--- a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
+++ b/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
@@ -22,7 +22,7 @@ class ServiceDeclaration(
class Method(
val function: IrSimpleFunction,
- val argumentTypes: List,
+ val arguments: List,
) {
class Argument(
val value: IrValueParameter,
diff --git a/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index 1fe7c5d0..e7c1d9a7 100644
--- a/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
+++ b/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
import org.jetbrains.kotlin.config.CompilerConfiguration
+import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter
@OptIn(ExperimentalCompilerApi::class)
class RPCCommandLineProcessor : CommandLineProcessor {
@@ -30,5 +31,6 @@ class RPCCompilerPlugin : CompilerPluginRegistrar() {
val extension = RPCCompilerPluginCore.provideExtension(configuration)
IrGenerationExtension.registerExtension(extension)
+ FirExtensionRegistrarAdapter.registerExtension(FirRPCExtensionRegistrar(configuration))
}
}
diff --git a/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
index 7898e1f0..02eebd9e 100644
--- a/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
+++ b/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -6,7 +6,6 @@ package kotlinx.rpc.codegen
import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
import org.jetbrains.kotlin.backend.common.ir.addExtensionReceiver
-import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrFunction
@@ -17,7 +16,6 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType
-import org.jetbrains.kotlin.ir.types.impl.IrErrorClassImpl.modality
import org.jetbrains.kotlin.ir.util.copyTo
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId
@@ -31,9 +29,11 @@ object VersionSpecificApiImpl : VersionSpecificApi {
return platform.isJs()
}
- override var IrFieldBuilder.modalityVS: Modality
- get() = modality
- set(value) { modality = value }
+ override var IrFieldBuilder.isFinalVS: Boolean
+ get() = isFinal
+ set(value) {
+ isFinal = value
+ }
override var IrCall.originVS: IrStatementOrigin?
get() = origin
diff --git a/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
index 0aa1ffb9..411eccd9 100644
--- a/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
+++ b/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -26,7 +26,7 @@ object VersionSpecificApiImpl : VersionSpecificApi {
override fun isJs(platform: TargetPlatform?): Boolean {
return platform.isJs()
}
- override var IrFieldBuilder.modalityVS: Modality
+ override var IrFieldBuilder.isFinalVS: Boolean
get() = undefinedAPI()
set(_) {}
diff --git a/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
index 5373cc6f..1823b456 100644
--- a/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
+++ b/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -29,7 +29,7 @@ object VersionSpecificApiImpl : VersionSpecificApi {
override fun isJs(platform: TargetPlatform?): Boolean {
return platform.isJs()
}
- override var IrFieldBuilder.modalityVS: Modality
+ override var IrFieldBuilder.isFinalVS: Boolean
get() = undefinedAPI()
set(_) {}
diff --git a/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
index 0ec5b4fa..132e21e5 100644
--- a/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
+++ b/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -29,7 +29,7 @@ object VersionSpecificApiImpl : VersionSpecificApi {
override fun isJs(platform: TargetPlatform?): Boolean {
return platform.isJs()
}
- override var IrFieldBuilder.modalityVS: Modality
+ override var IrFieldBuilder.isFinalVS: Boolean
get() = undefinedAPI()
set(_) {}
diff --git a/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
new file mode 100644
index 00000000..e7c1d9a7
--- /dev/null
+++ b/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -0,0 +1,36 @@
+/*
+ * 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 org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
+import org.jetbrains.kotlin.compiler.plugin.CliOption
+import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
+import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
+import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
+import org.jetbrains.kotlin.config.CompilerConfiguration
+import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter
+
+@OptIn(ExperimentalCompilerApi::class)
+class RPCCommandLineProcessor : CommandLineProcessor {
+ override val pluginId = "kotlinx.rpc.codegen"
+
+ override val pluginOptions = emptyList()
+}
+
+@OptIn(ExperimentalCompilerApi::class)
+class RPCCompilerPlugin : CompilerPluginRegistrar() {
+ init {
+ VersionSpecificApi.INSTANCE = VersionSpecificApiImpl
+ }
+
+ override val supportsK2: Boolean = true
+
+ override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
+ val extension = RPCCompilerPluginCore.provideExtension(configuration)
+
+ IrGenerationExtension.registerExtension(extension)
+ FirExtensionRegistrarAdapter.registerExtension(FirRPCExtensionRegistrar(configuration))
+ }
+}
diff --git a/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
new file mode 100644
index 00000000..dbbc03a4
--- /dev/null
+++ b/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
@@ -0,0 +1,73 @@
+/*
+ * 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 org.jetbrains.kotlin.backend.common.extensions.IrPluginContext
+import org.jetbrains.kotlin.backend.common.ir.addExtensionReceiver
+import org.jetbrains.kotlin.descriptors.Modality
+import org.jetbrains.kotlin.ir.builders.declarations.IrFieldBuilder
+import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
+import org.jetbrains.kotlin.ir.declarations.IrFunction
+import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.declarations.IrValueParameter
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
+import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
+import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
+import org.jetbrains.kotlin.ir.types.IrType
+import org.jetbrains.kotlin.ir.util.copyTo
+import org.jetbrains.kotlin.name.CallableId
+import org.jetbrains.kotlin.name.ClassId
+import org.jetbrains.kotlin.name.FqName
+import org.jetbrains.kotlin.name.Name
+import org.jetbrains.kotlin.platform.TargetPlatform
+import org.jetbrains.kotlin.platform.isJs
+
+object VersionSpecificApiImpl : VersionSpecificApi {
+ override fun isJs(platform: TargetPlatform?): Boolean {
+ return platform.isJs()
+ }
+
+ override var IrFieldBuilder.isFinalVS: Boolean
+ get() = modality == Modality.FINAL
+ set(value) {
+ modality = if (value) Modality.FINAL else Modality.OPEN
+ }
+
+ override var IrCall.originVS: IrStatementOrigin?
+ get() = origin
+ set(value) { origin = value }
+
+ override fun referenceClass(context: IrPluginContext, packageName: String, name: String): IrClassSymbol? {
+ return context.referenceClass(
+ ClassId(
+ FqName(packageName),
+ FqName(name),
+ false
+ )
+ )
+ }
+
+ override fun referenceFunctions(
+ context: IrPluginContext,
+ packageName: String,
+ name: String
+ ): Collection {
+ return context.referenceFunctions(
+ CallableId(
+ FqName(packageName),
+ Name.identifier(name),
+ )
+ )
+ }
+
+ override fun IrValueParameter.copyToVS(irFunction: IrFunction, origin: IrDeclarationOrigin): IrValueParameter {
+ return copyTo(irFunction, origin)
+ }
+
+ override fun IrSimpleFunction.addExtensionReceiverVS(type: IrType, origin: IrDeclarationOrigin): IrValueParameter {
+ return addExtensionReceiver(type, origin)
+ }
+}
diff --git a/core/build.gradle.kts b/core/build.gradle.kts
index 6731b095..cd9712e8 100644
--- a/core/build.gradle.kts
+++ b/core/build.gradle.kts
@@ -4,10 +4,9 @@
plugins {
alias(libs.plugins.conventions.kmp)
- alias(libs.plugins.serialization)
alias(libs.plugins.ksp)
- alias(libs.plugins.kotlinx.rpc)
alias(libs.plugins.atomicfu)
+ alias(libs.plugins.serialization)
}
kotlin {
@@ -24,5 +23,11 @@ kotlin {
implementation(projects.krpc.krpcLogging)
}
}
+
+ jsMain {
+ dependencies {
+ implementation(libs.kotlin.js.wrappers)
+ }
+ }
}
}
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.kt b/core/src/commonMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.kt
index 30e849a3..9c67a0b5 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.kt
@@ -28,4 +28,6 @@ internal expect class DeserializedException(
stacktrace: List,
cause: SerializedException?,
className: String
-) : Throwable
+) : Throwable {
+ override val message: String
+}
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCMethodClassArguments.kt b/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCMethodClassArguments.kt
index ce3d09bc..57657334 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCMethodClassArguments.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/internal/RPCMethodClassArguments.kt
@@ -6,5 +6,5 @@ package kotlinx.rpc.internal
@InternalRPCApi
public interface RPCMethodClassArguments {
- public fun asArray(): Array
+ public fun asArray(): Array
}
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.kt b/core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.kt
index 0d74fc4b..59bc204a 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.kt
@@ -7,4 +7,4 @@ package kotlinx.rpc.internal
import kotlin.reflect.KClass
@InternalRPCApi
-public expect fun findRPCProviderInCompanion(kClass: KClass<*>): R
+public expect fun findRPCStubProvider(kClass: KClass<*>, resultKClass: KClass): R
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/internal/transport/RPCPluginKey.kt b/core/src/commonMain/kotlin/kotlinx/rpc/internal/transport/RPCPluginKey.kt
index d6d47fa6..2eeb3562 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/internal/transport/RPCPluginKey.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/internal/transport/RPCPluginKey.kt
@@ -51,7 +51,7 @@ public enum class RPCPluginKey(override val uniqueIndex: Int, private val associ
init {
require(ordinal == 0 || associatedPlugin != RPCPlugin.UNKNOWN) {
error("associatedPlugin must not be $RPCPlugin.${RPCPlugin.UNKNOWN} " +
- "for anything other than $RPCPluginKey.${UNKNOWN}")
+ "for anything other than $RPCPluginKey.UNKNOWN")
}
}
diff --git a/core/src/jsMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.js.kt b/core/src/jsMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.js.kt
index b9b43951..cbd4c3cf 100644
--- a/core/src/jsMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.js.kt
+++ b/core/src/jsMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.js.kt
@@ -11,7 +11,7 @@ import kotlinx.rpc.internal.transport.StackElement
internal actual class DeserializedException actual constructor(
private val toStringMessage: String,
- override val message: String,
+ actual override val message: String,
stacktrace: List,
cause: SerializedException?,
className: String
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 9e4f061a..2a6098e6 100644
--- a/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
+++ b/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
@@ -6,6 +6,7 @@
package kotlinx.rpc.internal
+import js.objects.Object
import kotlinx.rpc.RPC
import kotlin.reflect.AssociatedObjectKey
import kotlin.reflect.ExperimentalAssociatedObjects
@@ -22,9 +23,51 @@ public annotation class WithRPCStubObject(
)
@InternalRPCApi
-@OptIn(ExperimentalAssociatedObjects::class)
-public actual fun findRPCProviderInCompanion(kClass: KClass<*>): R {
- @Suppress("UNCHECKED_CAST")
- return kClass.findAssociatedObject() as? R
- ?: internalError("unable to find $kClass rpc stub object")
+public actual fun findRPCStubProvider(kClass: KClass<*>, resultKClass: KClass): R {
+ val associatedObject = kClass.findAssociatedObjectImpl(WithRPCStubObject::class, resultKClass)
+ ?: internalError("Unable to find $kClass associated object")
+
+ if (resultKClass.isInstance(associatedObject)) {
+ @Suppress("UNCHECKED_CAST")
+ return associatedObject as R
+ }
+
+ internalError(
+ "Located associated object is not of desired type $resultKClass, " +
+ "instead found $associatedObject of class " +
+ (associatedObject::class.qualifiedClassNameOrNull ?: associatedObject::class.js.name)
+ )
+}
+
+private val KClass<*>.jClass get(): JsClass<*> = asDynamic().jClass_1.unsafeCast>()
+
+/**
+ * Workaround for bugs in [findAssociatedObject]
+ * See KT-70132 for more info.
+ *
+ * This function uses std-lib's implementation and accounts for the bug in the compiler
+ */
+@Suppress("detekt.ReturnCount")
+internal fun KClass<*>.findAssociatedObjectImpl(
+ annotationClass: KClass,
+ resultKClass: KClass,
+): Any? {
+ val key = annotationClass.jClass.asDynamic().`$metadata$`?.associatedObjectKey?.unsafeCast() ?: return null
+ val map = jClass.asDynamic().`$metadata$`?.associatedObjects ?: return null
+ val factory = map[key] ?: return fallbackFindAssociatedObjectImpl(map, resultKClass)
+ return factory()
+}
+
+private fun fallbackFindAssociatedObjectImpl(map: dynamic, resultKClass: KClass): R? {
+ return Object.entries(map as Any)
+ .mapNotNull { (_, factory) ->
+ val unsafeFactory = factory.asDynamic()
+ val maybeObject = unsafeFactory()
+ if (resultKClass.isInstance(maybeObject)) {
+ maybeObject.unsafeCast()
+ } else {
+ null
+ }
+ }
+ .singleOrNull()
}
diff --git a/core/src/jvmMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.jvm.kt b/core/src/jvmMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.jvm.kt
index b4539d49..982afdc3 100644
--- a/core/src/jvmMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.jvm.kt
+++ b/core/src/jvmMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.jvm.kt
@@ -13,7 +13,7 @@ private val throwableFields = Throwable::class.java.fieldsCountOrDefault(-1)
internal actual class DeserializedException actual constructor(
private val toStringMessage: String,
- override val message: String,
+ actual override val message: String,
stacktrace: List,
cause: SerializedException?,
private val className: String
diff --git a/core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.jvm.kt b/core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.jvm.kt
index 941fbc4b..9ffc595d 100644
--- a/core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.jvm.kt
+++ b/core/src/jvmMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.jvm.kt
@@ -10,11 +10,16 @@ import kotlin.reflect.KClass
import kotlin.reflect.full.companionObjectInstance
@InternalRPCApi
-public actual fun findRPCProviderInCompanion(kClass: KClass<*>): R {
- @Suppress("UNCHECKED_CAST")
- return kClass.java.classLoader
- .loadClass("${kClass.qualifiedName}Stub")
+public actual fun findRPCStubProvider(kClass: KClass<*>, resultKClass: KClass): R {
+ val candidate = kClass.java.classLoader
+ .loadClass("${kClass.qualifiedName}\$\$rpcServiceStub")
?.kotlin
- ?.companionObjectInstance as? R
- ?: internalError("unable to find $kClass rpc client object")
+ ?.companionObjectInstance
+
+ @Suppress("UNCHECKED_CAST")
+ if (resultKClass.isInstance(candidate)) {
+ return candidate as R
+ }
+
+ internalError("unable to find $kClass rpc client object")
}
diff --git a/core/src/nativeMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.native.kt b/core/src/nativeMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.native.kt
index dab60184..fa5d0f33 100644
--- a/core/src/nativeMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.native.kt
+++ b/core/src/nativeMain/kotlin/kotlinx/rpc/internal/ExceptionUtils.native.kt
@@ -11,7 +11,7 @@ import kotlinx.rpc.internal.transport.StackElement
internal actual class DeserializedException actual constructor(
private val toStringMessage: String,
- override val message: String,
+ actual override val message: String,
stacktrace: List,
cause: SerializedException?,
className: String
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 9e4f061a..638bfa78 100644
--- a/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt
+++ b/core/src/nativeMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.native.kt
@@ -23,8 +23,18 @@ public annotation class WithRPCStubObject(
@InternalRPCApi
@OptIn(ExperimentalAssociatedObjects::class)
-public actual fun findRPCProviderInCompanion(kClass: KClass<*>): R {
+public actual fun findRPCStubProvider(kClass: KClass<*>, resultKClass: KClass): R {
+ val associatedObject = kClass.findAssociatedObject()
+ ?: internalError("Unable to find $kClass associated object")
+
@Suppress("UNCHECKED_CAST")
- return kClass.findAssociatedObject() as? R
- ?: internalError("unable to find $kClass rpc stub object")
+ if (resultKClass.isInstance(associatedObject)) {
+ return associatedObject as R
+ }
+
+ internalError(
+ "Located associated object is not of desired type $resultKClass, " +
+ "instead found $associatedObject of class " +
+ (associatedObject::class.qualifiedClassNameOrNull ?: associatedObject::class.simpleName)
+ )
}
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts b/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
index 96b8ac19..d03b310d 100644
--- a/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
+++ b/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
@@ -62,15 +62,17 @@ fun KotlinSourceSet.configureResources(sourceSetPath: Path, vararg versionNames:
// 'resources' property does not work alone in gradle 7.5.1 with kotlin 1.7.0 (no idea why),
// so we adjust task contents as well
- tasks.withType().configureEach {
- duplicatesStrategy = DuplicatesStrategy.EXCLUDE
-
- from(versionNames.map { vsResources.resolve(it) })
- include { it.file.parentInAllowList(versionNames) }
- }
+ // todo duplicate (or to many resources are copied, should update the algo)
+// tasks.withType().configureEach {
+// duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+//
+// from(versionNames.map { vsResources.resolve(it) })
+// include { it.file.parentInAllowList(versionNames) }
+// }
}
fun File.parentInAllowList(allowList: Array): Boolean {
+// println("decide: $absolutePath")
val parent = toPath().parent?.toFile()
// will skip v_1_7 for 1.7.0, as it's parent is resources
// but will allow META-INF, as it's parent is v_1_7
diff --git a/gradle-conventions/conventions-utils/src/main/kotlin/util/TargetUtils.kt b/gradle-conventions/conventions-utils/src/main/kotlin/util/TargetUtils.kt
index af76fda5..7f21f783 100644
--- a/gradle-conventions/conventions-utils/src/main/kotlin/util/TargetUtils.kt
+++ b/gradle-conventions/conventions-utils/src/main/kotlin/util/TargetUtils.kt
@@ -8,7 +8,6 @@ import groovy.json.JsonSlurper
import io.gitlab.arturbosch.detekt.extensions.DetektExtension
import org.gradle.api.Action
import org.gradle.api.Project
-import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.kotlin.dsl.the
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget
@@ -82,11 +81,7 @@ private fun KotlinMultiplatformExtension.configureTargets(
}
if (jvm && isIncluded("jvm", kotlinVersion, targetsLookup)) {
- jvm {
- jvmToolchain {
- languageVersion.set(JavaLanguageVersion.of(8))
- }
- }.also { targets.add(it) }
+ jvm().also { targets.add(it) }
}
if (js && isIncluded("js", kotlinVersion, targetsLookup)) {
@@ -131,6 +126,8 @@ fun Project.configureKotlin(
configureDetekt(includedTargets)
+ jvmToolchain(8)
+
action.execute(this)
}
}
diff --git a/gradle-conventions/kotlin-version-new/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts b/gradle-conventions/kotlin-version-new/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts
index b5a13821..c41495ac 100644
--- a/gradle-conventions/kotlin-version-new/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts
+++ b/gradle-conventions/kotlin-version-new/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts
@@ -3,8 +3,11 @@
*/
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
+import util.optionalProperty
import util.projectLanguageVersion
+val useK2Plugin: Boolean by optionalProperty()
+
configure {
- compilerOptions(projectLanguageVersion)
+ compilerOptions(projectLanguageVersion(useK2Plugin))
}
diff --git a/gradle-conventions/kotlin-version-new/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts b/gradle-conventions/kotlin-version-new/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts
index 6659ba87..6a3d3143 100644
--- a/gradle-conventions/kotlin-version-new/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts
+++ b/gradle-conventions/kotlin-version-new/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts
@@ -4,9 +4,12 @@
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
+import util.optionalProperty
import util.projectLanguageVersion
+val useK2Plugin: Boolean by optionalProperty()
+
@OptIn(ExperimentalKotlinGradlePluginApi::class)
configure {
- compilerOptions(projectLanguageVersion)
+ compilerOptions(projectLanguageVersion(useK2Plugin))
}
diff --git a/gradle-conventions/kotlin-version-new/src/main/kotlin/util/CompilerOptions.kt b/gradle-conventions/kotlin-version-new/src/main/kotlin/util/CompilerOptions.kt
index 5faaf361..5d63bb2f 100644
--- a/gradle-conventions/kotlin-version-new/src/main/kotlin/util/CompilerOptions.kt
+++ b/gradle-conventions/kotlin-version-new/src/main/kotlin/util/CompilerOptions.kt
@@ -12,7 +12,12 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
*
* This should be lined up with the minimal supported compiler plugin version
*/
-val projectLanguageVersion: KotlinCommonCompilerOptions.() -> Unit = {
- languageVersion.set(KotlinVersion.KOTLIN_1_7)
- apiVersion.set(KotlinVersion.KOTLIN_1_7)
+fun projectLanguageVersion(useK2Plugin: Boolean): KotlinCommonCompilerOptions.() -> Unit = {
+ val kotlinVersion = when {
+ useK2Plugin -> KotlinVersion.KOTLIN_2_0
+ else -> KotlinVersion.KOTLIN_1_7
+ }
+
+ languageVersion.set(kotlinVersion)
+ apiVersion.set(kotlinVersion)
}
diff --git a/gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts b/gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts
index c83983d7..fcbf1600 100644
--- a/gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts
+++ b/gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts
@@ -2,6 +2,9 @@
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
+import util.optionalProperty
import util.setLanguageVersion
-setLanguageVersion()
+val useK2Plugin: Boolean by optionalProperty()
+
+setLanguageVersion(useK2Plugin)
diff --git a/gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts b/gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts
index c83983d7..fcbf1600 100644
--- a/gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts
+++ b/gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts
@@ -2,6 +2,9 @@
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
+import util.optionalProperty
import util.setLanguageVersion
-setLanguageVersion()
+val useK2Plugin: Boolean by optionalProperty()
+
+setLanguageVersion(useK2Plugin)
diff --git a/gradle-conventions/kotlin-version-old/src/main/kotlin/util/CompilerOptions.kt b/gradle-conventions/kotlin-version-old/src/main/kotlin/util/CompilerOptions.kt
index cbb06182..18867b3c 100644
--- a/gradle-conventions/kotlin-version-old/src/main/kotlin/util/CompilerOptions.kt
+++ b/gradle-conventions/kotlin-version-old/src/main/kotlin/util/CompilerOptions.kt
@@ -8,11 +8,16 @@ import org.gradle.api.Project
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
-fun Project.setLanguageVersion() {
+fun Project.setLanguageVersion(useK2Plugin: Boolean) {
+ val kotlinVersion = when {
+ useK2Plugin -> "2.0"
+ else -> "1.7"
+ }
+
tasks.withType().all {
kotlinOptions {
- freeCompilerArgs += "-language-version=1.7"
- freeCompilerArgs += "-api-version=1.7"
+ freeCompilerArgs += "-language-version=$kotlinVersion"
+ freeCompilerArgs += "-api-version=$kotlinVersion"
}
}
}
diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/KotlinCompilerPluginBuilder.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/KotlinCompilerPluginBuilder.kt
index 2b9a4870..79668135 100644
--- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/KotlinCompilerPluginBuilder.kt
+++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/KotlinCompilerPluginBuilder.kt
@@ -63,6 +63,6 @@ class KotlinCompilerPluginBuilder {
}
}
-fun compilerPlugin(builder: KotlinCompilerPluginBuilder.() -> Unit): KotlinCompilerPluginSupportPlugin {
+fun compilerPlugin(builder: KotlinCompilerPluginBuilder.() -> Unit = {}): KotlinCompilerPluginSupportPlugin {
return KotlinCompilerPluginBuilder().apply(builder).build()
}
diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
index 4073a5a4..10724177 100644
--- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
+++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
@@ -26,13 +26,19 @@ class RPCGradlePlugin : Plugin {
val config = RPCConfig(target.isInternalDevelopment)
applyPlatformConfiguration(target, config)
- applyKspPlugin(target, config)
+
+ // TODO languageVersion parameter check
+ if (kotlinVersion.first() < '2') { // for 1.*.* versions
+ applyKspPlugin(target, config)
+ }
+
applyCompilerPlugin(target)
}
private fun applyCompilerPlugin(target: Project) {
- target.plugins.apply(CompilerPluginCore::class.java)
-// target.plugins.apply(compilerPluginForKotlin(kotlinVersion))
+ target.plugins.apply(CompilerPlugin::class.java)
+ target.plugins.apply(CompilerPluginK2::class.java)
+ target.plugins.apply(CompilerPluginCommon::class.java)
}
private fun applyKspPlugin(target: Project, config: RPCConfig) {
diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
index dff89ba9..b19ad08e 100644
--- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
+++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
@@ -8,34 +8,12 @@ package kotlinx.rpc
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin
-class CompilerPluginCore : KotlinCompilerPluginSupportPlugin by compilerPlugin({
-// pluginSuffix = "-core"
-})
+class CompilerPlugin : KotlinCompilerPluginSupportPlugin by compilerPlugin()
-//class CompilerPlugin1_9 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
-// pluginSuffix = "-1_9"
-//})
-//
-//class CompilerPlugin1_8 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
-// pluginSuffix = "-1_8"
-//})
-//
-//class CompilerPlugin1_7_2 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
-// pluginSuffix = "-1_7_2"
-//})
-//
-//class CompilerPlugin1_7 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
-// pluginSuffix = "-1_7"
-//})
+class CompilerPluginK2 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
+ pluginSuffix = "-k2"
+})
-//// Transitive dependencies do not work for Kotlin/Native
-//// https://youtrack.jetbrains.com/issue/KT-53477/Native-Gradle-plugin-doesnt-add-compiler-plugin-transitive-dependencies-to-compiler-plugin-classpath
-//fun compilerPluginForKotlin(kotlin: String): Class> {
-// return when {
-// kotlin == "1.7.0" || kotlin == "1.7.10" -> CompilerPlugin1_7::class.java
-// kotlin.startsWith("1.7.2") -> CompilerPlugin1_7_2::class.java
-// kotlin.startsWith("1.8") -> CompilerPlugin1_8::class.java
-// kotlin.startsWith("1.9") -> CompilerPlugin1_9::class.java
-// else -> error("Unsupported kotlin version: $kotlin")
-// }
-//}
+class CompilerPluginCommon : KotlinCompilerPluginSupportPlugin by compilerPlugin({
+ pluginSuffix = "-common"
+})
diff --git a/gradle.properties b/gradle.properties
index a35dece9..e14ead2f 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -28,3 +28,9 @@ kotlinx.rpc.plugin.internalDevelopment=true
# https://github.com/gradle/gradle/issues/20416
systemProp.org.gradle.kotlin.dsl.precompiled.accessors.strict=true
+
+# uncomment to debug compilation process
+#kotlin.compiler.execution.strategy=in-process
+
+# set to true to use K2 RPC compiler plugin to build and run the project (including tests)
+kotlinx.rpc.useK2Plugin=false
diff --git a/gradle/kotlin-versions-lookup.csv b/gradle/kotlin-versions-lookup.csv
index 17c1edbf..bccaa716 100644
--- a/gradle/kotlin-versions-lookup.csv
+++ b/gradle/kotlin-versions-lookup.csv
@@ -1,4 +1,5 @@
Kotlin,ksp,atomicfu,serialization,detekt-gradle-plugin,gradle-kotlin-dsl,binary-compatibility-validator,kover
+2.0.0,1.0.23,0.22.0,1.6.1,1.23.6,4.1.0,0.14.0,0.8.0
1.9.24,1.0.20,0.22.0,1.6.1,1.23.6,4.1.0,0.14.0,0.8.0
1.9.23,1.0.19,0.22.0,1.6.1,1.23.6,4.1.0,0.14.0,0.8.0
1.9.22,1.0.17,0.22.0,1.6.1,1.23.6,4.1.0,0.14.0,0.8.0
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 75c9cb4e..4617b5ec 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -3,7 +3,7 @@
kotlinx-rpc = "0.2.2"
# kotlin
-kotlin-lang = "1.9.24"
+kotlin-lang = "2.0.0"
# kotlin independent versions
detekt-analyzer = "1.23.6"
@@ -13,6 +13,7 @@ kotlin-logging = "6.0.9"
slf4j = "2.0.13"
logback = "1.3.14"
gradle-plugin-publish = "1.2.1"
+kotlin-wrappers = "1.0.0-pre.781"
# stub versions - relpaced based on kotlin, mostly for gradle-related (plugins) dependencies
# but also for dependencies for compiler specific modules
@@ -35,6 +36,7 @@ kotlin-test-junit = { module = "org.jetbrains.kotlin:kotlin-test-junit", version
kotlin-gradle-plugin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin-lang" }
kotlin-compiler-embeddable = { group = "org.jetbrains.kotlin", name = "kotlin-compiler-embeddable" }
+serialization-plugin = { module = "org.jetbrains.kotlin:kotlin-serialization-compiler-plugin", version.ref = "kotlin-lang" }
# serialization
serialization-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialization" }
@@ -68,6 +70,7 @@ coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", ve
coroutines-debug = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-debug", version.ref = "coroutines" }
detekt-gradle-plugin = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt-gradle-plugin" }
kover-gradle-plugin = { module = "org.jetbrains.kotlinx:kover-gradle-plugin", version.ref = "kover" }
+kotlin-js-wrappers = { module = "org.jetbrains.kotlin-wrappers:kotlin-js", version.ref = "kotlin-wrappers" }
[plugins]
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin-lang" }
diff --git a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/RPCClientUtils.kt b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/RPCClientUtils.kt
index 29bffe22..04e827f9 100644
--- a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/RPCClientUtils.kt
+++ b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/RPCClientUtils.kt
@@ -8,8 +8,9 @@ import kotlinx.atomicfu.atomic
import kotlinx.rpc.RPC
import kotlinx.rpc.RPCClient
import kotlinx.rpc.internal.RPCStubServiceProvider
-import kotlinx.rpc.internal.findRPCProviderInCompanion
+import kotlinx.rpc.internal.findRPCStubProvider
import kotlinx.rpc.internal.kClass
+import kotlinx.rpc.internal.safeCast
import kotlin.reflect.KClass
import kotlin.reflect.KType
@@ -54,7 +55,11 @@ private val SERVICE_ID = atomic(0L)
* @return instance of the generated service.
*/
public fun RPCClient.withService(serviceKClass: KClass): T {
- val provider = findRPCProviderInCompanion>(serviceKClass)
+ val provider = findRPCStubProvider>(
+ kClass = serviceKClass,
+ resultKClass = RPCStubServiceProvider::class.safeCast(),
+ )
+
val id = SERVICE_ID.incrementAndGet()
return provider.withClient(id, this)
diff --git a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/awaitFieldInitialization.kt b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/awaitFieldInitialization.kt
index ac4dec61..7483218f 100644
--- a/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/awaitFieldInitialization.kt
+++ b/krpc/krpc-client/src/commonMain/kotlin/kotlinx/rpc/client/awaitFieldInitialization.kt
@@ -7,7 +7,8 @@ package kotlinx.rpc.client
import kotlinx.rpc.RPC
import kotlinx.rpc.internal.RPCDeferredField
import kotlinx.rpc.internal.RPCServiceFieldsProvider
-import kotlinx.rpc.internal.findRPCProviderInCompanion
+import kotlinx.rpc.internal.findRPCStubProvider
+import kotlinx.rpc.internal.safeCast
import kotlin.reflect.KClass
/**
@@ -78,7 +79,7 @@ public suspend inline fun T.awaitFieldInitialization(): T {
* @return specified service, after all of it's field were initialized.
*/
public suspend fun T.awaitFieldInitialization(kClass: KClass): T {
- findRPCProviderInCompanion>(kClass)
+ findRPCStubProvider>(kClass, RPCServiceFieldsProvider::class.safeCast())
.rpcFields(this)
.forEach { field ->
field.await()
diff --git a/krpc/krpc-server/src/commonMain/kotlin/kotlinx/rpc/server/internal/RPCServiceUtils.kt b/krpc/krpc-server/src/commonMain/kotlin/kotlinx/rpc/server/internal/RPCServiceUtils.kt
index aa49ff0d..5e9d4594 100644
--- a/krpc/krpc-server/src/commonMain/kotlin/kotlinx/rpc/server/internal/RPCServiceUtils.kt
+++ b/krpc/krpc-server/src/commonMain/kotlin/kotlinx/rpc/server/internal/RPCServiceUtils.kt
@@ -7,7 +7,7 @@ package kotlinx.rpc.server.internal
import kotlinx.rpc.RPC
import kotlinx.rpc.internal.InternalRPCApi
import kotlinx.rpc.internal.RPCServiceMethodSerializationTypeProvider
-import kotlinx.rpc.internal.findRPCProviderInCompanion
+import kotlinx.rpc.internal.findRPCStubProvider
import kotlinx.rpc.internal.kClass
import kotlin.reflect.KClass
import kotlin.reflect.KType
@@ -33,5 +33,6 @@ public fun rpcServiceMethodSerializationTypeOf(serviceType: KType, methodName: S
*/
@InternalRPCApi
public fun rpcServiceMethodSerializationTypeOf(serviceKClass: KClass<*>, methodName: String): KType? {
- return findRPCProviderInCompanion(serviceKClass).methodTypeOf(methodName)
+ return findRPCStubProvider(serviceKClass, RPCServiceMethodSerializationTypeProvider::class)
+ .methodTypeOf(methodName)
}
diff --git a/tests/codegen-tests/codegen-tests-mpp/build.gradle.kts b/tests/codegen-tests/codegen-tests-mpp/build.gradle.kts
index ebfcf33f..b1b4b040 100644
--- a/tests/codegen-tests/codegen-tests-mpp/build.gradle.kts
+++ b/tests/codegen-tests/codegen-tests-mpp/build.gradle.kts
@@ -3,12 +3,12 @@
*/
import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
-import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
plugins {
alias(libs.plugins.conventions.kmp)
alias(libs.plugins.ksp)
alias(libs.plugins.kotlinx.rpc)
+ alias(libs.plugins.serialization)
}
kotlin {
@@ -39,9 +39,15 @@ kotlin {
}
}
- explicitApi = ExplicitApiMode.Disabled
- compilerOptions {
- languageVersion.set(KotlinVersion.KOTLIN_2_0)
+ js {
+ binaries.executable()
+ browser {
+ commonWebpackConfig {
+ this.sourceMaps = true
+ }
+ }
}
+
+ explicitApi = ExplicitApiMode.Disabled
}
diff --git a/tests/codegen-tests/codegen-tests-mpp/src/jsMain/resources/index.html b/tests/codegen-tests/codegen-tests-mpp/src/jsMain/resources/index.html
new file mode 100644
index 00000000..1134dd1d
--- /dev/null
+++ b/tests/codegen-tests/codegen-tests-mpp/src/jsMain/resources/index.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+ Kotlin JS kRPC Sample
+
+
+
+
+
diff --git a/utils/src/commonMain/kotlin/kotlinx/rpc/internal/kClassSafeCast.kt b/utils/src/commonMain/kotlin/kotlinx/rpc/internal/kClassSafeCast.kt
new file mode 100644
index 00000000..d567f267
--- /dev/null
+++ b/utils/src/commonMain/kotlin/kotlinx/rpc/internal/kClassSafeCast.kt
@@ -0,0 +1,10 @@
+/*
+ * 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.internal
+
+import kotlin.reflect.KClass
+
+@Suppress("UNCHECKED_CAST")
+fun KClass<*>.safeCast() = this as R
From 56d55b6582ffa06373e790fa656b6c929e9df2d3 Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Tue, 6 Aug 2024 15:49:42 +0200
Subject: [PATCH 05/17] yarn.lock (#148)
---
kotlin-js-store/yarn.lock | 1480 ++++++++++++++++++++++++++++++++-----
1 file changed, 1290 insertions(+), 190 deletions(-)
diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock
index a50960ba..5edf46cf 100644
--- a/kotlin-js-store/yarn.lock
+++ b/kotlin-js-store/yarn.lock
@@ -34,6 +34,18 @@
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
+"@isaacs/cliui@^8.0.2":
+ version "8.0.2"
+ resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
+ integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==
+ dependencies:
+ string-width "^5.1.2"
+ string-width-cjs "npm:string-width@^4.2.0"
+ strip-ansi "^7.0.1"
+ strip-ansi-cjs "npm:strip-ansi@^6.0.1"
+ wrap-ansi "^8.1.0"
+ wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
+
"@jridgewell/gen-mapping@^0.3.0":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098"
@@ -66,7 +78,15 @@
resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
-"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9":
+"@jridgewell/trace-mapping@^0.3.20":
+ version "0.3.25"
+ resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
+ integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.1.0"
+ "@jridgewell/sourcemap-codec" "^1.4.14"
+
+"@jridgewell/trace-mapping@^0.3.9":
version "0.3.19"
resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811"
integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==
@@ -74,6 +94,36 @@
"@jridgewell/resolve-uri" "^3.1.0"
"@jridgewell/sourcemap-codec" "^1.4.14"
+"@jsonjoy.com/base64@^1.1.1":
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/@jsonjoy.com/base64/-/base64-1.1.2.tgz#cf8ea9dcb849b81c95f14fc0aaa151c6b54d2578"
+ integrity sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==
+
+"@jsonjoy.com/json-pack@^1.0.3":
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/@jsonjoy.com/json-pack/-/json-pack-1.0.4.tgz#ab59c642a2e5368e8bcfd815d817143d4f3035d0"
+ integrity sha512-aOcSN4MeAtFROysrbqG137b7gaDDSmVrl5mpo6sT/w+kcXpWnzhMjmY/Fh/sDx26NBxyIE7MB1seqLeCAzy9Sg==
+ dependencies:
+ "@jsonjoy.com/base64" "^1.1.1"
+ "@jsonjoy.com/util" "^1.1.2"
+ hyperdyperid "^1.2.0"
+ thingies "^1.20.0"
+
+"@jsonjoy.com/util@^1.1.2":
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/@jsonjoy.com/util/-/util-1.2.0.tgz#0fe9a92de72308c566ebcebe8b5a3f01d3149df2"
+ integrity sha512-4B8B+3vFsY4eo33DMKyJPlQ3sBMpPFUZK2dr3O3rXrOGKKbYG44J0XSFkDo1VOQiri5HFEhIeVvItjR2xcazmg==
+
+"@leichtgewicht/ip-codec@^2.0.1":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1"
+ integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==
+
+"@pkgjs/parseargs@^0.11.0":
+ version "0.11.0"
+ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
+ integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
+
"@puppeteer/browsers@1.8.0":
version "1.8.0"
resolved "https://registry.yarnpkg.com/@puppeteer/browsers/-/browsers-1.8.0.tgz#fb6ee61de15e7f0e67737aea9f9bab1512dbd7d8"
@@ -97,6 +147,36 @@
resolved "https://registry.yarnpkg.com/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz#db4ecfd499a9765ab24002c3b696d02e6d32a12c"
integrity sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==
+"@types/body-parser@*":
+ version "1.19.5"
+ resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4"
+ integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==
+ dependencies:
+ "@types/connect" "*"
+ "@types/node" "*"
+
+"@types/bonjour@^3.5.13":
+ version "3.5.13"
+ resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956"
+ integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==
+ dependencies:
+ "@types/node" "*"
+
+"@types/connect-history-api-fallback@^1.5.4":
+ version "1.5.4"
+ resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3"
+ integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==
+ dependencies:
+ "@types/express-serve-static-core" "*"
+ "@types/node" "*"
+
+"@types/connect@*":
+ version "3.4.38"
+ resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858"
+ integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==
+ dependencies:
+ "@types/node" "*"
+
"@types/cookie@^0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.4.1.tgz#bfd02c1f2224567676c1545199f87c3a861d878d"
@@ -130,21 +210,123 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.1.tgz#aa22750962f3bf0e79d753d3cc067f010c95f194"
integrity sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==
-"@types/estree@^1.0.0":
+"@types/estree@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
+"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33":
+ version "4.19.5"
+ resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz#218064e321126fcf9048d1ca25dd2465da55d9c6"
+ integrity sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==
+ dependencies:
+ "@types/node" "*"
+ "@types/qs" "*"
+ "@types/range-parser" "*"
+ "@types/send" "*"
+
+"@types/express@*", "@types/express@^4.17.21":
+ version "4.17.21"
+ resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d"
+ integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==
+ dependencies:
+ "@types/body-parser" "*"
+ "@types/express-serve-static-core" "^4.17.33"
+ "@types/qs" "*"
+ "@types/serve-static" "*"
+
+"@types/http-errors@*":
+ version "2.0.4"
+ resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f"
+ integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==
+
+"@types/http-proxy@^1.17.8":
+ version "1.17.14"
+ resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec"
+ integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w==
+ dependencies:
+ "@types/node" "*"
+
"@types/json-schema@*", "@types/json-schema@^7.0.8":
version "7.0.12"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb"
integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==
+"@types/json-schema@^7.0.9":
+ version "7.0.15"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841"
+ integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==
+
+"@types/mime@^1":
+ version "1.3.5"
+ resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690"
+ integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==
+
+"@types/node-forge@^1.3.0":
+ version "1.3.11"
+ resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.11.tgz#0972ea538ddb0f4d9c2fa0ec5db5724773a604da"
+ integrity sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==
+ dependencies:
+ "@types/node" "*"
+
"@types/node@*", "@types/node@>=10.0.0":
version "20.6.0"
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.0.tgz#9d7daa855d33d4efec8aea88cd66db1c2f0ebe16"
integrity sha512-najjVq5KN2vsH2U/xyh2opaSEz6cZMR2SetLIlxlj08nOcmPOemJmUK2o4kUzfLqfrWE0PIrNeE16XhYDd3nqg==
+"@types/qs@*":
+ version "6.9.15"
+ resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.15.tgz#adde8a060ec9c305a82de1babc1056e73bd64dce"
+ integrity sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg==
+
+"@types/range-parser@*":
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb"
+ integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==
+
+"@types/retry@0.12.2":
+ version "0.12.2"
+ resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.2.tgz#ed279a64fa438bb69f2480eda44937912bb7480a"
+ integrity sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==
+
+"@types/send@*":
+ version "0.17.4"
+ resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a"
+ integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==
+ dependencies:
+ "@types/mime" "^1"
+ "@types/node" "*"
+
+"@types/serve-index@^1.9.4":
+ version "1.9.4"
+ resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898"
+ integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==
+ dependencies:
+ "@types/express" "*"
+
+"@types/serve-static@*", "@types/serve-static@^1.15.5":
+ version "1.15.7"
+ resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714"
+ integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==
+ dependencies:
+ "@types/http-errors" "*"
+ "@types/node" "*"
+ "@types/send" "*"
+
+"@types/sockjs@^0.3.36":
+ version "0.3.36"
+ resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535"
+ integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==
+ dependencies:
+ "@types/node" "*"
+
+"@types/ws@^8.5.10":
+ version "8.5.11"
+ resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.11.tgz#90ad17b3df7719ce3e6bc32f83ff954d38656508"
+ integrity sha512-4+q7P5h3SpJxaBft0Dzpbr6lmMaqh0Jr2tbhJZ/luAwvD7ohSCniYkwz/pLxuT2h0EOa6QADgJj1Ko+TzRfZ+w==
+ dependencies:
+ "@types/node" "*"
+
"@types/yauzl@^2.9.1":
version "2.10.2"
resolved "https://registry.yarnpkg.com/@types/yauzl/-/yauzl-2.10.2.tgz#dab926ef9b41a898bc943f11bca6b0bad6d4b729"
@@ -152,10 +334,10 @@
dependencies:
"@types/node" "*"
-"@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5":
- version "1.11.6"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24"
- integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==
+"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1":
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb"
+ integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==
dependencies:
"@webassemblyjs/helper-numbers" "1.11.6"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
@@ -170,10 +352,10 @@
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768"
integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==
-"@webassemblyjs/helper-buffer@1.11.6":
- version "1.11.6"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093"
- integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==
+"@webassemblyjs/helper-buffer@1.12.1":
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz#6df20d272ea5439bf20ab3492b7fb70e9bfcb3f6"
+ integrity sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==
"@webassemblyjs/helper-numbers@1.11.6":
version "1.11.6"
@@ -189,15 +371,15 @@
resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9"
integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==
-"@webassemblyjs/helper-wasm-section@1.11.6":
- version "1.11.6"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577"
- integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==
+"@webassemblyjs/helper-wasm-section@1.12.1":
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz#3da623233ae1a60409b509a52ade9bc22a37f7bf"
+ integrity sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==
dependencies:
- "@webassemblyjs/ast" "1.11.6"
- "@webassemblyjs/helper-buffer" "1.11.6"
+ "@webassemblyjs/ast" "1.12.1"
+ "@webassemblyjs/helper-buffer" "1.12.1"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
- "@webassemblyjs/wasm-gen" "1.11.6"
+ "@webassemblyjs/wasm-gen" "1.12.1"
"@webassemblyjs/ieee754@1.11.6":
version "1.11.6"
@@ -218,72 +400,72 @@
resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a"
integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==
-"@webassemblyjs/wasm-edit@^1.11.5":
- version "1.11.6"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab"
- integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==
+"@webassemblyjs/wasm-edit@^1.12.1":
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b"
+ integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==
dependencies:
- "@webassemblyjs/ast" "1.11.6"
- "@webassemblyjs/helper-buffer" "1.11.6"
+ "@webassemblyjs/ast" "1.12.1"
+ "@webassemblyjs/helper-buffer" "1.12.1"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
- "@webassemblyjs/helper-wasm-section" "1.11.6"
- "@webassemblyjs/wasm-gen" "1.11.6"
- "@webassemblyjs/wasm-opt" "1.11.6"
- "@webassemblyjs/wasm-parser" "1.11.6"
- "@webassemblyjs/wast-printer" "1.11.6"
-
-"@webassemblyjs/wasm-gen@1.11.6":
- version "1.11.6"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268"
- integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==
- dependencies:
- "@webassemblyjs/ast" "1.11.6"
+ "@webassemblyjs/helper-wasm-section" "1.12.1"
+ "@webassemblyjs/wasm-gen" "1.12.1"
+ "@webassemblyjs/wasm-opt" "1.12.1"
+ "@webassemblyjs/wasm-parser" "1.12.1"
+ "@webassemblyjs/wast-printer" "1.12.1"
+
+"@webassemblyjs/wasm-gen@1.12.1":
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz#a6520601da1b5700448273666a71ad0a45d78547"
+ integrity sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==
+ dependencies:
+ "@webassemblyjs/ast" "1.12.1"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
"@webassemblyjs/ieee754" "1.11.6"
"@webassemblyjs/leb128" "1.11.6"
"@webassemblyjs/utf8" "1.11.6"
-"@webassemblyjs/wasm-opt@1.11.6":
- version "1.11.6"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2"
- integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==
+"@webassemblyjs/wasm-opt@1.12.1":
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz#9e6e81475dfcfb62dab574ac2dda38226c232bc5"
+ integrity sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==
dependencies:
- "@webassemblyjs/ast" "1.11.6"
- "@webassemblyjs/helper-buffer" "1.11.6"
- "@webassemblyjs/wasm-gen" "1.11.6"
- "@webassemblyjs/wasm-parser" "1.11.6"
+ "@webassemblyjs/ast" "1.12.1"
+ "@webassemblyjs/helper-buffer" "1.12.1"
+ "@webassemblyjs/wasm-gen" "1.12.1"
+ "@webassemblyjs/wasm-parser" "1.12.1"
-"@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5":
- version "1.11.6"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1"
- integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==
+"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1":
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937"
+ integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==
dependencies:
- "@webassemblyjs/ast" "1.11.6"
+ "@webassemblyjs/ast" "1.12.1"
"@webassemblyjs/helper-api-error" "1.11.6"
"@webassemblyjs/helper-wasm-bytecode" "1.11.6"
"@webassemblyjs/ieee754" "1.11.6"
"@webassemblyjs/leb128" "1.11.6"
"@webassemblyjs/utf8" "1.11.6"
-"@webassemblyjs/wast-printer@1.11.6":
- version "1.11.6"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20"
- integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==
+"@webassemblyjs/wast-printer@1.12.1":
+ version "1.12.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz#bcecf661d7d1abdaf989d8341a4833e33e2b31ac"
+ integrity sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==
dependencies:
- "@webassemblyjs/ast" "1.11.6"
+ "@webassemblyjs/ast" "1.12.1"
"@xtuc/long" "4.2.2"
-"@webpack-cli/configtest@^2.1.0":
+"@webpack-cli/configtest@^2.1.1":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646"
integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==
-"@webpack-cli/info@^2.0.1":
+"@webpack-cli/info@^2.0.2":
version "2.0.2"
resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd"
integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==
-"@webpack-cli/serve@^2.0.3":
+"@webpack-cli/serve@^2.0.5":
version "2.0.5"
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e"
integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==
@@ -298,11 +480,6 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==
-abab@^2.0.6:
- version "2.0.6"
- resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291"
- integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==
-
abort-controller@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392"
@@ -310,7 +487,7 @@ abort-controller@3.0.0:
dependencies:
event-target-shim "^5.0.0"
-accepts@~1.3.4:
+accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8:
version "1.3.8"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
@@ -318,7 +495,7 @@ accepts@~1.3.4:
mime-types "~2.1.34"
negotiator "0.6.3"
-acorn-import-assertions@^1.7.6:
+acorn-import-assertions@^1.9.0:
version "1.9.0"
resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac"
integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==
@@ -340,11 +517,25 @@ agent-base@^7.0.2, agent-base@^7.1.0:
dependencies:
debug "^4.3.4"
+ajv-formats@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520"
+ integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==
+ dependencies:
+ ajv "^8.0.0"
+
ajv-keywords@^3.5.2:
version "3.5.2"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d"
integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==
+ajv-keywords@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16"
+ integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+
ajv@^6.12.5:
version "6.12.6"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4"
@@ -355,16 +546,36 @@ ajv@^6.12.5:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
+ajv@^8.0.0, ajv@^8.9.0:
+ version "8.16.0"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.16.0.tgz#22e2a92b94f005f7e0f9c9d39652ef0b8f6f0cb4"
+ integrity sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+ json-schema-traverse "^1.0.0"
+ require-from-string "^2.0.2"
+ uri-js "^4.4.1"
+
ansi-colors@4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348"
integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==
+ansi-html-community@^0.0.8:
+ version "0.0.8"
+ resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41"
+ integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==
+
ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
+ansi-regex@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
+ integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
+
ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
@@ -379,6 +590,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
+ansi-styles@^6.1.0:
+ version "6.2.1"
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
+ integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
+
anymatch@~3.1.2:
version "3.1.3"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
@@ -392,6 +608,11 @@ argparse@^2.0.1:
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
+array-flatten@1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
+ integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==
+
ast-types@^0.13.4:
version "0.13.4"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.13.4.tgz#ee0d77b343263965ecc3fb62da16e7222b2b6782"
@@ -424,12 +645,17 @@ basic-ftp@^5.0.2:
resolved "https://registry.yarnpkg.com/basic-ftp/-/basic-ftp-5.0.3.tgz#b14c0fe8111ce001ec913686434fe0c2fb461228"
integrity sha512-QHX8HLlncOLpy54mh+k/sWIFd0ThmRqwe9ZjELybGZK+tZ8rUb9VO0saKJUROTbE+KhzDUT7xziGpGrW8Kmd+g==
+batch@0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16"
+ integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==
+
binary-extensions@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==
-body-parser@^1.19.0:
+body-parser@1.20.2, body-parser@^1.19.0:
version "1.20.2"
resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd"
integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==
@@ -447,6 +673,14 @@ body-parser@^1.19.0:
type-is "~1.6.18"
unpipe "1.0.0"
+bonjour-service@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.2.1.tgz#eb41b3085183df3321da1264719fbada12478d02"
+ integrity sha512-oSzCS2zV14bh2kji6vNe7vrpJYCHGvcZnlffFQ1MEoX/WOeQ/teD8SYWKR942OI3INjq8OMNJlbPK5LLLUxFDw==
+ dependencies:
+ fast-deep-equal "^3.1.3"
+ multicast-dns "^7.2.5"
+
brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
@@ -469,20 +703,27 @@ braces@^3.0.2, braces@~3.0.2:
dependencies:
fill-range "^7.0.1"
+braces@^3.0.3:
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
+ integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
+ dependencies:
+ fill-range "^7.1.1"
+
browser-stdout@1.3.1:
version "1.3.1"
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60"
integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
-browserslist@^4.14.5:
- version "4.21.10"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.10.tgz#dbbac576628c13d3b2231332cb2ec5a46e015bb0"
- integrity sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==
+browserslist@^4.21.10:
+ version "4.23.2"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.2.tgz#244fe803641f1c19c28c48c4b6ec9736eb3d32ed"
+ integrity sha512-qkqSyistMYdxAcw+CzbZwlBy8AGmS/eEWs+sEV5TnLRGDOL+C5M2EnH6tlZyg0YoAxGJAFKh61En9BR941GnHA==
dependencies:
- caniuse-lite "^1.0.30001517"
- electron-to-chromium "^1.4.477"
- node-releases "^2.0.13"
- update-browserslist-db "^1.0.11"
+ caniuse-lite "^1.0.30001640"
+ electron-to-chromium "^1.4.820"
+ node-releases "^2.0.14"
+ update-browserslist-db "^1.1.0"
buffer-crc32@~0.2.3:
version "0.2.13"
@@ -502,6 +743,18 @@ buffer@^5.2.1:
base64-js "^1.3.1"
ieee754 "^1.1.13"
+bundle-name@^4.1.0:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889"
+ integrity sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==
+ dependencies:
+ run-applescript "^7.0.0"
+
+bytes@3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
+ integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==
+
bytes@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5"
@@ -525,10 +778,10 @@ camelcase@^6.0.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
-caniuse-lite@^1.0.30001517:
- version "1.0.30001534"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001534.tgz#f24a9b2a6d39630bac5c132b5dff89b39a12e7dd"
- integrity sha512-vlPVrhsCS7XaSh2VvWluIQEzVhefrUQcEsQWSS5A5V+dM07uv1qHeQzAOTGIMy9i3e9bH15+muvI/UHojVgS/Q==
+caniuse-lite@^1.0.30001640:
+ version "1.0.30001643"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001643.tgz#9c004caef315de9452ab970c3da71085f8241dbd"
+ integrity sha512-ERgWGNleEilSrHM6iUz/zJNSQTP8Mr21wDWpdgvRwcTXGAq6jMtOUPP4dqFPTdKqZ2wKTdtB+uucZ3MRpAUSmg==
chalk@^2.4.2:
version "2.4.2"
@@ -562,6 +815,21 @@ chokidar@3.5.3, chokidar@^3.5.1:
optionalDependencies:
fsevents "~2.3.2"
+chokidar@^3.6.0:
+ version "3.6.0"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
+ integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
+ dependencies:
+ anymatch "~3.1.2"
+ braces "~3.0.2"
+ glob-parent "~5.1.2"
+ is-binary-path "~2.1.0"
+ is-glob "~4.0.1"
+ normalize-path "~3.0.0"
+ readdirp "~3.6.0"
+ optionalDependencies:
+ fsevents "~2.3.2"
+
chrome-trace-event@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
@@ -626,7 +894,7 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-colorette@^2.0.14:
+colorette@^2.0.10, colorette@^2.0.14:
version "2.0.20"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
@@ -641,11 +909,36 @@ commander@^2.20.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
+compressible@~2.0.16:
+ version "2.0.18"
+ resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
+ integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==
+ dependencies:
+ mime-db ">= 1.43.0 < 2"
+
+compression@^1.7.4:
+ version "1.7.4"
+ resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
+ integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
+ dependencies:
+ accepts "~1.3.5"
+ bytes "3.0.0"
+ compressible "~2.0.16"
+ debug "2.6.9"
+ on-headers "~1.0.2"
+ safe-buffer "5.1.2"
+ vary "~1.1.2"
+
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
+connect-history-api-fallback@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8"
+ integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==
+
connect@^3.7.0:
version "3.7.0"
resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8"
@@ -656,16 +949,38 @@ connect@^3.7.0:
parseurl "~1.3.3"
utils-merge "1.0.1"
-content-type@~1.0.5:
+content-disposition@0.5.4:
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe"
+ integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==
+ dependencies:
+ safe-buffer "5.2.1"
+
+content-type@~1.0.4, content-type@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918"
integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==
+cookie-signature@1.0.6:
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
+ integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==
+
+cookie@0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051"
+ integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==
+
cookie@~0.4.1:
version "0.4.2"
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432"
integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==
+core-util-is@~1.0.0:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
+ integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
+
cors@~2.8.5:
version "2.8.5"
resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29"
@@ -691,7 +1006,7 @@ cross-fetch@4.0.0:
dependencies:
node-fetch "^2.6.12"
-cross-spawn@^7.0.3:
+cross-spawn@^7.0.0, cross-spawn@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
@@ -729,11 +1044,43 @@ debug@4, debug@4.3.4, debug@^4.1.1, debug@^4.3.4, debug@~4.3.1, debug@~4.3.2:
dependencies:
ms "2.1.2"
+debug@^4.1.0:
+ version "4.3.5"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.5.tgz#e83444eceb9fedd4a1da56d671ae2446a01a6e1e"
+ integrity sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==
+ dependencies:
+ ms "2.1.2"
+
decamelize@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837"
integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==
+default-browser-id@^5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-5.0.0.tgz#a1d98bf960c15082d8a3fa69e83150ccccc3af26"
+ integrity sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==
+
+default-browser@^5.2.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-5.2.1.tgz#7b7ba61204ff3e425b556869ae6d3e9d9f1712cf"
+ integrity sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==
+ dependencies:
+ bundle-name "^4.1.0"
+ default-browser-id "^5.0.0"
+
+default-gateway@^6.0.3:
+ version "6.0.3"
+ resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71"
+ integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==
+ dependencies:
+ execa "^5.0.0"
+
+define-lazy-prop@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f"
+ integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==
+
degenerator@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/degenerator/-/degenerator-5.0.1.tgz#9403bf297c6dad9a1ece409b37db27954f91f2f5"
@@ -748,11 +1095,21 @@ depd@2.0.0:
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==
+depd@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
+ integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==
+
destroy@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015"
integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==
+detect-node@^2.0.4:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1"
+ integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==
+
devtools-protocol@0.0.1191157:
version "0.0.1191157"
resolved "https://registry.yarnpkg.com/devtools-protocol/-/devtools-protocol-0.0.1191157.tgz#2a3e4d95b3fdb8696ab8c486e34d76519eb8715a"
@@ -768,6 +1125,13 @@ diff@5.0.0:
resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
+dns-packet@^5.2.2:
+ version "5.6.1"
+ resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f"
+ integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==
+ dependencies:
+ "@leichtgewicht/ip-codec" "^2.0.1"
+
dom-serialize@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/dom-serialize/-/dom-serialize-2.2.1.tgz#562ae8999f44be5ea3076f5419dcd59eb43ac95b"
@@ -778,21 +1142,31 @@ dom-serialize@^2.2.1:
extend "^3.0.0"
void-elements "^2.0.0"
+eastasianwidth@^0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
+ integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
+
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==
-electron-to-chromium@^1.4.477:
- version "1.4.519"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.519.tgz#01b9bc3f1bb50c4971bdd1eeca6d9a73575bd581"
- integrity sha512-kqs9oGYL4UFVkLKhqCTgBCYZv+wZ374yABDMqlDda9HvlkQxvSr7kgf4hfWVjMieDbX+1MwPHFBsOGCMIBaFKg==
+electron-to-chromium@^1.4.820:
+ version "1.5.1"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.1.tgz#24640bd4dcfaccb6d82bb4c3f4c7311503241581"
+ integrity sha512-FKbOCOQ5QRB3VlIbl1LZQefWIYwszlBloaXcY2rbfpu9ioJnNh3TK03YtIDKDo3WKBi8u+YV4+Fn2CkEozgf4w==
emoji-regex@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
+emoji-regex@^9.2.2:
+ version "9.2.2"
+ resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
+ integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
+
encodeurl@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59"
@@ -826,10 +1200,10 @@ engine.io@~6.5.2:
engine.io-parser "~5.2.1"
ws "~8.11.0"
-enhanced-resolve@^5.13.0:
- version "5.15.0"
- resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35"
- integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==
+enhanced-resolve@^5.16.0:
+ version "5.17.1"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15"
+ integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
@@ -861,6 +1235,11 @@ escalade@^3.1.1:
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
+escalade@^3.1.2:
+ version "3.1.2"
+ resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
+ integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
+
escape-html@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
@@ -922,6 +1301,11 @@ esutils@^2.0.2:
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64"
integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==
+etag@~1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
+ integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
+
event-target-shim@^5.0.0:
version "5.0.1"
resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789"
@@ -937,6 +1321,58 @@ events@^3.2.0:
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==
+execa@^5.0.0:
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
+ integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
+ dependencies:
+ cross-spawn "^7.0.3"
+ get-stream "^6.0.0"
+ human-signals "^2.1.0"
+ is-stream "^2.0.0"
+ merge-stream "^2.0.0"
+ npm-run-path "^4.0.1"
+ onetime "^5.1.2"
+ signal-exit "^3.0.3"
+ strip-final-newline "^2.0.0"
+
+express@^4.17.3:
+ version "4.19.2"
+ resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465"
+ integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==
+ dependencies:
+ accepts "~1.3.8"
+ array-flatten "1.1.1"
+ body-parser "1.20.2"
+ content-disposition "0.5.4"
+ content-type "~1.0.4"
+ cookie "0.6.0"
+ cookie-signature "1.0.6"
+ debug "2.6.9"
+ depd "2.0.0"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ finalhandler "1.2.0"
+ fresh "0.5.2"
+ http-errors "2.0.0"
+ merge-descriptors "1.0.1"
+ methods "~1.1.2"
+ on-finished "2.4.1"
+ parseurl "~1.3.3"
+ path-to-regexp "0.1.7"
+ proxy-addr "~2.0.7"
+ qs "6.11.0"
+ range-parser "~1.2.1"
+ safe-buffer "5.2.1"
+ send "0.18.0"
+ serve-static "1.15.0"
+ setprototypeof "1.2.0"
+ statuses "2.0.1"
+ type-is "~1.6.18"
+ utils-merge "1.0.1"
+ vary "~1.1.2"
+
extend@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
@@ -953,7 +1389,7 @@ extract-zip@2.0.1:
optionalDependencies:
"@types/yauzl" "^2.9.1"
-fast-deep-equal@^3.1.1:
+fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
version "3.1.3"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
@@ -973,6 +1409,13 @@ fastest-levenshtein@^1.0.12:
resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5"
integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==
+faye-websocket@^0.11.3:
+ version "0.11.4"
+ resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da"
+ integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==
+ dependencies:
+ websocket-driver ">=0.5.1"
+
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
@@ -987,6 +1430,13 @@ fill-range@^7.0.1:
dependencies:
to-regex-range "^5.0.1"
+fill-range@^7.1.1:
+ version "7.1.1"
+ resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
+ integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
+ dependencies:
+ to-regex-range "^5.0.1"
+
finalhandler@1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d"
@@ -1000,6 +1450,19 @@ finalhandler@1.1.2:
statuses "~1.5.0"
unpipe "~1.0.0"
+finalhandler@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32"
+ integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==
+ dependencies:
+ debug "2.6.9"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ on-finished "2.4.1"
+ parseurl "~1.3.3"
+ statuses "2.0.1"
+ unpipe "~1.0.0"
+
find-up@5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
@@ -1031,11 +1494,29 @@ follow-redirects@^1.0.0:
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
+foreground-child@^3.1.0:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.2.1.tgz#767004ccf3a5b30df39bed90718bab43fe0a59f7"
+ integrity sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==
+ dependencies:
+ cross-spawn "^7.0.0"
+ signal-exit "^4.0.1"
+
format-util@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271"
integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg==
+forwarded@0.2.0:
+ version "0.2.0"
+ resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
+ integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==
+
+fresh@0.5.2:
+ version "0.5.2"
+ resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"
+ integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==
+
fs-extra@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
@@ -1082,6 +1563,11 @@ get-stream@^5.1.0:
dependencies:
pump "^3.0.0"
+get-stream@^6.0.0:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
+ integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
+
get-uri@^6.0.1:
version "6.0.2"
resolved "https://registry.yarnpkg.com/get-uri/-/get-uri-6.0.2.tgz#e019521646f4a8ff6d291fbaea2c46da204bb75b"
@@ -1104,17 +1590,28 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
-glob@7.2.0:
- version "7.2.0"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
- integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
+glob@8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
+ integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
- minimatch "^3.0.4"
+ minimatch "^5.0.1"
once "^1.3.0"
- path-is-absolute "^1.0.0"
+
+glob@^10.3.7:
+ version "10.4.5"
+ resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
+ integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
+ dependencies:
+ foreground-child "^3.1.0"
+ jackspeak "^3.1.2"
+ minimatch "^9.0.4"
+ minipass "^7.1.2"
+ package-json-from-dist "^1.0.0"
+ path-scurry "^1.11.1"
glob@^7.1.3, glob@^7.1.7:
version "7.2.3"
@@ -1128,11 +1625,16 @@ glob@^7.1.3, glob@^7.1.7:
once "^1.3.0"
path-is-absolute "^1.0.0"
-graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9:
+graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.10, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6:
version "4.2.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3"
integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==
+handle-thing@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
+ integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==
+
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -1165,6 +1667,26 @@ he@1.2.0:
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
+hpack.js@^2.1.6:
+ version "2.1.6"
+ resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2"
+ integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==
+ dependencies:
+ inherits "^2.0.1"
+ obuf "^1.0.0"
+ readable-stream "^2.0.1"
+ wbuf "^1.1.0"
+
+html-entities@^2.4.0:
+ version "2.5.2"
+ resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.5.2.tgz#201a3cf95d3a15be7099521620d19dfb4f65359f"
+ integrity sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==
+
+http-deceiver@^1.2.7:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87"
+ integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==
+
http-errors@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3"
@@ -1176,6 +1698,21 @@ http-errors@2.0.0:
statuses "2.0.1"
toidentifier "1.0.1"
+http-errors@~1.6.2:
+ version "1.6.3"
+ resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d"
+ integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==
+ dependencies:
+ depd "~1.1.2"
+ inherits "2.0.3"
+ setprototypeof "1.1.0"
+ statuses ">= 1.4.0 < 2"
+
+http-parser-js@>=0.5.1:
+ version "0.5.8"
+ resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3"
+ integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==
+
http-proxy-agent@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz#e9096c5afd071a3fce56e6252bb321583c124673"
@@ -1184,6 +1721,17 @@ http-proxy-agent@^7.0.0:
agent-base "^7.1.0"
debug "^4.3.4"
+http-proxy-middleware@^2.0.3:
+ version "2.0.6"
+ resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f"
+ integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==
+ dependencies:
+ "@types/http-proxy" "^1.17.8"
+ http-proxy "^1.18.1"
+ is-glob "^4.0.1"
+ is-plain-obj "^3.0.0"
+ micromatch "^4.0.2"
+
http-proxy@^1.18.1:
version "1.18.1"
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
@@ -1201,6 +1749,16 @@ https-proxy-agent@^7.0.2:
agent-base "^7.0.2"
debug "4"
+human-signals@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
+ integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
+
+hyperdyperid@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/hyperdyperid/-/hyperdyperid-1.2.0.tgz#59668d323ada92228d2a869d3e474d5a33b69e6b"
+ integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==
+
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -1244,11 +1802,16 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@2, inherits@2.0.4:
+inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
version "2.0.4"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
+inherits@2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
+ integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==
+
interpret@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4"
@@ -1264,6 +1827,16 @@ ip@^2.0.0:
resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da"
integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==
+ipaddr.js@1.9.1:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
+ integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==
+
+ipaddr.js@^2.1.0:
+ version "2.2.0"
+ resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8"
+ integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==
+
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
@@ -1283,6 +1856,11 @@ is-core-module@^2.13.0:
dependencies:
has "^1.0.3"
+is-docker@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200"
+ integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==
+
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
@@ -1300,6 +1878,18 @@ is-glob@^4.0.1, is-glob@~4.0.1:
dependencies:
is-extglob "^2.1.1"
+is-inside-container@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4"
+ integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==
+ dependencies:
+ is-docker "^3.0.0"
+
+is-network-error@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/is-network-error/-/is-network-error-1.1.0.tgz#d26a760e3770226d11c169052f266a4803d9c997"
+ integrity sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==
+
is-number@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
@@ -1310,6 +1900,11 @@ is-plain-obj@^2.1.0:
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287"
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==
+is-plain-obj@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7"
+ integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==
+
is-plain-object@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677"
@@ -1317,11 +1912,28 @@ is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
+is-stream@^2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
+ integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
+
is-unicode-supported@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7"
integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==
+is-wsl@^3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-3.1.0.tgz#e1c657e39c10090afcbedec61720f6b924c3cbd2"
+ integrity sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==
+ dependencies:
+ is-inside-container "^1.0.0"
+
+isarray@~1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
+ integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==
+
isbinaryfile@^4.0.8:
version "4.0.10"
resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-4.0.10.tgz#0c5b5e30c2557a2f06febd37b7322946aaee42b3"
@@ -1337,6 +1949,15 @@ isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==
+jackspeak@^3.1.2:
+ version "3.4.3"
+ resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a"
+ integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==
+ dependencies:
+ "@isaacs/cliui" "^8.0.2"
+ optionalDependencies:
+ "@pkgjs/parseargs" "^0.11.0"
+
jest-worker@^27.4.5:
version "27.5.1"
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0"
@@ -1368,6 +1989,11 @@ json-schema-traverse@^0.4.1:
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==
+json-schema-traverse@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
+ integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
+
jsonfile@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
@@ -1396,19 +2022,19 @@ karma-sourcemap-loader@0.4.0:
dependencies:
graceful-fs "^4.2.10"
-karma-webpack@5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.0.tgz#2a2c7b80163fe7ffd1010f83f5507f95ef39f840"
- integrity sha512-+54i/cd3/piZuP3dr54+NcFeKOPnys5QeM1IY+0SPASwrtHsliXUiCL50iW+K9WWA7RvamC4macvvQ86l3KtaA==
+karma-webpack@5.0.1:
+ version "5.0.1"
+ resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-5.0.1.tgz#4eafd31bbe684a747a6e8f3e4ad373e53979ced4"
+ integrity sha512-oo38O+P3W2mSPCSUrQdySSPv1LvPpXP+f+bBimNomS5sW+1V4SuhCuW8TfJzV+rDv921w2fDSDw0xJbPe6U+kQ==
dependencies:
glob "^7.1.3"
- minimatch "^3.0.4"
+ minimatch "^9.0.3"
webpack-merge "^4.1.5"
-karma@6.4.2:
- version "6.4.2"
- resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.2.tgz#a983f874cee6f35990c4b2dcc3d274653714de8e"
- integrity sha512-C6SU/53LB31BEgRg+omznBEMY4SjHU3ricV6zBcAe1EeILKkeScr+fZXtaI5WyDbkVowJxxAI6h73NcFPmXolQ==
+karma@6.4.3:
+ version "6.4.3"
+ resolved "https://registry.yarnpkg.com/karma/-/karma-6.4.3.tgz#763e500f99597218bbb536de1a14acc4ceea7ce8"
+ integrity sha512-LuucC/RE92tJ8mlCwqEoRWXP38UMAqpnq98vktmS9SznSoUPPUJQbc91dHcxcunROvfQjdORVA/YFviH+Xci9Q==
dependencies:
"@colors/colors" "1.5.0"
body-parser "^1.19.0"
@@ -1429,7 +2055,7 @@ karma@6.4.2:
qjobs "^1.2.0"
range-parser "^1.2.1"
rimraf "^3.0.2"
- socket.io "^4.4.1"
+ socket.io "^4.7.2"
source-map "^0.6.1"
tmp "^0.2.1"
ua-parser-js "^0.7.30"
@@ -1440,6 +2066,14 @@ kind-of@^6.0.2:
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd"
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
+launch-editor@^2.6.1:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.8.0.tgz#7255d90bdba414448e2138faa770a74f28451305"
+ integrity sha512-vJranOAJrI/llyWGRQqiDM+adrw+k83fvmmx3+nV47g3+36xM15jE+zyZ6Ffel02+xSvuM0b2GDRosXZkbb6wA==
+ dependencies:
+ picocolors "^1.0.0"
+ shell-quote "^1.8.1"
+
lines-and-columns@^1.1.6:
version "1.2.4"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
@@ -1488,6 +2122,11 @@ log4js@^6.4.1:
rfdc "^1.3.0"
streamroller "^3.1.5"
+lru-cache@^10.2.0:
+ version "10.4.3"
+ resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
+ integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
+
lru-cache@^7.14.1:
version "7.18.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89"
@@ -1498,28 +2137,71 @@ media-typer@0.3.0:
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==
+memfs@^4.6.0:
+ version "4.9.4"
+ resolved "https://registry.yarnpkg.com/memfs/-/memfs-4.9.4.tgz#803eb7f2091d1c6198ec9ba9b582505ad8699c9e"
+ integrity sha512-Xlj8b2rU11nM6+KU6wC7cuWcHQhVINWCUgdPS4Ar9nPxLaOya3RghqK7ALyDW2QtGebYAYs6uEdEVnwPVT942A==
+ dependencies:
+ "@jsonjoy.com/json-pack" "^1.0.3"
+ "@jsonjoy.com/util" "^1.1.2"
+ tree-dump "^1.0.1"
+ tslib "^2.0.0"
+
+merge-descriptors@1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
+ integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==
+
merge-stream@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
-mime-db@1.52.0:
+methods@~1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
+ integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
+
+micromatch@^4.0.2:
+ version "4.0.7"
+ resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.7.tgz#33e8190d9fe474a9895525f5618eee136d46c2e5"
+ integrity sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==
+ dependencies:
+ braces "^3.0.3"
+ picomatch "^2.3.1"
+
+mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
version "1.52.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
-mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34:
+mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"
+mime@1.6.0:
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
+ integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
+
mime@^2.5.2:
version "2.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367"
integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==
+mimic-fn@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
+ integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
+
+minimalistic-assert@^1.0.0:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
+ integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
+
minimatch@5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b"
@@ -1534,11 +2216,30 @@ minimatch@^3.0.4, minimatch@^3.1.1:
dependencies:
brace-expansion "^1.1.7"
+minimatch@^5.0.1:
+ version "5.1.6"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
+ integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
+ dependencies:
+ brace-expansion "^2.0.1"
+
+minimatch@^9.0.3, minimatch@^9.0.4:
+ version "9.0.5"
+ resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
+ integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
+ dependencies:
+ brace-expansion "^2.0.1"
+
minimist@^1.2.3, minimist@^1.2.6:
version "1.2.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
+"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
+ version "7.1.2"
+ resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
+ integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
+
mitt@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/mitt/-/mitt-3.0.1.tgz#ea36cf0cc30403601ae074c8f77b7092cdab36d1"
@@ -1556,10 +2257,10 @@ mkdirp@^0.5.5:
dependencies:
minimist "^1.2.6"
-mocha@10.2.0:
- version "10.2.0"
- resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8"
- integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==
+mocha@10.3.0:
+ version "10.3.0"
+ resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.3.0.tgz#0e185c49e6dccf582035c05fa91084a4ff6e3fe9"
+ integrity sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==
dependencies:
ansi-colors "4.1.1"
browser-stdout "1.3.1"
@@ -1568,13 +2269,12 @@ mocha@10.2.0:
diff "5.0.0"
escape-string-regexp "4.0.0"
find-up "5.0.0"
- glob "7.2.0"
+ glob "8.1.0"
he "1.2.0"
js-yaml "4.1.0"
log-symbols "4.1.0"
minimatch "5.0.1"
ms "2.1.3"
- nanoid "3.3.3"
serialize-javascript "6.0.0"
strip-json-comments "3.1.1"
supports-color "8.1.1"
@@ -1598,10 +2298,13 @@ ms@2.1.3:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
-nanoid@3.3.3:
- version "3.3.3"
- resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25"
- integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w==
+multicast-dns@^7.2.5:
+ version "7.2.5"
+ resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced"
+ integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==
+ dependencies:
+ dns-packet "^5.2.2"
+ thunky "^1.0.2"
negotiator@0.6.3:
version "0.6.3"
@@ -1632,16 +2335,28 @@ node-fetch@^2.6.12:
dependencies:
whatwg-url "^5.0.0"
-node-releases@^2.0.13:
- version "2.0.13"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d"
- integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==
+node-forge@^1:
+ version "1.3.1"
+ resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3"
+ integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==
+
+node-releases@^2.0.14:
+ version "2.0.18"
+ resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f"
+ integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==
normalize-path@^3.0.0, normalize-path@~3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
+npm-run-path@^4.0.1:
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
+ integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
+ dependencies:
+ path-key "^3.0.0"
+
object-assign@^4:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
@@ -1652,7 +2367,12 @@ object-inspect@^1.9.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9"
integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==
-on-finished@2.4.1:
+obuf@^1.0.0, obuf@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e"
+ integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==
+
+on-finished@2.4.1, on-finished@^2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==
@@ -1666,6 +2386,11 @@ on-finished@~2.3.0:
dependencies:
ee-first "1.1.1"
+on-headers@~1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
+ integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
+
once@^1.3.0, once@^1.3.1, once@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
@@ -1673,6 +2398,23 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
+onetime@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
+ integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
+ dependencies:
+ mimic-fn "^2.1.0"
+
+open@^10.0.3:
+ version "10.1.0"
+ resolved "https://registry.yarnpkg.com/open/-/open-10.1.0.tgz#a7795e6e5d519abe4286d9937bb24b51122598e1"
+ integrity sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==
+ dependencies:
+ default-browser "^5.2.1"
+ define-lazy-prop "^3.0.0"
+ is-inside-container "^1.0.0"
+ is-wsl "^3.1.0"
+
p-limit@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
@@ -1701,6 +2443,15 @@ p-locate@^5.0.0:
dependencies:
p-limit "^3.0.2"
+p-retry@^6.2.0:
+ version "6.2.0"
+ resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-6.2.0.tgz#8d6df01af298750009691ce2f9b3ad2d5968f3bd"
+ integrity sha512-JA6nkq6hKyWLLasXQXUrO4z8BUZGUt/LjlJxx8Gb2+2ntodU/SS63YZ8b0LUTbQ8ZB9iwOfhEPhg4ykKnn2KsA==
+ dependencies:
+ "@types/retry" "0.12.2"
+ is-network-error "^1.0.0"
+ retry "^0.13.1"
+
p-try@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
@@ -1729,6 +2480,11 @@ pac-resolver@^7.0.0:
ip "^1.1.8"
netmask "^2.0.2"
+package-json-from-dist@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz#e501cd3094b278495eb4258d4c9f6d5ac3019f00"
+ integrity sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==
+
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@@ -1746,7 +2502,7 @@ parse-json@^5.2.0:
json-parse-even-better-errors "^2.3.0"
lines-and-columns "^1.1.6"
-parseurl@~1.3.3:
+parseurl@~1.3.2, parseurl@~1.3.3:
version "1.3.3"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
@@ -1761,7 +2517,7 @@ path-is-absolute@^1.0.0:
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==
-path-key@^3.1.0:
+path-key@^3.0.0, path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
@@ -1771,6 +2527,19 @@ path-parse@^1.0.7:
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
+path-scurry@^1.11.1:
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2"
+ integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==
+ dependencies:
+ lru-cache "^10.2.0"
+ minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
+
+path-to-regexp@0.1.7:
+ version "0.1.7"
+ resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
+ integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==
+
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
@@ -1786,7 +2555,12 @@ picocolors@^1.0.0:
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
-picomatch@^2.0.4, picomatch@^2.2.1:
+picocolors@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1"
+ integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
+
+picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
@@ -1798,11 +2572,24 @@ pkg-dir@^4.2.0:
dependencies:
find-up "^4.0.0"
+process-nextick-args@~2.0.0:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
+ integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
+
progress@2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
+proxy-addr@~2.0.7:
+ version "2.0.7"
+ resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025"
+ integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==
+ dependencies:
+ forwarded "0.2.0"
+ ipaddr.js "1.9.1"
+
proxy-agent@6.3.1:
version "6.3.1"
resolved "https://registry.yarnpkg.com/proxy-agent/-/proxy-agent-6.3.1.tgz#40e7b230552cf44fd23ffaf7c59024b692612687"
@@ -1880,7 +2667,7 @@ randombytes@^2.1.0:
dependencies:
safe-buffer "^5.1.0"
-range-parser@^1.2.1:
+range-parser@^1.2.1, range-parser@~1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"
integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==
@@ -1895,6 +2682,28 @@ raw-body@2.5.2:
iconv-lite "0.4.24"
unpipe "1.0.0"
+readable-stream@^2.0.1:
+ version "2.3.8"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
+ integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
+ dependencies:
+ core-util-is "~1.0.0"
+ inherits "~2.0.3"
+ isarray "~1.0.0"
+ process-nextick-args "~2.0.0"
+ safe-buffer "~5.1.1"
+ string_decoder "~1.1.1"
+ util-deprecate "~1.0.1"
+
+readable-stream@^3.0.6:
+ version "3.6.2"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
+ integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
@@ -1914,6 +2723,11 @@ require-directory@^2.1.1:
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==
+require-from-string@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
+ integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
+
requires-port@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
@@ -1945,6 +2759,11 @@ resolve@^1.20.0:
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
+retry@^0.13.1:
+ version "0.13.1"
+ resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658"
+ integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==
+
rfdc@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
@@ -1957,7 +2776,24 @@ rimraf@^3.0.0, rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
-safe-buffer@^5.1.0:
+rimraf@^5.0.5:
+ version "5.0.9"
+ resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-5.0.9.tgz#c3baa1b886eadc2ec7981a06a593c3d01134ffe9"
+ integrity sha512-3i7b8OcswU6CpU8Ej89quJD4O98id7TtVM5U4Mybh84zQXdrFmDLouWBEEaD/QfO3gDDfH+AGFCGsR7kngzQnA==
+ dependencies:
+ glob "^10.3.7"
+
+run-applescript@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-7.0.0.tgz#e5a553c2bffd620e169d276c1cd8f1b64778fbeb"
+ integrity sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==
+
+safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
+ integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
+
+safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0:
version "5.2.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
@@ -1967,7 +2803,7 @@ safe-buffer@^5.1.0:
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-schema-utils@^3.1.1, schema-utils@^3.1.2:
+schema-utils@^3.1.1, schema-utils@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe"
integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==
@@ -1976,6 +2812,48 @@ schema-utils@^3.1.1, schema-utils@^3.1.2:
ajv "^6.12.5"
ajv-keywords "^3.5.2"
+schema-utils@^4.0.0, schema-utils@^4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b"
+ integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw==
+ dependencies:
+ "@types/json-schema" "^7.0.9"
+ ajv "^8.9.0"
+ ajv-formats "^2.1.1"
+ ajv-keywords "^5.1.0"
+
+select-hose@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
+ integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==
+
+selfsigned@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0"
+ integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==
+ dependencies:
+ "@types/node-forge" "^1.3.0"
+ node-forge "^1"
+
+send@0.18.0:
+ version "0.18.0"
+ resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be"
+ integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==
+ dependencies:
+ debug "2.6.9"
+ depd "2.0.0"
+ destroy "1.2.0"
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ etag "~1.8.1"
+ fresh "0.5.2"
+ http-errors "2.0.0"
+ mime "1.6.0"
+ ms "2.1.3"
+ on-finished "2.4.1"
+ range-parser "~1.2.1"
+ statuses "2.0.1"
+
serialize-javascript@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
@@ -1990,6 +2868,34 @@ serialize-javascript@^6.0.1:
dependencies:
randombytes "^2.1.0"
+serve-index@^1.9.1:
+ version "1.9.1"
+ resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239"
+ integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==
+ dependencies:
+ accepts "~1.3.4"
+ batch "0.6.1"
+ debug "2.6.9"
+ escape-html "~1.0.3"
+ http-errors "~1.6.2"
+ mime-types "~2.1.17"
+ parseurl "~1.3.2"
+
+serve-static@1.15.0:
+ version "1.15.0"
+ resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540"
+ integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==
+ dependencies:
+ encodeurl "~1.0.2"
+ escape-html "~1.0.3"
+ parseurl "~1.3.3"
+ send "0.18.0"
+
+setprototypeof@1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
+ integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==
+
setprototypeof@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424"
@@ -2014,6 +2920,11 @@ shebang-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
+shell-quote@^1.8.1:
+ version "1.8.1"
+ resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680"
+ integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==
+
side-channel@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf"
@@ -2023,6 +2934,16 @@ side-channel@^1.0.4:
get-intrinsic "^1.0.2"
object-inspect "^1.9.0"
+signal-exit@^3.0.3:
+ version "3.0.7"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
+ integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
+
+signal-exit@^4.0.1:
+ version "4.1.0"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
+ integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
+
smart-buffer@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae"
@@ -2043,10 +2964,10 @@ socket.io-parser@~4.2.4:
"@socket.io/component-emitter" "~3.1.0"
debug "~4.3.1"
-socket.io@^4.4.1:
- version "4.7.2"
- resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.7.2.tgz#22557d76c3f3ca48f82e73d68b7add36a22df002"
- integrity sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==
+socket.io@^4.7.2:
+ version "4.7.5"
+ resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.7.5.tgz#56eb2d976aef9d1445f373a62d781a41c7add8f8"
+ integrity sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==
dependencies:
accepts "~1.3.4"
base64id "~2.0.0"
@@ -2056,6 +2977,15 @@ socket.io@^4.4.1:
socket.io-adapter "~2.5.2"
socket.io-parser "~4.2.4"
+sockjs@^0.3.24:
+ version "0.3.24"
+ resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce"
+ integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==
+ dependencies:
+ faye-websocket "^0.11.3"
+ uuid "^8.3.2"
+ websocket-driver "^0.7.4"
+
socks-proxy-agent@^8.0.2:
version "8.0.2"
resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-8.0.2.tgz#5acbd7be7baf18c46a3f293a840109a430a640ad"
@@ -2078,12 +3008,11 @@ source-map-js@^1.0.2:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
-source-map-loader@4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-4.0.1.tgz#72f00d05f5d1f90f80974eda781cbd7107c125f2"
- integrity sha512-oqXpzDIByKONVY8g1NUPOTQhe0UTU5bWUl32GSkqK2LjJj0HmwTMVKxcUip0RgAYhY1mqgOxjbQM48a0mmeNfA==
+source-map-loader@5.0.0:
+ version "5.0.0"
+ resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-5.0.0.tgz#f593a916e1cc54471cfc8851b905c8a845fc7e38"
+ integrity sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==
dependencies:
- abab "^2.0.6"
iconv-lite "^0.6.3"
source-map-js "^1.0.2"
@@ -2100,12 +3029,35 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+spdy-transport@^3.0.0:
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31"
+ integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==
+ dependencies:
+ debug "^4.1.0"
+ detect-node "^2.0.4"
+ hpack.js "^2.1.6"
+ obuf "^1.1.2"
+ readable-stream "^3.0.6"
+ wbuf "^1.7.3"
+
+spdy@^4.0.2:
+ version "4.0.2"
+ resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b"
+ integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==
+ dependencies:
+ debug "^4.1.0"
+ handle-thing "^2.0.0"
+ http-deceiver "^1.2.7"
+ select-hose "^2.0.0"
+ spdy-transport "^3.0.0"
+
statuses@2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63"
integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==
-statuses@~1.5.0:
+"statuses@>= 1.4.0 < 2", statuses@~1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
@@ -2127,7 +3079,7 @@ streamx@^2.15.0:
fast-fifo "^1.1.0"
queue-tick "^1.0.1"
-string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -2136,13 +3088,48 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+string-width@^5.0.1, string-width@^5.1.2:
+ version "5.1.2"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
+ integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
+ dependencies:
+ eastasianwidth "^0.2.0"
+ emoji-regex "^9.2.2"
+ strip-ansi "^7.0.1"
+
+string_decoder@^1.1.1:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
+ integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+ dependencies:
+ safe-buffer "~5.2.0"
+
+string_decoder@~1.1.1:
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
+ integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==
+ dependencies:
+ safe-buffer "~5.1.0"
+
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
ansi-regex "^5.0.1"
+strip-ansi@^7.0.1:
+ version "7.1.0"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
+ integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
+ dependencies:
+ ansi-regex "^6.0.1"
+
+strip-final-newline@^2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
+ integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
+
strip-json-comments@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
@@ -2197,32 +3184,42 @@ tar-stream@^3.1.5:
fast-fifo "^1.2.0"
streamx "^2.15.0"
-terser-webpack-plugin@^5.3.7:
- version "5.3.9"
- resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1"
- integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==
+terser-webpack-plugin@^5.3.10:
+ version "5.3.10"
+ resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199"
+ integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==
dependencies:
- "@jridgewell/trace-mapping" "^0.3.17"
+ "@jridgewell/trace-mapping" "^0.3.20"
jest-worker "^27.4.5"
schema-utils "^3.1.1"
serialize-javascript "^6.0.1"
- terser "^5.16.8"
+ terser "^5.26.0"
-terser@^5.16.8:
- version "5.19.4"
- resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.4.tgz#941426fa482bf9b40a0308ab2b3cd0cf7c775ebd"
- integrity sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g==
+terser@^5.26.0:
+ version "5.31.3"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.3.tgz#b24b7beb46062f4653f049eea4f0cd165d0f0c38"
+ integrity sha512-pAfYn3NIZLyZpa83ZKigvj6Rn9c/vd5KfYGX7cN1mnzqgDcxWvrU5ZtAfIKhEXz9nRecw4z3LXkjaq96/qZqAA==
dependencies:
"@jridgewell/source-map" "^0.3.3"
acorn "^8.8.2"
commander "^2.20.0"
source-map-support "~0.5.20"
+thingies@^1.20.0:
+ version "1.21.0"
+ resolved "https://registry.yarnpkg.com/thingies/-/thingies-1.21.0.tgz#e80fbe58fd6fdaaab8fad9b67bd0a5c943c445c1"
+ integrity sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==
+
through@^2.3.8:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==
+thunky@^1.0.2:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
+ integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==
+
tmp@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14"
@@ -2247,6 +3244,16 @@ tr46@~0.0.3:
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
+tree-dump@^1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/tree-dump/-/tree-dump-1.0.2.tgz#c460d5921caeb197bde71d0e9a7b479848c5b8ac"
+ integrity sha512-dpev9ABuLWdEubk+cIaI9cHwRNNDjkBBLXTwI4UCUFdQ5xXKqNXoK4FEciw/vxf+NQ7Cb7sGUyeUtORvHIdRXQ==
+
+tslib@^2.0.0:
+ version "2.6.3"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
+ integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==
+
tslib@^2.0.1:
version "2.6.2"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
@@ -2260,10 +3267,10 @@ type-is@~1.6.18:
media-typer "0.3.0"
mime-types "~2.1.24"
-typescript@5.0.4:
- version "5.0.4"
- resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b"
- integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==
+typescript@5.4.3:
+ version "5.4.3"
+ resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.4.3.tgz#5c6fedd4c87bee01cd7a528a30145521f8e0feff"
+ integrity sha512-KrPd3PKaCLr78MalgiwJnA25Nm8HAmdwN3mYUYZgG/wizIo9EainNVQI9/yDavtVFRN2h3k8uf3GLHuhDMgEHg==
ua-parser-js@^0.7.30:
version "0.7.36"
@@ -2288,15 +3295,15 @@ unpipe@1.0.0, unpipe@~1.0.0:
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==
-update-browserslist-db@^1.0.11:
- version "1.0.11"
- resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940"
- integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==
+update-browserslist-db@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e"
+ integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==
dependencies:
- escalade "^3.1.1"
- picocolors "^1.0.0"
+ escalade "^3.1.2"
+ picocolors "^1.0.1"
-uri-js@^4.2.2:
+uri-js@^4.2.2, uri-js@^4.4.1:
version "4.4.1"
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
@@ -2308,12 +3315,22 @@ urlpattern-polyfill@9.0.0:
resolved "https://registry.yarnpkg.com/urlpattern-polyfill/-/urlpattern-polyfill-9.0.0.tgz#bc7e386bb12fd7898b58d1509df21d3c29ab3460"
integrity sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==
+util-deprecate@^1.0.1, util-deprecate@~1.0.1:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
+ integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
+
utils-merge@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==
-vary@^1:
+uuid@^8.3.2:
+ version "8.3.2"
+ resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
+ integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
+
+vary@^1, vary@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
@@ -2323,28 +3340,35 @@ void-elements@^2.0.0:
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==
-watchpack@^2.4.0:
- version "2.4.0"
- resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d"
- integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==
+watchpack@^2.4.1:
+ version "2.4.1"
+ resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.1.tgz#29308f2cac150fa8e4c92f90e0ec954a9fed7fff"
+ integrity sha512-8wrBCMtVhqcXP2Sup1ctSkga6uc2Bx0IIvKyT7yTFier5AXHooSI+QyQQAtTb7+E0IUCCKyTFmXqdqgum2XWGg==
dependencies:
glob-to-regexp "^0.4.1"
graceful-fs "^4.1.2"
+wbuf@^1.1.0, wbuf@^1.7.3:
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df"
+ integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==
+ dependencies:
+ minimalistic-assert "^1.0.0"
+
webidl-conversions@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==
-webpack-cli@5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.0.tgz#abc4b1f44b50250f2632d8b8b536cfe2f6257891"
- integrity sha512-a7KRJnCxejFoDpYTOwzm5o21ZXMaNqtRlvS183XzGDUPRdVEzJNImcQokqYZ8BNTnk9DkKiuWxw75+DCCoZ26w==
+webpack-cli@5.1.4:
+ version "5.1.4"
+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b"
+ integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==
dependencies:
"@discoveryjs/json-ext" "^0.5.0"
- "@webpack-cli/configtest" "^2.1.0"
- "@webpack-cli/info" "^2.0.1"
- "@webpack-cli/serve" "^2.0.3"
+ "@webpack-cli/configtest" "^2.1.1"
+ "@webpack-cli/info" "^2.0.2"
+ "@webpack-cli/serve" "^2.0.5"
colorette "^2.0.14"
commander "^10.0.1"
cross-spawn "^7.0.3"
@@ -2355,6 +3379,54 @@ webpack-cli@5.1.0:
rechoir "^0.8.0"
webpack-merge "^5.7.3"
+webpack-dev-middleware@^7.1.0:
+ version "7.3.0"
+ resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-7.3.0.tgz#5975ea41271083dc5678886b99d4c058382fb311"
+ integrity sha512-xD2qnNew+F6KwOGZR7kWdbIou/ud7cVqLEXeK1q0nHcNsX/u7ul/fSdlOTX4ntSL5FNFy7ZJJXbf0piF591JYw==
+ dependencies:
+ colorette "^2.0.10"
+ memfs "^4.6.0"
+ mime-types "^2.1.31"
+ on-finished "^2.4.1"
+ range-parser "^1.2.1"
+ schema-utils "^4.0.0"
+
+webpack-dev-server@5.0.4:
+ version "5.0.4"
+ resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-5.0.4.tgz#cb6ea47ff796b9251ec49a94f24a425e12e3c9b8"
+ integrity sha512-dljXhUgx3HqKP2d8J/fUMvhxGhzjeNVarDLcbO/EWMSgRizDkxHQDZQaLFL5VJY9tRBj2Gz+rvCEYYvhbqPHNA==
+ dependencies:
+ "@types/bonjour" "^3.5.13"
+ "@types/connect-history-api-fallback" "^1.5.4"
+ "@types/express" "^4.17.21"
+ "@types/serve-index" "^1.9.4"
+ "@types/serve-static" "^1.15.5"
+ "@types/sockjs" "^0.3.36"
+ "@types/ws" "^8.5.10"
+ ansi-html-community "^0.0.8"
+ bonjour-service "^1.2.1"
+ chokidar "^3.6.0"
+ colorette "^2.0.10"
+ compression "^1.7.4"
+ connect-history-api-fallback "^2.0.0"
+ default-gateway "^6.0.3"
+ express "^4.17.3"
+ graceful-fs "^4.2.6"
+ html-entities "^2.4.0"
+ http-proxy-middleware "^2.0.3"
+ ipaddr.js "^2.1.0"
+ launch-editor "^2.6.1"
+ open "^10.0.3"
+ p-retry "^6.2.0"
+ rimraf "^5.0.5"
+ schema-utils "^4.2.0"
+ selfsigned "^2.4.1"
+ serve-index "^1.9.1"
+ sockjs "^0.3.24"
+ spdy "^4.0.2"
+ webpack-dev-middleware "^7.1.0"
+ ws "^8.16.0"
+
webpack-merge@^4.1.5:
version "4.2.2"
resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-4.2.2.tgz#a27c52ea783d1398afd2087f547d7b9d2f43634d"
@@ -2375,36 +3447,50 @@ webpack-sources@^3.2.3:
resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde"
integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==
-webpack@5.82.0:
- version "5.82.0"
- resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.82.0.tgz#3c0d074dec79401db026b4ba0fb23d6333f88e7d"
- integrity sha512-iGNA2fHhnDcV1bONdUu554eZx+XeldsaeQ8T67H6KKHl2nUSwX8Zm7cmzOA46ox/X1ARxf7Bjv8wQ/HsB5fxBg==
+webpack@5.91.0:
+ version "5.91.0"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.91.0.tgz#ffa92c1c618d18c878f06892bbdc3373c71a01d9"
+ integrity sha512-rzVwlLeBWHJbmgTC/8TvAcu5vpJNII+MelQpylD4jNERPwpBJOE2lEcko1zJX3QJeLjTTAnQxn/OJ8bjDzVQaw==
dependencies:
"@types/eslint-scope" "^3.7.3"
- "@types/estree" "^1.0.0"
- "@webassemblyjs/ast" "^1.11.5"
- "@webassemblyjs/wasm-edit" "^1.11.5"
- "@webassemblyjs/wasm-parser" "^1.11.5"
+ "@types/estree" "^1.0.5"
+ "@webassemblyjs/ast" "^1.12.1"
+ "@webassemblyjs/wasm-edit" "^1.12.1"
+ "@webassemblyjs/wasm-parser" "^1.12.1"
acorn "^8.7.1"
- acorn-import-assertions "^1.7.6"
- browserslist "^4.14.5"
+ acorn-import-assertions "^1.9.0"
+ browserslist "^4.21.10"
chrome-trace-event "^1.0.2"
- enhanced-resolve "^5.13.0"
+ enhanced-resolve "^5.16.0"
es-module-lexer "^1.2.1"
eslint-scope "5.1.1"
events "^3.2.0"
glob-to-regexp "^0.4.1"
- graceful-fs "^4.2.9"
+ graceful-fs "^4.2.11"
json-parse-even-better-errors "^2.3.1"
loader-runner "^4.2.0"
mime-types "^2.1.27"
neo-async "^2.6.2"
- schema-utils "^3.1.2"
+ schema-utils "^3.2.0"
tapable "^2.1.1"
- terser-webpack-plugin "^5.3.7"
- watchpack "^2.4.0"
+ terser-webpack-plugin "^5.3.10"
+ watchpack "^2.4.1"
webpack-sources "^3.2.3"
+websocket-driver@>=0.5.1, websocket-driver@^0.7.4:
+ version "0.7.4"
+ resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760"
+ integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==
+ dependencies:
+ http-parser-js ">=0.5.1"
+ safe-buffer ">=5.1.0"
+ websocket-extensions ">=0.1.1"
+
+websocket-extensions@>=0.1.1:
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
+ integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
+
whatwg-url@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
@@ -2437,7 +3523,7 @@ workerpool@6.2.1:
resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343"
integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw==
-wrap-ansi@^7.0.0:
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -2446,6 +3532,15 @@ wrap-ansi@^7.0.0:
string-width "^4.1.0"
strip-ansi "^6.0.0"
+wrap-ansi@^8.1.0:
+ version "8.1.0"
+ resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
+ integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
+ dependencies:
+ ansi-styles "^6.1.0"
+ string-width "^5.0.1"
+ strip-ansi "^7.0.1"
+
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
@@ -2461,6 +3556,11 @@ ws@8.5.0:
resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f"
integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==
+ws@^8.16.0:
+ version "8.18.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.0.tgz#0d7505a6eafe2b0e712d232b42279f53bc289bbc"
+ integrity sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==
+
ws@~8.11.0:
version "8.11.0"
resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143"
From b2fbd81d94441b7e0e719c53e3b7933d45b598ce Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Tue, 6 Aug 2024 15:52:40 +0200
Subject: [PATCH 06/17] Update docs for K2 (#153)
---
docs/pages/kotlinx-rpc/topics/plugins.topic | 26 +++++++++++----------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/docs/pages/kotlinx-rpc/topics/plugins.topic b/docs/pages/kotlinx-rpc/topics/plugins.topic
index b9ccb15d..02651e32 100644
--- a/docs/pages/kotlinx-rpc/topics/plugins.topic
+++ b/docs/pages/kotlinx-rpc/topics/plugins.topic
@@ -81,24 +81,26 @@
where you define your RPC services in one set of subprojects and use in the
other. In such a setup, you can add the plugin only to modules with service definitions
to save time on building your project.
-
- For kotlinx.rpc library to work correctly with user-defined services,
- two additional configurations are required: the Kotlin compiler plugin and the
- KSP plugin.
- By adding the kotlinx.rpc and KSP Gradle plugins, all necessary configurations will be automatically set up:
plugins {
kotlin("jvm") version "%kotlin-version%"
- id("com.google.devtools.ksp") version "%ksp-version%"
id("org.jetbrains.kotlinx.rpc.plugin") version "%kotlinx-rpc-version%"
}
-
- dependencies {
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-client")
- implementation("org.jetbrains.kotlinx:kotlinx-rpc-krpc-server")
- }
+
+
+
+ If you are using a version of Kotlin prior to 2.0,
+ you must also add the KSP (Kotlin Symbol Processing) Gradle plugin:
+
+
+ plugins {
+ kotlin("jvm") version "1.9.24"
+ id("org.jetbrains.kotlinx.rpc.plugin") version "%kotlinx-rpc-version%"
+ id("com.google.devtools.ksp") version "1.9.24-1.0.20"
+ }
+
+
\ No newline at end of file
From 877e029284a81a2d8ff69911ae531f1c5dc3b5f6 Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Tue, 6 Aug 2024 15:55:32 +0200
Subject: [PATCH 07/17] Restructure compiler-plugin module into: backend, k2,
common and cli (#149)
---
compiler-plugin/build.gradle.kts | 14 +-------
.../compiler-plugin-backend/build.gradle.kts | 19 ++++++++++
.../core/kotlinx/rpc/codegen/RPCIrPlugin.kt} | 2 +-
.../kotlinx/rpc/codegen/VersionSpecificApi.kt | 0
.../kotlinx/rpc/codegen/extension/IrUtils.kt | 0
.../extension/RPCDeclarationScanner.kt | 0
.../rpc/codegen/extension/RPCIrContext.kt | 0
.../rpc/codegen/extension/RPCIrExtension.kt | 0
.../extension/RPCIrServiceProcessor.kt | 0
.../rpc/codegen/extension/RPCStubGenerator.kt | 0
.../codegen/extension/ServiceDeclaration.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
.../rpc/codegen/VersionSpecificApiImpl.kt | 0
.../compiler-plugin-cli/build.gradle.kts | 21 +++++++++++
.../compiler-plugin-cli/src/main/core/Stub.kt | 7 ++++
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 6 ++--
...otlin.compiler.plugin.CommandLineProcessor | 0
...in.compiler.plugin.CompilerPluginRegistrar | 0
...otlin.compiler.plugin.CommandLineProcessor | 0
....kotlin.compiler.plugin.ComponentRegistrar | 0
...otlin.compiler.plugin.CommandLineProcessor | 0
....kotlin.compiler.plugin.ComponentRegistrar | 0
...otlin.compiler.plugin.CommandLineProcessor | 0
...in.compiler.plugin.CompilerPluginRegistrar | 0
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 6 ++--
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 4 +--
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 6 ++--
compiler-plugin/settings.gradle.kts | 2 ++
.../kotlinx/rpc/codegen/RPCCompilerPlugin.kt | 36 -------------------
.../conventions-utils/build.gradle.kts | 8 +++++
.../main/kotlin/conventions-utils.gradle.kts | 5 +++
.../kotlin/kotlinx/rpc/RPCGradlePlugin.kt | 3 +-
.../kotlin/kotlinx/rpc/compilerPlugins.kt | 10 ++++--
gradle/libs.versions.toml | 1 +
37 files changed, 86 insertions(+), 64 deletions(-)
create mode 100644 compiler-plugin/compiler-plugin-backend/build.gradle.kts
rename compiler-plugin/{src/main/core/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt => compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/RPCIrPlugin.kt} (96%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/core/kotlinx/rpc/codegen/extension/IrUtils.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/core/kotlinx/rpc/codegen/extension/RPCIrExtension.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
rename compiler-plugin/{ => compiler-plugin-backend}/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt (100%)
create mode 100644 compiler-plugin/compiler-plugin-cli/build.gradle.kts
create mode 100644 compiler-plugin/compiler-plugin-cli/src/main/core/Stub.kt
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt (86%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar (100%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar (100%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar (100%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar (100%)
rename compiler-plugin/{src/main/v_1_8 => compiler-plugin-cli/src/main/v_1}/kotlinx/rpc/codegen/RPCCompilerPlugin.kt (85%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt (86%)
rename compiler-plugin/{ => compiler-plugin-cli}/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt (83%)
delete mode 100644 compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
create mode 100644 gradle-conventions/conventions-utils/src/main/kotlin/conventions-utils.gradle.kts
diff --git a/compiler-plugin/build.gradle.kts b/compiler-plugin/build.gradle.kts
index f64434c4..b5d9f2e8 100644
--- a/compiler-plugin/build.gradle.kts
+++ b/compiler-plugin/build.gradle.kts
@@ -2,12 +2,10 @@
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
-import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
import util.configureMetaTasks
plugins {
- alias(libs.plugins.conventions.jvm)
- alias(libs.plugins.compiler.specific.module)
+ alias(libs.plugins.conventions.utils)
}
val kotlinVersion: String by extra
@@ -18,15 +16,5 @@ allprojects {
version = "$kotlinVersion-$rpcVersion"
}
-kotlin {
- explicitApi = ExplicitApiMode.Disabled
-}
-
-dependencies {
- compileOnly(libs.kotlin.compiler.embeddable)
- implementation(projects.compilerPluginK2)
- implementation(projects.compilerPluginCommon)
-}
-
configureMetaTasks("cleanTest", "test")
configureMetaTasks(tasks.matching { it.name.startsWith("publish") }.map { it.name })
diff --git a/compiler-plugin/compiler-plugin-backend/build.gradle.kts b/compiler-plugin/compiler-plugin-backend/build.gradle.kts
new file mode 100644
index 00000000..c687e1a1
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-backend/build.gradle.kts
@@ -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.
+ */
+
+import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
+
+plugins {
+ alias(libs.plugins.conventions.jvm)
+ alias(libs.plugins.compiler.specific.module)
+}
+
+kotlin {
+ explicitApi = ExplicitApiMode.Disabled
+}
+
+dependencies {
+ compileOnly(libs.kotlin.compiler.embeddable)
+ implementation(projects.compilerPluginCommon)
+}
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/RPCIrPlugin.kt
similarity index 96%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/RPCIrPlugin.kt
index 32066972..3ad1c0d8 100644
--- a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/RPCCompilerPluginCore.kt
+++ b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/RPCIrPlugin.kt
@@ -10,7 +10,7 @@ import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
import org.jetbrains.kotlin.config.CompilerConfiguration
-object RPCCompilerPluginCore {
+object RPCIrPlugin {
fun provideExtension(configuration: CompilerConfiguration): IrGenerationExtension {
val logger = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, MessageCollector.NONE)
val versionSpecificApi = VersionSpecificApi.INSTANCE
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt
similarity index 100%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/VersionSpecificApi.kt
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/IrUtils.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/IrUtils.kt
similarity index 100%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/IrUtils.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/IrUtils.kt
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
similarity index 100%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCDeclarationScanner.kt
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
similarity index 100%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrContext.kt
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrExtension.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
similarity index 100%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrExtension.kt
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
similarity index 100%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCIrServiceProcessor.kt
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
similarity index 100%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/RPCStubGenerator.kt
diff --git a/compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt b/compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
similarity index 100%
rename from compiler-plugin/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/core/kotlinx/rpc/codegen/extension/ServiceDeclaration.kt
diff --git a/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-backend/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/latest/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-backend/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/v_1_7/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-backend/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/v_1_7_2/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-backend/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/v_1_8/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt b/compiler-plugin/compiler-plugin-backend/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
similarity index 100%
rename from compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
rename to compiler-plugin/compiler-plugin-backend/src/main/v_1_9/kotlinx/rpc/codegen/VersionSpecificApiImpl.kt
diff --git a/compiler-plugin/compiler-plugin-cli/build.gradle.kts b/compiler-plugin/compiler-plugin-cli/build.gradle.kts
new file mode 100644
index 00000000..7daebade
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-cli/build.gradle.kts
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode
+
+plugins {
+ alias(libs.plugins.conventions.jvm)
+ alias(libs.plugins.compiler.specific.module)
+}
+
+kotlin {
+ explicitApi = ExplicitApiMode.Disabled
+}
+
+dependencies {
+ compileOnly(libs.kotlin.compiler.embeddable)
+ implementation(projects.compilerPluginK2)
+ implementation(projects.compilerPluginCommon)
+ implementation(projects.compilerPluginBackend)
+}
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/core/Stub.kt b/compiler-plugin/compiler-plugin-cli/src/main/core/Stub.kt
new file mode 100644
index 00000000..8d2d7bef
--- /dev/null
+++ b/compiler-plugin/compiler-plugin-cli/src/main/core/Stub.kt
@@ -0,0 +1,7 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+@file:Suppress("detekt.MissingPackageDeclaration")
+
+// do not delete
diff --git a/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-cli/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 86%
rename from compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
rename to compiler-plugin/compiler-plugin-cli/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index e7c1d9a7..63ac652b 100644
--- a/compiler-plugin/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
+++ b/compiler-plugin/compiler-plugin-cli/src/main/latest/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter
@OptIn(ExperimentalCompilerApi::class)
class RPCCommandLineProcessor : CommandLineProcessor {
- override val pluginId = "kotlinx.rpc.codegen"
+ override val pluginId = "kotlinx.rpc.compiler-plugin"
override val pluginOptions = emptyList()
}
@@ -28,9 +28,9 @@ class RPCCompilerPlugin : CompilerPluginRegistrar() {
override val supportsK2: Boolean = true
override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
- val extension = RPCCompilerPluginCore.provideExtension(configuration)
+ val irExtension = RPCIrPlugin.provideExtension(configuration)
- IrGenerationExtension.registerExtension(extension)
+ IrGenerationExtension.registerExtension(irExtension)
FirExtensionRegistrarAdapter.registerExtension(FirRPCExtensionRegistrar(configuration))
}
}
diff --git a/compiler-plugin/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/compiler-plugin-cli/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/compiler-plugin-cli/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar b/compiler-plugin/compiler-plugin-cli/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
similarity index 100%
rename from compiler-plugin/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
rename to compiler-plugin/compiler-plugin-cli/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
diff --git a/compiler-plugin/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
similarity index 100%
rename from compiler-plugin/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
rename to compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
diff --git a/compiler-plugin/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
similarity index 100%
rename from compiler-plugin/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
rename to compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
diff --git a/compiler-plugin/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
similarity index 100%
rename from compiler-plugin/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
rename to compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
diff --git a/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-cli/src/main/v_1/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 85%
rename from compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
rename to compiler-plugin/compiler-plugin-cli/src/main/v_1/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index 5910422c..9fc69ae1 100644
--- a/compiler-plugin/src/main/v_1_8/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
+++ b/compiler-plugin/compiler-plugin-cli/src/main/v_1/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -24,11 +24,11 @@ class RPCCompilerPlugin : CompilerPluginRegistrar() {
VersionSpecificApi.INSTANCE = VersionSpecificApiImpl
}
- override val supportsK2: Boolean = true
+ override val supportsK2: Boolean = false
override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
- val extension = RPCCompilerPluginCore.provideExtension(configuration)
+ val irExtension = RPCIrPlugin.provideExtension(configuration)
- IrGenerationExtension.registerExtension(extension)
+ IrGenerationExtension.registerExtension(irExtension)
}
}
\ No newline at end of file
diff --git a/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-cli/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 86%
rename from compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
rename to compiler-plugin/compiler-plugin-cli/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index dc953930..82519345 100644
--- a/compiler-plugin/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
+++ b/compiler-plugin/compiler-plugin-cli/src/main/v_1_7/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -23,8 +23,8 @@ class RPCCompilerPlugin : ComponentRegistrar {
}
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
- val extension = RPCCompilerPluginCore.provideExtension(configuration)
+ val irExtension = RPCIrPlugin.provideExtension(configuration)
- IrGenerationExtension.registerExtension(project, extension)
+ IrGenerationExtension.registerExtension(project, irExtension)
}
}
diff --git a/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/compiler-plugin-cli/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
similarity index 83%
rename from compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
rename to compiler-plugin/compiler-plugin-cli/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
index 55e1830b..4a941f97 100644
--- a/compiler-plugin/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
+++ b/compiler-plugin/compiler-plugin-cli/src/main/v_1_7_2/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
@@ -22,11 +22,11 @@ class RPCCompilerPlugin : ComponentRegistrar {
VersionSpecificApi.INSTANCE = VersionSpecificApiImpl
}
- override val supportsK2: Boolean = true
+ override val supportsK2: Boolean = false
override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
- val extension = RPCCompilerPluginCore.provideExtension(configuration)
+ val irExtension = RPCIrPlugin.provideExtension(configuration)
- IrGenerationExtension.registerExtension(project, extension)
+ IrGenerationExtension.registerExtension(project, irExtension)
}
}
diff --git a/compiler-plugin/settings.gradle.kts b/compiler-plugin/settings.gradle.kts
index 2d2a6ddb..e349830d 100644
--- a/compiler-plugin/settings.gradle.kts
+++ b/compiler-plugin/settings.gradle.kts
@@ -19,3 +19,5 @@ includeRootAsPublic()
includePublic(":compiler-plugin-k2")
includePublic(":compiler-plugin-common")
+includePublic(":compiler-plugin-backend")
+includePublic(":compiler-plugin-cli")
diff --git a/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/RPCCompilerPlugin.kt b/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
deleted file mode 100644
index e7c1d9a7..00000000
--- a/compiler-plugin/src/main/v_1_9/kotlinx/rpc/codegen/RPCCompilerPlugin.kt
+++ /dev/null
@@ -1,36 +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.codegen
-
-import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
-import org.jetbrains.kotlin.compiler.plugin.CliOption
-import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
-import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
-import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi
-import org.jetbrains.kotlin.config.CompilerConfiguration
-import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrarAdapter
-
-@OptIn(ExperimentalCompilerApi::class)
-class RPCCommandLineProcessor : CommandLineProcessor {
- override val pluginId = "kotlinx.rpc.codegen"
-
- override val pluginOptions = emptyList()
-}
-
-@OptIn(ExperimentalCompilerApi::class)
-class RPCCompilerPlugin : CompilerPluginRegistrar() {
- init {
- VersionSpecificApi.INSTANCE = VersionSpecificApiImpl
- }
-
- override val supportsK2: Boolean = true
-
- override fun ExtensionStorage.registerExtensions(configuration: CompilerConfiguration) {
- val extension = RPCCompilerPluginCore.provideExtension(configuration)
-
- IrGenerationExtension.registerExtension(extension)
- FirExtensionRegistrarAdapter.registerExtension(FirRPCExtensionRegistrar(configuration))
- }
-}
diff --git a/gradle-conventions/conventions-utils/build.gradle.kts b/gradle-conventions/conventions-utils/build.gradle.kts
index 189cd242..8ff36d0f 100644
--- a/gradle-conventions/conventions-utils/build.gradle.kts
+++ b/gradle-conventions/conventions-utils/build.gradle.kts
@@ -28,3 +28,11 @@ dependencies {
// https://stackoverflow.com/questions/76713758/use-version-catalog-inside-precompiled-gradle-plugin
api(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
}
+
+gradlePlugin {
+ plugins {
+ named("conventions-utils") {
+ version = libs.versions.kotlinx.rpc.get()
+ }
+ }
+}
diff --git a/gradle-conventions/conventions-utils/src/main/kotlin/conventions-utils.gradle.kts b/gradle-conventions/conventions-utils/src/main/kotlin/conventions-utils.gradle.kts
new file mode 100644
index 00000000..b648ed7e
--- /dev/null
+++ b/gradle-conventions/conventions-utils/src/main/kotlin/conventions-utils.gradle.kts
@@ -0,0 +1,5 @@
+/*
+ * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
+ */
+
+// do not delete. This plugin includes util functions in the buildscript classpath
diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
index 10724177..27a3dc07 100644
--- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
+++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/RPCGradlePlugin.kt
@@ -36,9 +36,10 @@ class RPCGradlePlugin : Plugin {
}
private fun applyCompilerPlugin(target: Project) {
- target.plugins.apply(CompilerPlugin::class.java)
target.plugins.apply(CompilerPluginK2::class.java)
target.plugins.apply(CompilerPluginCommon::class.java)
+ target.plugins.apply(CompilerPluginBackend::class.java)
+ target.plugins.apply(CompilerPluginCli::class.java)
}
private fun applyKspPlugin(target: Project, config: RPCConfig) {
diff --git a/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt b/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
index b19ad08e..17c88d66 100644
--- a/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
+++ b/gradle-plugin/src/main/kotlin/kotlinx/rpc/compilerPlugins.kt
@@ -8,8 +8,6 @@ package kotlinx.rpc
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin
-class CompilerPlugin : KotlinCompilerPluginSupportPlugin by compilerPlugin()
-
class CompilerPluginK2 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
pluginSuffix = "-k2"
})
@@ -17,3 +15,11 @@ class CompilerPluginK2 : KotlinCompilerPluginSupportPlugin by compilerPlugin({
class CompilerPluginCommon : KotlinCompilerPluginSupportPlugin by compilerPlugin({
pluginSuffix = "-common"
})
+
+class CompilerPluginBackend : KotlinCompilerPluginSupportPlugin by compilerPlugin({
+ pluginSuffix = "-backend"
+})
+
+class CompilerPluginCli : KotlinCompilerPluginSupportPlugin by compilerPlugin({
+ pluginSuffix = "-cli"
+})
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 4617b5ec..9ef84ab4 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -86,6 +86,7 @@ kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
gradle-plugin-publish = { id = "com.gradle.plugin-publish", version.ref = "gradle-plugin-publish" }
# gradle-conventions project
+conventions-utils = { id = "conventions-utils", version.ref = "kotlinx-rpc" }
conventions-common = { id = "conventions-common", version.ref = "kotlinx-rpc" }
conventions-jvm = { id = "conventions-jvm", version.ref = "kotlinx-rpc" }
conventions-kmp = { id = "conventions-kmp", version.ref = "kotlinx-rpc" }
From 10faf14538baaf48199ba6e655849fa248d28d71 Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Tue, 6 Aug 2024 15:56:36 +0200
Subject: [PATCH 08/17] Fix CSM resources load for all Kotlin versions (#152)
---
build.gradle.kts | 7 ++
.../extension/RPCDeclarationScanner.kt | 3 +
...otlin.compiler.plugin.CommandLineProcessor | 0
...in.compiler.plugin.CompilerPluginRegistrar | 0
...otlin.compiler.plugin.CommandLineProcessor | 0
....kotlin.compiler.plugin.ComponentRegistrar | 0
...otlin.compiler.plugin.CommandLineProcessor | 5 --
....kotlin.compiler.plugin.ComponentRegistrar | 5 --
...otlin.compiler.plugin.CommandLineProcessor | 5 --
...in.compiler.plugin.CompilerPluginRegistrar | 5 --
.../compiler-specific-module.gradle.kts | 83 +++++++++----------
.../src/main/kotlin/dependency.kt | 18 ----
.../src/main/kotlin/util.kt | 21 +++--
.../src/main/kotlin/version.kt | 15 +++-
14 files changed, 79 insertions(+), 88 deletions(-)
rename compiler-plugin/compiler-plugin-cli/src/{main/resources => main-resources}/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/compiler-plugin-cli/src/{main/resources => main-resources}/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar (100%)
rename compiler-plugin/compiler-plugin-cli/src/{main/resources => main-resources}/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor (100%)
rename compiler-plugin/compiler-plugin-cli/src/{main/resources => main-resources}/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar (100%)
delete mode 100644 compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
delete mode 100644 compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
delete mode 100644 compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
delete mode 100644 compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
delete mode 100644 gradle-conventions/compiler-specific-module/src/main/kotlin/dependency.kt
diff --git a/build.gradle.kts b/build.gradle.kts
index e55a5700..ac0b17c1 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -15,6 +15,13 @@ plugins {
alias(libs.plugins.binary.compatibility.validator)
}
+// useful for dependencies introspection
+// run ./gradlew htmlDependencyReport
+// Report can normally be found in build/reports/project/dependencies/index.html
+allprojects {
+ plugins.apply("project-report")
+}
+
object Const {
const val INTERNAL_RPC_API_ANNOTATION = "kotlinx.rpc.internal.InternalRPCApi"
}
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 e790bc3b..693262fa 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
@@ -2,6 +2,8 @@
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
+@file:OptIn(UnsafeDuringIrConstructionAPI::class)
+
package kotlinx.rpc.codegen.extension
import kotlinx.rpc.codegen.common.RpcNames
@@ -9,6 +11,7 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
+import org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.util.dumpKotlinLike
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/compiler-plugin-cli/src/main-resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/compiler-plugin-cli/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/compiler-plugin-cli/src/main-resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar b/compiler-plugin/compiler-plugin-cli/src/main-resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
similarity index 100%
rename from compiler-plugin/compiler-plugin-cli/src/main/resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
rename to compiler-plugin/compiler-plugin-cli/src/main-resources/latest/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/compiler-plugin-cli/src/main-resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
similarity index 100%
rename from compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
rename to compiler-plugin/compiler-plugin-cli/src/main-resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/compiler-plugin/compiler-plugin-cli/src/main-resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
similarity index 100%
rename from compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
rename to compiler-plugin/compiler-plugin-cli/src/main-resources/v_1_7/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
deleted file mode 100644
index 61cf7463..00000000
--- a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# 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
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
deleted file mode 100644
index 04b0b782..00000000
--- a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_7_2/META-INF/services/org.jetbrains.kotlin.compiler.plugin.ComponentRegistrar
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# 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
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
deleted file mode 100644
index 61cf7463..00000000
--- a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# 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
diff --git a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar b/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
deleted file mode 100644
index 04b0b782..00000000
--- a/compiler-plugin/compiler-plugin-cli/src/main/resources/v_1_8/META-INF/services/org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# 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
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts b/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
index d03b310d..905088d3 100644
--- a/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
+++ b/gradle-conventions/compiler-specific-module/src/main/kotlin/compiler-specific-module.gradle.kts
@@ -24,20 +24,17 @@ fun NamedDomainObjectContainer.applyCompilerSpecificSourceSets(
return@forEach
}
- val core = sourceSetPath.resolve(Const.CORE_SOURCE_SET).toFile()
+ val core = sourceSetPath.resolve(CORE_SOURCE_DIR).toFile()
// version-specific source sets
- val vsSets = Files.newDirectoryStream(sourceSetPath).use { it.toList() }.filter {
- Files.isDirectory(it) && it.name().matches(directoryNameRegex)
- }.map { it.toFile() }
+ val vsSets = filterSourceDirs(sourceSetPath)
// choose 'latest' if there are no more specific ones
- val mostSpecificApplicable = vsSets.mostSpecificByVersionOrNull(kotlinVersion)
- ?: vsSets.singleOrNull { it.name == Const.LATEST_SOURCE_SET }
+ val mostSpecificApplicable = vsSets.mostSpecificVersionOrLatest(kotlinVersion)
?: run {
logger.info("No version specific sources sets, but '${core.name}'")
set.kotlin.setSrcDirs(listOf(core)) // 'core' source set instead of 'kotlin'
- set.configureResources(sourceSetPath, core.name)
+ set.configureResources(sourceSetPath)
return@forEach
}
@@ -47,57 +44,59 @@ fun NamedDomainObjectContainer.applyCompilerSpecificSourceSets(
)
set.kotlin.setSrcDirs(listOf(core, mostSpecificApplicable)) // 'core' source set instead of 'kotlin'
- set.configureResources(sourceSetPath, core.name, mostSpecificApplicable.name)
+ set.configureResources(sourceSetPath)
val excluded = vsSets.filter { it != mostSpecificApplicable }
logger.info("${project.name}: excluded version specific source sets: [${excluded.joinToString { it.name }}]")
}
}
-fun KotlinSourceSet.configureResources(sourceSetPath: Path, vararg versionNames: String) {
- val vsResources = sourceSetPath.resolve(Const.RESOURCES).toFile()
- resources.setSrcDirs(
- versionNames.map { vsResources.resolve(it) }
- )
+fun KotlinSourceSet.configureResources(sourceSetPath: Path) {
+ val parent = sourceSetPath.parent.toAbsolutePath()
+ if (!Files.exists(parent)) {
+ error("Expected parent dir for ${sourceSetPath.toAbsolutePath()}")
+ }
- // 'resources' property does not work alone in gradle 7.5.1 with kotlin 1.7.0 (no idea why),
- // so we adjust task contents as well
- // todo duplicate (or to many resources are copied, should update the algo)
-// tasks.withType().configureEach {
-// duplicatesStrategy = DuplicatesStrategy.EXCLUDE
-//
-// from(versionNames.map { vsResources.resolve(it) })
-// include { it.file.parentInAllowList(versionNames) }
-// }
-}
+ // only works for jvm projects
+ val resourcesName = if (name.lowercase().contains(MAIN_SOURCE_SET)) MAIN_RESOURCES else TEST_RESOURCES
+ val resourcesDir = parent.resolve(resourcesName)
-fun File.parentInAllowList(allowList: Array): Boolean {
-// println("decide: $absolutePath")
- val parent = toPath().parent?.toFile()
- // will skip v_1_7 for 1.7.0, as it's parent is resources
- // but will allow META-INF, as it's parent is v_1_7
- if (parent?.name in allowList) {
- return true
+ if (!Files.exists(resourcesDir)) {
+ return
}
- // allow META-INF contents
- return untilAllowedParentOrNull(allowList) != null
-}
+ val mostSpecificApplicable = filterSourceDirs(resourcesDir)
+ .mostSpecificVersionOrLatest(kotlinVersion)
-tailrec fun File.untilAllowedParentOrNull(allowList: Array): File? {
- if (name in allowList) {
- return null
- }
+ val versionNames = listOfNotNull(CORE_SOURCE_DIR, mostSpecificApplicable?.name)
+
+ resources.srcDirs(versionNames.map { resourcesDir.resolve(it).toFile() })
+
+ // 'resources' property does not work alone in gradle 7.5.1 with kotlin 1.7.* and 1.8.* (no idea why),
+ // so we adjust task contents as well
+ if (kotlinVersion.startsWith("1.8") || kotlinVersion.startsWith("1.7")) {
+ // only works for jvm projects
+ val resourcesTaskName = if (name == MAIN_SOURCE_SET) PROCESS_RESOURCES else PROCESS_TEST_RESOURCES
+ tasks.withType().configureEach {
+ if (name != resourcesTaskName) {
+ return@configureEach
+ }
- val parent = toPath().parent?.toFile()
- return if (parent?.name in allowList) this else parent?.untilAllowedParentOrNull(allowList)
+ duplicatesStrategy = DuplicatesStrategy.EXCLUDE
+
+ from(versionNames.map { resourcesDir.resolve(it) })
+ include {
+ // double check if the files are the right ones
+ it.file.toPath().toAbsolutePath().startsWith(parent)
+ }
+ }
+ }
}
-plugins.withId(Const.KOTLIN_JVM_PLUGIN_ID) {
+plugins.withId(KOTLIN_JVM_PLUGIN_ID) {
the().sourceSets.applyCompilerSpecificSourceSets()
}
-plugins.withId(Const.KOTLIN_MULTIPLATFORM_PLUGIN_ID) {
+plugins.withId(KOTLIN_MULTIPLATFORM_PLUGIN_ID) {
the().sourceSets.applyCompilerSpecificSourceSets()
}
-
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/dependency.kt b/gradle-conventions/compiler-specific-module/src/main/kotlin/dependency.kt
deleted file mode 100644
index 3e5338ac..00000000
--- a/gradle-conventions/compiler-specific-module/src/main/kotlin/dependency.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
- */
-
-import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
-import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
-
-/**
- * Use this to add a specific dependency to a source set, depending on a Kotlin version
- */
-fun KotlinSourceSet.vsDependencies(
- vsSourceSetDir: String,
- configure: KotlinDependencyHandler.() -> Unit,
-) {
- kotlin.srcDirs.find { it.name == vsSourceSetDir }?.apply {
- dependencies(configure)
- }
-}
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/util.kt b/gradle-conventions/compiler-specific-module/src/main/kotlin/util.kt
index cda3e63f..bec27f62 100644
--- a/gradle-conventions/compiler-specific-module/src/main/kotlin/util.kt
+++ b/gradle-conventions/compiler-specific-module/src/main/kotlin/util.kt
@@ -3,16 +3,20 @@
*/
import java.nio.file.Path
+import java.util.*
-object Const {
- const val KOTLIN_MULTIPLATFORM_PLUGIN_ID = "org.jetbrains.kotlin.multiplatform"
- const val KOTLIN_JVM_PLUGIN_ID = "org.jetbrains.kotlin.jvm"
+const val KOTLIN_MULTIPLATFORM_PLUGIN_ID = "org.jetbrains.kotlin.multiplatform"
+const val KOTLIN_JVM_PLUGIN_ID = "org.jetbrains.kotlin.jvm"
- const val CORE_SOURCE_SET = "core"
- const val LATEST_SOURCE_SET = "latest"
+const val MAIN_SOURCE_SET = "main"
- const val RESOURCES = "resources"
-}
+const val CORE_SOURCE_DIR = "core"
+const val LATEST_SOURCE_DIR = "latest"
+
+const val MAIN_RESOURCES = "main-resources"
+const val TEST_RESOURCES = "test-resources"
+const val PROCESS_RESOURCES = "processResources"
+const val PROCESS_TEST_RESOURCES = "processTestResources"
fun capitalize(string: String): String {
if (string.isEmpty()) {
@@ -22,4 +26,7 @@ fun capitalize(string: String): String {
return string.replaceFirst(firstChar, Character.toTitleCase(firstChar))
}
+@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN", "NOTHING_TO_INLINE")
+inline fun String.lowercase(): String = (this as java.lang.String).toLowerCase(Locale.ROOT)
+
fun Path.name() = fileName?.toString().orEmpty()
diff --git a/gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt b/gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt
index c1d2d3fc..ffc0e56c 100644
--- a/gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt
+++ b/gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt
@@ -3,6 +3,14 @@
*/
import java.io.File
+import java.nio.file.Files
+import java.nio.file.Path
+
+fun filterSourceDirs(sourceSetPath: Path): List {
+ return Files.newDirectoryStream(sourceSetPath).use { it.toList() }.filter {
+ Files.isDirectory(it) && it.name().matches(directoryNameRegex)
+ }.map { it.toFile() }
+}
// Versioning is used to sort version-specific source sets in the 'first comes more specific' order
// By 'more specific' we mean that '1.7.10' is more specific than '1.7'.
@@ -27,7 +35,12 @@ class CompilerModuleVersion(fullName: String, prefix: String) : Comparable.mostSpecificByVersionOrNull(kotlinVersion: String): File? {
+fun Collection.mostSpecificVersionOrLatest(kotlinVersion: String): File? {
+ return mostSpecificByVersionOrNull(kotlinVersion)
+ ?: singleOrNull { it.name == LATEST_SOURCE_DIR }
+}
+
+private fun Collection.mostSpecificByVersionOrNull(kotlinVersion: String): File? {
return map { it to CompilerModuleVersion(it.name, "v_") }
.sortedBy { (_, semVer) -> semVer }
.firstOrNull { (_, semVer) ->
From b7762c0135a1d7ea4c606a6cd20d25e987bfa0de Mon Sep 17 00:00:00 2001
From: Alexander Sysoev
Date: Thu, 8 Aug 2024 13:39:17 +0200
Subject: [PATCH 09/17] Simplified gradle configurations (#154)
---
build.gradle.kts | 15 ++----
compiler-plugin/build.gradle.kts | 6 +--
compiler-plugin/settings.gradle.kts | 2 +-
.../rpc/internal/transport/RPCPluginKey.kt | 1 -
.../rpc/internal/WithRPCStubObject.js.kt | 1 -
detekt/baseline.xml | 1 -
detekt/config.yaml | 6 +--
.../build.gradle.kts | 13 ++----
.../settings.gradle.kts | 4 +-
.../src/main/kotlin/includePublic.kt | 0
.../settings-conventions.settings.gradle.kts | 37 ++++++++-------
.../src/main/kotlin/util/Dir.kt | 17 +++++++
.../src/main/kotlin/util/JsTarget.kt | 0
.../src/main/kotlin/util/KotlinExtension.kt | 31 +++++++++++++
.../src/main/kotlin/util/KotlinVersion.kt | 44 ++++++++++++++----
.../main/kotlin/util/OptInForInternalApi.kt | 0
.../src/main/kotlin/util/OptionalProperty.kt | 0
.../src/main/kotlin/util/Path.kt | 15 ++++++
.../src/main/kotlin/util/PublicModule.kt | 2 +-
.../src/main/kotlin/util/PublicationUtils.kt | 0
.../src/main/kotlin/util/StringCase.kt | 18 ++++++++
.../src/main/kotlin/util/TargetUtils.kt | 17 ++++---
.../kotlin/util/VersionCatalogForPlugins.kt | 0
.../main/kotlin/util/conventionsDefaults.kt | 18 ++++++++
.../src/main/kotlin/util/metaTask.kt | 0
gradle-conventions/build.gradle.kts | 46 ++++---------------
.../compiler-specific-module/build.gradle.kts | 28 -----------
.../src/main/kotlin/util.kt | 32 -------------
.../main/kotlin/conventions-utils.gradle.kts | 5 --
.../src/main/kotlin/util/KotlinExtension.kt | 13 ------
gradle-conventions/empty/build.gradle.kts | 31 +++++++++++++
.../src/main/kotlin/empty.gradle.kts} | 2 +-
.../gradle-publish-stub/build.gradle.kts | 29 ------------
.../conventions-gradle-publish.gradle.kts | 3 --
.../gradle-publish/build.gradle.kts | 29 ------------
.../kotlin-version-new/build.gradle.kts | 36 ---------------
.../kotlin-version-old/build.gradle.kts | 36 ---------------
.../conventions-kotlin-version-jvm.gradle.kts | 10 ----
.../conventions-kotlin-version-kmp.gradle.kts | 10 ----
.../src/main/kotlin/util/CompilerOptions.kt | 23 ----------
.../kover-stub/build.gradle.kts | 29 ------------
gradle-conventions/kover/build.gradle.kts | 30 ------------
.../latest-only/build.gradle.kts | 17 +++++++
.../conventions-gradle-publish.gradle.kts | 0
.../conventions-kotlin-version-jvm.gradle.kts | 0
.../conventions-kotlin-version-kmp.gradle.kts | 0
.../main/kotlin/conventions-kover.gradle.kts} | 0
.../src/main/kotlin/util/CompilerOptions.kt | 0
gradle-conventions/settings.gradle.kts | 39 +++++++---------
.../compiler-specific-module.gradle.kts | 28 +++++------
.../main/kotlin/conventions-common.gradle.kts | 4 +-
.../main/kotlin/conventions-kmp.gradle.kts | 3 ++
.../kotlin/conventions-publishing.gradle.kts | 4 +-
gradle-plugin/settings.gradle.kts | 2 +-
gradle-settings-conventions/build.gradle.kts | 24 ----------
ksp-plugin/build.gradle.kts | 2 +-
ksp-plugin/settings.gradle.kts | 2 +-
settings.gradle.kts | 2 +-
.../kotlinx/rpc/internal/hex/HexBytes.kt | 2 -
.../kotlin-versions-lookup.csv | 2 +-
{gradle => versions-root}/libs.versions.toml | 5 +-
.../targets-since-kotlin-lookup.json | 0
62 files changed, 282 insertions(+), 494 deletions(-)
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/build.gradle.kts (77%)
rename {gradle-settings-conventions => gradle-conventions-settings}/settings.gradle.kts (64%)
rename {gradle-settings-conventions => gradle-conventions-settings}/src/main/kotlin/includePublic.kt (100%)
rename {gradle-settings-conventions => gradle-conventions-settings}/src/main/kotlin/settings-conventions.settings.gradle.kts (86%)
create mode 100644 gradle-conventions-settings/src/main/kotlin/util/Dir.kt
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/src/main/kotlin/util/JsTarget.kt (100%)
create mode 100644 gradle-conventions-settings/src/main/kotlin/util/KotlinExtension.kt
rename gradle-conventions/compiler-specific-module/src/main/kotlin/version.kt => gradle-conventions-settings/src/main/kotlin/util/KotlinVersion.kt (61%)
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/src/main/kotlin/util/OptInForInternalApi.kt (100%)
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/src/main/kotlin/util/OptionalProperty.kt (100%)
create mode 100644 gradle-conventions-settings/src/main/kotlin/util/Path.kt
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/src/main/kotlin/util/PublicModule.kt (84%)
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/src/main/kotlin/util/PublicationUtils.kt (100%)
create mode 100644 gradle-conventions-settings/src/main/kotlin/util/StringCase.kt
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/src/main/kotlin/util/TargetUtils.kt (86%)
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/src/main/kotlin/util/VersionCatalogForPlugins.kt (100%)
create mode 100644 gradle-conventions-settings/src/main/kotlin/util/conventionsDefaults.kt
rename {gradle-conventions/conventions-utils => gradle-conventions-settings}/src/main/kotlin/util/metaTask.kt (100%)
delete mode 100644 gradle-conventions/compiler-specific-module/build.gradle.kts
delete mode 100644 gradle-conventions/compiler-specific-module/src/main/kotlin/util.kt
delete mode 100644 gradle-conventions/conventions-utils/src/main/kotlin/conventions-utils.gradle.kts
delete mode 100644 gradle-conventions/conventions-utils/src/main/kotlin/util/KotlinExtension.kt
create mode 100644 gradle-conventions/empty/build.gradle.kts
rename gradle-conventions/{kover-stub/src/main/kotlin/kover-root-project.gradle.kts => empty/src/main/kotlin/empty.gradle.kts} (63%)
delete mode 100644 gradle-conventions/gradle-publish-stub/build.gradle.kts
delete mode 100644 gradle-conventions/gradle-publish-stub/src/main/kotlin/conventions-gradle-publish.gradle.kts
delete mode 100644 gradle-conventions/gradle-publish/build.gradle.kts
delete mode 100644 gradle-conventions/kotlin-version-new/build.gradle.kts
delete mode 100644 gradle-conventions/kotlin-version-old/build.gradle.kts
delete mode 100644 gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts
delete mode 100644 gradle-conventions/kotlin-version-old/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts
delete mode 100644 gradle-conventions/kotlin-version-old/src/main/kotlin/util/CompilerOptions.kt
delete mode 100644 gradle-conventions/kover-stub/build.gradle.kts
delete mode 100644 gradle-conventions/kover/build.gradle.kts
create mode 100644 gradle-conventions/latest-only/build.gradle.kts
rename gradle-conventions/{gradle-publish => latest-only}/src/main/kotlin/conventions-gradle-publish.gradle.kts (100%)
rename gradle-conventions/{kotlin-version-new => latest-only}/src/main/kotlin/conventions-kotlin-version-jvm.gradle.kts (100%)
rename gradle-conventions/{kotlin-version-new => latest-only}/src/main/kotlin/conventions-kotlin-version-kmp.gradle.kts (100%)
rename gradle-conventions/{kover/src/main/kotlin/kover-root-project.gradle.kts => latest-only/src/main/kotlin/conventions-kover.gradle.kts} (100%)
rename gradle-conventions/{kotlin-version-new => latest-only}/src/main/kotlin/util/CompilerOptions.kt (100%)
rename gradle-conventions/{compiler-specific-module => }/src/main/kotlin/compiler-specific-module.gradle.kts (75%)
delete mode 100644 gradle-settings-conventions/build.gradle.kts
rename {gradle => versions-root}/kotlin-versions-lookup.csv (95%)
rename {gradle => versions-root}/libs.versions.toml (95%)
rename {gradle => versions-root}/targets-since-kotlin-lookup.json (100%)
diff --git a/build.gradle.kts b/build.gradle.kts
index ac0b17c1..c8873ab0 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -3,15 +3,14 @@
*/
import org.jetbrains.kotlin.gradle.plugin.getKotlinPluginVersion
+import util.kotlinVersionParsed
plugins {
- alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.serialization) apply false
alias(libs.plugins.ksp) apply false
alias(libs.plugins.kotlinx.rpc) apply false
alias(libs.plugins.atomicfu) apply false
- alias(libs.plugins.detekt) apply false
- alias(libs.plugins.kover.root.project) apply false
+ alias(libs.plugins.conventions.kover)
alias(libs.plugins.binary.compatibility.validator)
}
@@ -41,11 +40,7 @@ apiValidation {
nonPublicMarkers.add(Const.INTERNAL_RPC_API_ANNOTATION)
}
-val kotlinVersion: String by extra
-
-if (kotlinVersion >= "1.8.0") {
- apply(plugin = libs.plugins.kover.root.project.get().pluginId)
-}
+val kotlinVersion: KotlinVersion by extra
allprojects {
group = "org.jetbrains.kotlinx"
@@ -57,8 +52,8 @@ println("kotlinx.rpc project version: $version, Kotlin version: $kotlinVersion")
// If the prefix of the kPRC version is not Kotlin gradle plugin version - you have a problem :)
// Probably some dependency brings kotlin with higher version.
// To mitigate so, please refer to `gradle/kotlin-version-lookup.json`
-// and it's usage in `gradle-settings-conventions/src/main/kotlin/settings-conventions.settings.gradle.kts`
-val kotlinGPVersion = getKotlinPluginVersion()
+// and it's usage in `gradle-conventions-settings/src/main/kotlin/settings-conventions.settings.gradle.kts`
+val kotlinGPVersion = getKotlinPluginVersion().kotlinVersionParsed()
if (kotlinVersion != kotlinGPVersion) {
error("KGP version mismatch. Project version: $kotlinVersion, KGP version: $kotlinGPVersion")
}
diff --git a/compiler-plugin/build.gradle.kts b/compiler-plugin/build.gradle.kts
index b5d9f2e8..9b6f9307 100644
--- a/compiler-plugin/build.gradle.kts
+++ b/compiler-plugin/build.gradle.kts
@@ -4,11 +4,7 @@
import util.configureMetaTasks
-plugins {
- alias(libs.plugins.conventions.utils)
-}
-
-val kotlinVersion: String by extra
+val kotlinVersion: KotlinVersion by extra
val rpcVersion: String = libs.versions.kotlinx.rpc.get()
allprojects {
diff --git a/compiler-plugin/settings.gradle.kts b/compiler-plugin/settings.gradle.kts
index e349830d..e5c3851e 100644
--- a/compiler-plugin/settings.gradle.kts
+++ b/compiler-plugin/settings.gradle.kts
@@ -8,7 +8,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
pluginManagement {
includeBuild("../gradle-conventions")
- includeBuild("../gradle-settings-conventions")
+ includeBuild("../gradle-conventions-settings")
}
plugins {
diff --git a/core/src/commonMain/kotlin/kotlinx/rpc/internal/transport/RPCPluginKey.kt b/core/src/commonMain/kotlin/kotlinx/rpc/internal/transport/RPCPluginKey.kt
index 2eeb3562..1a38582f 100644
--- a/core/src/commonMain/kotlin/kotlinx/rpc/internal/transport/RPCPluginKey.kt
+++ b/core/src/commonMain/kotlin/kotlinx/rpc/internal/transport/RPCPluginKey.kt
@@ -21,7 +21,6 @@ import kotlinx.serialization.Serializable
*/
@InternalRPCApi
@Serializable(with = RPCPluginKeySerializer::class)
-@Suppress("detekt.MagicNumber")
public enum class RPCPluginKey(override val uniqueIndex: Int, private val associatedPlugin: RPCPlugin): IndexedEnum {
/**
* Failed to decode key, possible due to different endpoint versions.
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 2a6098e6..09fdd682 100644
--- a/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
+++ b/core/src/jsMain/kotlin/kotlinx/rpc/internal/WithRPCStubObject.js.kt
@@ -47,7 +47,6 @@ private val KClass<*>.jClass get(): JsClass<*> = asDynamic().jClass_1.unsafeCast
*
* This function uses std-lib's implementation and accounts for the bug in the compiler
*/
-@Suppress("detekt.ReturnCount")
internal fun KClass<*>.findAssociatedObjectImpl(
annotationClass: KClass,
resultKClass: KClass,
diff --git a/detekt/baseline.xml b/detekt/baseline.xml
index 452ca7ca..2c1473cc 100644
--- a/detekt/baseline.xml
+++ b/detekt/baseline.xml
@@ -5,7 +5,6 @@
- ReturnCount:ExceptionUtils.jvm.kt$@InternalRPCApi public actual fun SerializedException.deserialize(): ThrowableCyclomaticComplexMethod:RPCServerService.kt$RPCServerService$@Suppress("detekt.ThrowsCount", "detekt.LongMethod") private fun handleCall(callData: RPCCallMessage.CallData)LongMethod:RPCServerService.kt$RPCServerService$@OptIn(InternalCoroutinesApi::class) private fun handleCall(callData: RPCCallMessage.CallData)RethrowCaughtException:KRPCTransportTestBase.kt$KRPCTransportTestBase$throw e
diff --git a/detekt/config.yaml b/detekt/config.yaml
index 20f9aa61..2553f459 100644
--- a/detekt/config.yaml
+++ b/detekt/config.yaml
@@ -478,7 +478,7 @@ potential-bugs:
active: true
MissingPackageDeclaration:
active: true
- excludes: ['**/*.kts']
+ excludes: ['**/*.kts', '**/gradle-conventions-settings/**', '**/gradle-conventions/**']
NullCheckOnMutableProperty:
active: false
NullableToStringCall:
@@ -616,7 +616,7 @@ style:
active: true
maxJumpCount: 3
MagicNumber:
- active: true
+ active: false
excludes: ['**/*test*/**', '**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts']
ignoreNumbers:
- '-1'
@@ -683,7 +683,7 @@ style:
active: false
ReturnCount:
active: true
- max: 2
+ max: 6
excludedFunctions:
- 'equals'
excludeLabeled: false
diff --git a/gradle-conventions/conventions-utils/build.gradle.kts b/gradle-conventions-settings/build.gradle.kts
similarity index 77%
rename from gradle-conventions/conventions-utils/build.gradle.kts
rename to gradle-conventions-settings/build.gradle.kts
index 8ff36d0f..b700e193 100644
--- a/gradle-conventions/conventions-utils/build.gradle.kts
+++ b/gradle-conventions-settings/build.gradle.kts
@@ -15,24 +15,17 @@ configurations.configureEach {
}
}
-val kotlinVersion: String by extra
+val kotlinVersion: KotlinVersion by extra
+val isLatestKotlinVersion: Boolean by extra
dependencies {
api(libs.kotlin.gradle.plugin)
api(libs.detekt.gradle.plugin)
- if (kotlinVersion >= "1.8.0") {
+ if (isLatestKotlinVersion) {
api(libs.kover.gradle.plugin)
}
// https://stackoverflow.com/questions/76713758/use-version-catalog-inside-precompiled-gradle-plugin
api(files(libs.javaClass.superclass.protectionDomain.codeSource.location))
}
-
-gradlePlugin {
- plugins {
- named("conventions-utils") {
- version = libs.versions.kotlinx.rpc.get()
- }
- }
-}
diff --git a/gradle-settings-conventions/settings.gradle.kts b/gradle-conventions-settings/settings.gradle.kts
similarity index 64%
rename from gradle-settings-conventions/settings.gradle.kts
rename to gradle-conventions-settings/settings.gradle.kts
index 3336274f..0f5b82b4 100644
--- a/gradle-settings-conventions/settings.gradle.kts
+++ b/gradle-conventions-settings/settings.gradle.kts
@@ -2,7 +2,7 @@
* Copyright 2023-2024 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
-rootProject.name = "gradle-settings-conventions"
+rootProject.name = "gradle-conventions-settings"
// Code below is a hack because a chicken-egg problem, I can't use myself as a settings-plugin
-apply(from="src/main/kotlin/settings-conventions.settings.gradle.kts")
+apply(from = "src/main/kotlin/settings-conventions.settings.gradle.kts")
diff --git a/gradle-settings-conventions/src/main/kotlin/includePublic.kt b/gradle-conventions-settings/src/main/kotlin/includePublic.kt
similarity index 100%
rename from gradle-settings-conventions/src/main/kotlin/includePublic.kt
rename to gradle-conventions-settings/src/main/kotlin/includePublic.kt
diff --git a/gradle-settings-conventions/src/main/kotlin/settings-conventions.settings.gradle.kts b/gradle-conventions-settings/src/main/kotlin/settings-conventions.settings.gradle.kts
similarity index 86%
rename from gradle-settings-conventions/src/main/kotlin/settings-conventions.settings.gradle.kts
rename to gradle-conventions-settings/src/main/kotlin/settings-conventions.settings.gradle.kts
index 88e6923b..3a78d912 100644
--- a/gradle-settings-conventions/src/main/kotlin/settings-conventions.settings.gradle.kts
+++ b/gradle-conventions-settings/src/main/kotlin/settings-conventions.settings.gradle.kts
@@ -40,9 +40,9 @@ object SettingsConventions {
const val VERSIONS_SECTION_NAME = "[versions]"
- const val GRADLE_WRAPPER_FOLDER = "gradle"
- const val LIBS_VERSION_CATALOG_PATH = "$GRADLE_WRAPPER_FOLDER/libs.versions.toml"
- const val KOTLIN_VERSIONS_LOOKUP_PATH = "$GRADLE_WRAPPER_FOLDER/kotlin-versions-lookup.csv"
+ const val VERSIONS_ROOT_PATH = "versions-root"
+ const val LIBS_VERSION_CATALOG_PATH = "$VERSIONS_ROOT_PATH/libs.versions.toml"
+ const val KOTLIN_VERSIONS_LOOKUP_PATH = "$VERSIONS_ROOT_PATH/kotlin-versions-lookup.csv"
}
// ### VERSION RESOLVING SECTION ###
@@ -51,18 +51,17 @@ object SettingsConventions {
// This plugin can be applied in different subprojects,
// so we need a way to find global project root for kotlinx.rpc project
-// to be able to resolve 'gradle/libs.versions.toml' and other files
-fun findGlobalRootDirPath(start: Path, onDir: () -> Unit = {}): Path {
+// to be able to resolve 'versions-root/libs.versions.toml' and other files
+fun findGlobalRootDirPath(start: Path): Path {
var path = start
- // we assume that `gradle` folder can only be present in the root folder
+ // we assume that VERSIONS_ROOT_PATH folder can only be present in the root folder
while (
Files.newDirectoryStream(path).use { it.toList() }.none {
- Files.isDirectory(it) && it.fileName.toString() == SettingsConventions.GRADLE_WRAPPER_FOLDER
+ Files.isDirectory(it) && it.fileName.toString() == SettingsConventions.VERSIONS_ROOT_PATH
}
) {
path = path.parent ?: error("Unable to find root path for kotlinx.rpc project")
- onDir()
}
gradle.rootProject {
@@ -74,7 +73,7 @@ fun findGlobalRootDirPath(start: Path, onDir: () -> Unit = {}): Path {
return path
}
-// Resolves 'gradle/kotlin-versions-lookup.csv'
+// Resolves 'versions-root/kotlin-versions-lookup.csv'
fun loadLookupTable(rootDir: Path, kotlinVersion: String): Pair