diff --git a/.run/PublishAllToLocal.run.xml b/.run/PublishAllToLocal.run.xml
new file mode 100644
index 0000000..8d3e8ff
--- /dev/null
+++ b/.run/PublishAllToLocal.run.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ true
+ false
+ false
+
+
+
\ No newline at end of file
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index 9d385fe..3f035b5 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -9,7 +9,7 @@ repositories {
}
val kotlinVersion = "1.8.21"
-val dokkaPluginVersion = "1.8.10"
+val dokkaPluginVersion = "1.8.20"
val gradleCommon = "0.0.11"
dependencies {
diff --git a/buildSrc/src/main/kotlin/IProject.kt b/buildSrc/src/main/kotlin/IProject.kt
index 8adbfb1..2492bb3 100644
--- a/buildSrc/src/main/kotlin/IProject.kt
+++ b/buildSrc/src/main/kotlin/IProject.kt
@@ -8,7 +8,7 @@ object IProject : ProjectDetail() {
const val DESCRIPTION = "Generate platform-compatible functions for Kotlin suspend functions"
const val HOMEPAGE = "https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin"
- override val version: Version = version(0, 3, 2)
+ override val version: Version = version(0, 4, 0)
override val homepage: String get() = HOMEPAGE
diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformTransformer.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformTransformer.kt
index d2474a0..ba44e2c 100644
--- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformTransformer.kt
+++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformTransformer.kt
@@ -1,6 +1,9 @@
package love.forte.plugin.suspendtrans.ir
-import love.forte.plugin.suspendtrans.*
+import love.forte.plugin.suspendtrans.SuspendTransformConfiguration
+import love.forte.plugin.suspendtrans.SuspendTransformUserData
+import love.forte.plugin.suspendtrans.SuspendTransformUserDataKey
+import love.forte.plugin.suspendtrans.fqn
import love.forte.plugin.suspendtrans.utils.*
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.extensions.FirIncompatiblePluginAPI
@@ -9,16 +12,16 @@ import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
-import org.jetbrains.kotlin.ir.builders.irBlockBody
-import org.jetbrains.kotlin.ir.builders.irCall
-import org.jetbrains.kotlin.ir.builders.irGet
-import org.jetbrains.kotlin.ir.builders.irReturn
+import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody
+import org.jetbrains.kotlin.ir.expressions.IrCall
+import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
+import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
-import org.jetbrains.kotlin.ir.types.isSubtypeOfClass
-import org.jetbrains.kotlin.ir.types.typeWith
-import org.jetbrains.kotlin.ir.util.*
+import org.jetbrains.kotlin.ir.types.*
+import org.jetbrains.kotlin.ir.util.isAnnotationWithEqualFqName
+import org.jetbrains.kotlin.ir.util.primaryConstructor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
@@ -92,7 +95,8 @@ class SuspendTransformTransformer(
private fun resolveFunctionBodyByDescriptor(declaration: IrFunction, descriptor: CallableDescriptor): IrFunction? {
val userData = descriptor.getUserData(SuspendTransformUserDataKey) ?: return null
- val callableFunction = pluginContext.referenceFunctions(userData.transformer.transformFunctionInfo.toCallableId()).firstOrNull()
+ val callableFunction =
+ pluginContext.referenceFunctions(userData.transformer.transformFunctionInfo.toCallableId()).firstOrNull()
?: throw IllegalStateException("Transform function ${userData.transformer.transformFunctionInfo} not found")
val generatedOriginFunction = resolveFunctionBody(declaration, userData.originFunction, callableFunction)
@@ -112,7 +116,7 @@ class SuspendTransformTransformer(
currentAnnotations.any { a -> a.isAnnotationWithEqualFqName(name) }
addAll(currentAnnotations)
- val syntheticFunctionIncludes = userData.transformer.originFunctionIncludeAnnotations
+ val syntheticFunctionIncludes = userData.transformer.originFunctionIncludeAnnotations
syntheticFunctionIncludes.forEach { include ->
val classId = include.classInfo.toClassId()
@@ -205,24 +209,69 @@ private fun generateTransformBodyForFunction(
//println(transformTargetFunctionCall.owner.valueParameters)
val owner = transformTargetFunctionCall.owner
- if (owner.valueParameters.size > 1) {
- val secondType = owner.valueParameters[1].type
- val coroutineScopeTypeName = "kotlinx.coroutines.CoroutineScope".fqn
- val coroutineScopeTypeClassId = ClassId.topLevel("kotlinx.coroutines.CoroutineScope".fqn)
- val coroutineScopeTypeNameUnsafe = coroutineScopeTypeName.toUnsafe()
- if (secondType.isClassType(coroutineScopeTypeNameUnsafe)) {
- function.dispatchReceiverParameter?.also { dispatchReceiverParameter ->
- context.referenceClass(coroutineScopeTypeClassId)?.also { coroutineScopeRef ->
- if (dispatchReceiverParameter.type.isSubtypeOfClass(coroutineScopeRef)) {
- // put 'this' to second arg
- putValueArgument(1, irGet(dispatchReceiverParameter))
- }
- }
- }
- }
+ // CoroutineScope
+ val ownerValueParameters = owner.valueParameters
+ if (ownerValueParameters.size > 1) {
+ for (index in 1..ownerValueParameters.lastIndex) {
+ val valueParameter = ownerValueParameters[index]
+ val type = valueParameter.type
+ tryResolveCoroutineScopeValueParameter(type, context, function, owner, this@irBlockBody, index)
+ }
}
})
}
}
+
+private val coroutineScopeTypeName = "kotlinx.coroutines.CoroutineScope".fqn
+private val coroutineScopeTypeClassId = ClassId.topLevel("kotlinx.coroutines.CoroutineScope".fqn)
+private val coroutineScopeTypeNameUnsafe = coroutineScopeTypeName.toUnsafe()
+
+/**
+ * 解析类型为 CoroutineScope 的参数。
+ * 如果当前参数类型为 CoroutineScope:
+ * - 如果当前 receiver 即为 CoroutineScope 类型,将其填充
+ * - 如果当前 receiver 不是 CoroutineScope 类型,但是此参数可以为 null,
+ * 则使用 safe-cast 将 receiver 转化为 CoroutineScope ( `dispatcher as? CoroutineScope` )
+ * - 其他情况忽略此参数(适用于此参数有默认值的情况)
+ */
+private fun IrCall.tryResolveCoroutineScopeValueParameter(
+ type: IrType,
+ context: IrPluginContext,
+ function: IrFunction,
+ owner: IrSimpleFunction,
+ builderWithScope: IrBuilderWithScope,
+ index: Int
+) {
+ if (!type.isClassType(coroutineScopeTypeNameUnsafe)) {
+ return
+ }
+
+ function.dispatchReceiverParameter?.also { dispatchReceiverParameter ->
+ context.referenceClass(coroutineScopeTypeClassId)?.also { coroutineScopeRef ->
+ if (dispatchReceiverParameter.type.isSubtypeOfClass(coroutineScopeRef)) {
+ // put 'this' to the arg
+ putValueArgument(index, builderWithScope.irGet(dispatchReceiverParameter))
+ } else {
+ val scopeType = coroutineScopeRef.defaultType
+
+ val scopeParameter = owner.valueParameters.getOrNull(1)
+
+ if (scopeParameter?.type?.isNullable() == true) {
+ val irSafeAs = IrTypeOperatorCallImpl(
+ startOffset,
+ endOffset,
+ scopeType,
+ IrTypeOperator.SAFE_CAST,
+ scopeType,
+ builderWithScope.irGet(dispatchReceiverParameter)
+ )
+
+ putValueArgument(index, irSafeAs)
+ }
+// irAs(irGet(dispatchReceiverParameter), coroutineScopeRef.defaultType)
+ }
+ }
+ }
+}
diff --git a/runtime/suspend-transform-runtime/src/jvmMain/kotlin/love/forte/plugin/suspendtrans/runtime/RunInSuspendJvm.kt b/runtime/suspend-transform-runtime/src/jvmMain/kotlin/love/forte/plugin/suspendtrans/runtime/RunInSuspendJvm.kt
index 53b8b5c..d344b6a 100644
--- a/runtime/suspend-transform-runtime/src/jvmMain/kotlin/love/forte/plugin/suspendtrans/runtime/RunInSuspendJvm.kt
+++ b/runtime/suspend-transform-runtime/src/jvmMain/kotlin/love/forte/plugin/suspendtrans/runtime/RunInSuspendJvm.kt
@@ -74,9 +74,9 @@ private val transformer: FutureTransformer =
@Suppress("FunctionName")
public fun `$runInAsync$`(
block: suspend () -> T,
- scope: CoroutineScope = `$CoroutineScope4J$`
+ scope: CoroutineScope? = null
): CompletableFuture {
- return transformer.trans(scope, block)
+ return transformer.trans(scope ?: `$CoroutineScope4J$`, block)
}
diff --git a/suspend-transform-plugin-sample/build.gradle.kts b/suspend-transform-plugin-sample/build.gradle.kts
index f7a00f6..34e2533 100644
--- a/suspend-transform-plugin-sample/build.gradle.kts
+++ b/suspend-transform-plugin-sample/build.gradle.kts
@@ -8,6 +8,7 @@ plugins {
// id(project(":suspend-transform-plugin-gradle"))
}
+
buildscript {
this@buildscript.repositories {
mavenLocal()
@@ -15,7 +16,7 @@ plugins {
}
dependencies {
//this.implementation()
- classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:0.3.2")
+ classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:0.4.0")
}
}
@@ -24,9 +25,10 @@ plugins {
// sourceCompatibility = "11"
// targetCompatibility = "11"
//}
-//withType {
-// kotlinOptions.jvmTarget = "11"
-//}
+
+tasks.withType {
+ kotlinOptions.freeCompilerArgs += "-Xjvm-default=all"
+}
repositories {
mavenLocal()
@@ -36,9 +38,10 @@ apply(plugin = "love.forte.plugin.suspend-transform")
dependencies {
api(kotlin("stdlib"))
-// api("love.forte.plugin.suspend-transform:suspend-transform-runtime:0.3.2")
-// api("love.forte.plugin.suspend-transform:suspend-transform-annotation:0.3.2")
- api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.0")
+// val pluginVersion = "0.4.0"
+// api("love.forte.plugin.suspend-transform:suspend-transform-runtime:$pluginVersion")
+// api("love.forte.plugin.suspend-transform:suspend-transform-annotation:$pluginVersion")
+ api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
}
extensions.getByType().apply {
diff --git a/suspend-transform-plugin-sample/src/main/kotlin/love/forte/plugin/suspendtrans/sample/ForteScarlet.kt b/suspend-transform-plugin-sample/src/main/kotlin/love/forte/plugin/suspendtrans/sample/ForteScarlet.kt
index 9c743d7..3e789a0 100644
--- a/suspend-transform-plugin-sample/src/main/kotlin/love/forte/plugin/suspendtrans/sample/ForteScarlet.kt
+++ b/suspend-transform-plugin-sample/src/main/kotlin/love/forte/plugin/suspendtrans/sample/ForteScarlet.kt
@@ -3,22 +3,37 @@ package love.forte.plugin.suspendtrans.sample
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import love.forte.plugin.suspendtrans.annotation.JvmAsync
+import love.forte.plugin.suspendtrans.annotation.JvmBlocking
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
+abstract class IForteScarlet {
+ @JvmAsync
+ @JvmBlocking
+ abstract suspend fun stringToInt(value: String): Int
+}
+
+
/**
*
* @author ForteScarlet
*/
-class ForteScarlet : CoroutineScope {
+class ForteScarlet : CoroutineScope, IForteScarlet() {
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
@JvmAsync
- suspend fun stringToInt(value: String): Int {
+ @JvmBlocking
+ override suspend fun stringToInt(value: String): Int {
delay(5)
return value.toInt()
}
+ // @JvmAsync
+// suspend fun stringToInt(value: String): Int {
+// delay(5)
+// return value.toInt()
+// }
+
}