From 6a95c9bb54b0c602dedf7e8c33a7b18e43b758c5 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Thu, 10 Apr 2025 18:26:28 +0800 Subject: [PATCH 01/21] Add README for suspend-transform-plugin-cli --- compiler/suspend-transform-plugin-cli/README.md | 6 ++++++ settings.gradle.kts | 1 + 2 files changed, 7 insertions(+) create mode 100644 compiler/suspend-transform-plugin-cli/README.md diff --git a/compiler/suspend-transform-plugin-cli/README.md b/compiler/suspend-transform-plugin-cli/README.md new file mode 100644 index 0000000..6130688 --- /dev/null +++ b/compiler/suspend-transform-plugin-cli/README.md @@ -0,0 +1,6 @@ +# CliOption Module + +TODO:将 CliOption 相关的内容独立出来, +以避免在 Gradle Plugin 中传递引用 Kotlin compiler。 + +see also: diff --git a/settings.gradle.kts b/settings.gradle.kts index 619a39c..656f762 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -20,6 +20,7 @@ dependencyResolutionManagement { } include(":compiler:suspend-transform-plugin") +include(":compiler:suspend-transform-plugin-cli") include(":compiler:suspend-transform-plugin-embeddable") include(":runtime:suspend-transform-annotation") From c60594b05d8c67f04b51a333ce5f8f0f49f3ca0e Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 11 Apr 2025 18:23:49 +0800 Subject: [PATCH 02/21] new Gradle providers API --- buildSrc/src/main/kotlin/IProject.kt | 2 +- .../build.gradle.kts | 70 ++++ .../cli/GradlePluginCliOptions.kt | 11 + .../cli/KotlinCompilerPluginCliOptions.kt | 3 + .../cli/SuspendTransformCliOption.kt | 80 ++++ .../cli/SuspendTransformCliOptions.kt | 13 + .../build.gradle.kts | 68 +++ .../SuspendTransformConfiguration.kt | 309 ++++++++++++++ .../SuspendTransformConfiguration.kt | 2 +- gradle/libs.versions.toml | 2 + .../build.gradle.kts | 8 + .../gradle/SuspendTransformGradlePlugin.kt | 9 + .../gradle/SuspendTransformPluginExtension.kt | 390 ++++++++++++++++++ settings.gradle.kts | 7 +- tests/test-jvm/build.gradle.kts | 108 +++-- 15 files changed, 1039 insertions(+), 43 deletions(-) create mode 100644 compiler/suspend-transform-plugin-cli/build.gradle.kts create mode 100644 compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/GradlePluginCliOptions.kt create mode 100644 compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/KotlinCompilerPluginCliOptions.kt create mode 100644 compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt create mode 100644 compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOptions.kt create mode 100644 compiler/suspend-transform-plugin-configuration/build.gradle.kts create mode 100644 compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt create mode 100644 plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt diff --git a/buildSrc/src/main/kotlin/IProject.kt b/buildSrc/src/main/kotlin/IProject.kt index d969090..ef6e09a 100644 --- a/buildSrc/src/main/kotlin/IProject.kt +++ b/buildSrc/src/main/kotlin/IProject.kt @@ -11,7 +11,7 @@ object IProject : ProjectDetail() { // Remember the libs.versions.toml! val ktVersion = "2.1.20" - val pluginVersion = "0.11.1" + val pluginVersion = "0.12.0" override val version: String = "$ktVersion-$pluginVersion" diff --git a/compiler/suspend-transform-plugin-cli/build.gradle.kts b/compiler/suspend-transform-plugin-cli/build.gradle.kts new file mode 100644 index 0000000..5165ffb --- /dev/null +++ b/compiler/suspend-transform-plugin-cli/build.gradle.kts @@ -0,0 +1,70 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") + kotlin("plugin.serialization") + // id("com.github.gmazzo.buildconfig") + id("suspend-transform.jvm-maven-publish") +} + +dependencies { + compileOnly(kotlin("stdlib")) + compileOnly(kotlin("compiler")) + api(project(":compiler:suspend-transform-plugin-configuration")) + api(libs.kotlinx.serialization.core) + api(libs.kotlinx.serialization.protobuf) + + // testImplementation("junit:junit:4.13.2") + testImplementation(kotlin("stdlib")) + testImplementation(kotlin("test-junit5")) + + testImplementation(kotlin("compiler")) + testImplementation(kotlin("reflect")) + +// testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.4.9") +// testImplementation("org.bitbucket.mstrobel:procyon-compilertools:0.6.0") + + testImplementation(libs.kotlinx.coroutines.core) +} + +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_1_8) + // optIn.addAll( + // "kotlin.RequiresOptIn", + // "org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI" + // ) + freeCompilerArgs.addAll( + "-Xjvm-default=all", +// "-opt-in=kotlin.RequiresOptIn", +// "-opt-in=org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI", + ) + } +} + +tasks.withType(KotlinCompile::class.java).configureEach { + // see https://youtrack.jetbrains.com/issue/KTIJ-21563 + // see https://youtrack.jetbrains.com/issue/KT-57297 +// kotlinOptions { +// languageVersion = "1.9" +// apiVersion = "1.9" +// } +} + +repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots/") + mavenContent { + snapshotsOnly() + } + } +} + +// buildConfig { +// useKotlinOutput { +// internalVisibility = true +// } +// withoutPackage() +// buildConfigField("String", "KOTLIN_PLUGIN_ID", "\"${rootProject.extra["kotlin_plugin_id"]}\"") +// } diff --git a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/GradlePluginCliOptions.kt b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/GradlePluginCliOptions.kt new file mode 100644 index 0000000..8dea49e --- /dev/null +++ b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/GradlePluginCliOptions.kt @@ -0,0 +1,11 @@ +package love.forte.plugin.suspendtrans.cli + +// Cli Options for gradle plugin + +interface GradlePluginSuspendTransformCliOption : SuspendTransformCliOption { + /** + * Encode a value [T] to a String CLI option. + * _Should use base64(protobuf(value))_ + */ + fun encode(value: T): String +} diff --git a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/KotlinCompilerPluginCliOptions.kt b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/KotlinCompilerPluginCliOptions.kt new file mode 100644 index 0000000..d9e4892 --- /dev/null +++ b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/KotlinCompilerPluginCliOptions.kt @@ -0,0 +1,3 @@ +package love.forte.plugin.suspendtrans.cli + +// Cli Options for Kotlin compiler plugin diff --git a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt new file mode 100644 index 0000000..2b58567 --- /dev/null +++ b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt @@ -0,0 +1,80 @@ +package love.forte.plugin.suspendtrans.cli + +import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption + +/** + * + * + * @author ForteScarlet + */ +interface SuspendTransformCliOption { + val optionName: String + val valueDescription: String + val description: String + val required: Boolean + val allowMultipleOccurrences: Boolean +} + +private data class SimpleSuspendTransformCliOption( + override val allowMultipleOccurrences: Boolean, + override val description: String, + override val optionName: String, + override val required: Boolean, + override val valueDescription: String +) : SuspendTransformCliOption + +private data class AbstractCliOptionImpl( + override val allowMultipleOccurrences: Boolean, + override val description: String, + override val optionName: String, + override val required: Boolean, + override val valueDescription: String +) : AbstractCliOption, SuspendTransformCliOption + +/** + * Creates an instance of [SuspendTransformCliOption] to describe and define a CLI option. + * + * @param optionName The name of the option used to identify it in the CLI. + * @param valueDescription A description of the option's value, defaults to the option name. + * @param description A textual description of the option, defaults to an empty string. + * @param required Whether this option is mandatory, defaults to not required (`false`). + * @param allowMultipleOccurrences Whether this option can appear multiple times in the CLI, + * defaults to not allowed (`false`). + * @return Returns an instance of [SuspendTransformCliOption] implemented by [SimpleSuspendTransformCliOption]. + */ +fun SuspendTransformCliOption( + optionName: String, + valueDescription: String = optionName, + description: String = "", + required: Boolean = false, + allowMultipleOccurrences: Boolean = false +): SuspendTransformCliOption { + // Create and return an instance of the concrete implementation class + return SimpleSuspendTransformCliOption( + allowMultipleOccurrences = allowMultipleOccurrences, + description = description, + optionName = optionName, + required = required, + valueDescription = valueDescription + ) +} + +/** + * Converts the current [SuspendTransformCliOption] instance to an [AbstractCliOption]. + * If the current object is already an [AbstractCliOption], it is returned directly; + * otherwise, a new instance is created and returned. + * + * @return The converted [AbstractCliOption] instance + */ +fun SuspendTransformCliOption.toAbstractCliOption(): AbstractCliOption { + return this as? AbstractCliOption ?: AbstractCliOptionImpl( + allowMultipleOccurrences = allowMultipleOccurrences, + description = description, + optionName = optionName, + required = required, + valueDescription = valueDescription + ) +} + + + diff --git a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOptions.kt b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOptions.kt new file mode 100644 index 0000000..cce0308 --- /dev/null +++ b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOptions.kt @@ -0,0 +1,13 @@ +package love.forte.plugin.suspendtrans.cli + +object SuspendTransformCliOptions { + const val CONFIGURATION = "configuration" + + val ENABLED = SuspendTransformCliOption( + optionName = "enabled", + valueDescription = "Whether to enable the plugin", + description = "Whether to enable the plugin", + ) + + +} diff --git a/compiler/suspend-transform-plugin-configuration/build.gradle.kts b/compiler/suspend-transform-plugin-configuration/build.gradle.kts new file mode 100644 index 0000000..3ef63d8 --- /dev/null +++ b/compiler/suspend-transform-plugin-configuration/build.gradle.kts @@ -0,0 +1,68 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + kotlin("jvm") + kotlin("plugin.serialization") + // id("com.github.gmazzo.buildconfig") + id("suspend-transform.jvm-maven-publish") +} + +dependencies { + compileOnly(kotlin("stdlib")) + // compileOnly(kotlin("compiler")) + api(libs.kotlinx.serialization.core) + // api(libs.kotlinx.serialization.protobuf) + + // testImplementation("junit:junit:4.13.2") + testImplementation(kotlin("stdlib")) + testImplementation(kotlin("test-junit5")) + + // testImplementation(kotlin("compiler")) + testImplementation(kotlin("reflect")) + +// testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.4.9") +// testImplementation("org.bitbucket.mstrobel:procyon-compilertools:0.6.0") + // testImplementation(libs.kotlinx.coroutines.core) +} + +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_1_8) + // optIn.addAll( + // "kotlin.RequiresOptIn", + // "org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI" + // ) + freeCompilerArgs.addAll( + "-Xjvm-default=all", +// "-opt-in=kotlin.RequiresOptIn", +// "-opt-in=org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI", + ) + } +} + +tasks.withType(KotlinCompile::class.java).configureEach { + // see https://youtrack.jetbrains.com/issue/KTIJ-21563 + // see https://youtrack.jetbrains.com/issue/KT-57297 +// kotlinOptions { +// languageVersion = "1.9" +// apiVersion = "1.9" +// } +} + +repositories { + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots/") + mavenContent { + snapshotsOnly() + } + } +} + +// buildConfig { +// useKotlinOutput { +// internalVisibility = true +// } +// withoutPackage() +// buildConfigField("String", "KOTLIN_PLUGIN_ID", "\"${rootProject.extra["kotlin_plugin_id"]}\"") +// } diff --git a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt new file mode 100644 index 0000000..7f31eb4 --- /dev/null +++ b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt @@ -0,0 +1,309 @@ +package love.forte.plugin.suspendtrans.configuration + +import kotlinx.serialization.Serializable + +@RequiresOptIn( + "This is an internal suspend transform config api. " + + "It may be changed in the future without notice.", RequiresOptIn.Level.ERROR +) +annotation class InternalSuspendTransformConstructorApi + +@Serializable +class FunctionInfo @InternalSuspendTransformConstructorApi constructor( + val packageName: String, + val functionName: String +) + +@Serializable +class ClassInfo @InternalSuspendTransformConstructorApi constructor( + val packageName: String, + val className: String, + val local: Boolean = false, + val nullable: Boolean = false, +) + +@Serializable +enum class TargetPlatform { + COMMON, JVM, JS, WASM, NATIVE +} + +/** + * 用于标记的注解信息. + */ +@Serializable +class MarkAnnotation @InternalSuspendTransformConstructorApi constructor( + /** + * 注解类信息 + */ + val classInfo: ClassInfo, + /** + * 用于标记生成函数需要使用的基础函数名的注解属性名。 + */ + val baseNameProperty: String = "baseName", + /** + * 用于标记生成函数需要使用的基础函数名之后的后缀的注解属性名。 + */ + val suffixProperty: String = "suffix", + /** + * 用于标记生成函数是否需要转化为 property 类型的注解属性名。 + */ + val asPropertyProperty: String = "asProperty", + /** + * 当 [suffixProperty] 不存在时使用的默认后缀 + */ + val defaultSuffix: String = "", + /** + * 当 [asPropertyProperty] 不存在时使用的默认值 + */ + val defaultAsProperty: Boolean = false, +) + +@Serializable +class IncludeAnnotation @InternalSuspendTransformConstructorApi constructor( + val classInfo: ClassInfo, + val repeatable: Boolean = false, + /** + * 如果是追加,是否追加到property上 + * + * @since 0.9.0 + */ + val includeProperty: Boolean = false +) + +@Serializable +class Transformer @InternalSuspendTransformConstructorApi constructor( + /** + * 函数上的某种标记。 + */ + val markAnnotation: MarkAnnotation, + + /** + * 用于转化的函数信息。 + * + * 这个函数的实际格式必须为 + * + * ```kotlin + * fun (block: suspend () -> T[, scope: CoroutineScope = ...]): T { + * // ... + * } + * ``` + * + * 其中,此异步函数可以有第二个参数,此参数格式必须为 [kotlinx.coroutines.CoroutineScope]。 + * 如果存在此参数,当转化函数所处类型自身实现了 [kotlinx.coroutines.CoroutineScope] 时,将会将其自身作为参数填入,类似于: + * + * ```kotlin + * class Bar : CoroutineScope { + * @Xxx + * suspend fun foo(): Foo + * + * @Api4J fun fooXxx(): CompletableFuture = transform(block = { foo() }, scope = this) + * } + */ + val transformFunctionInfo: FunctionInfo, + + /** + * 转化后的返回值类型, 为null时代表与原函数一致。 + */ + val transformReturnType: ClassInfo?, + + // TODO TypeGeneric for suspend function return type and transform function return type? + + /** + * 转化后的返回值类型中,是否存在需要与原本返回值类型一致的泛型。 + */ + val transformReturnTypeGeneric: Boolean, + + /** + * 函数生成后,需要在原函数上追加的注解信息。 + * + * 例如追加个 `@kotlin.jvm.JvmSynthetic` 之类的。 + */ + val originFunctionIncludeAnnotations: List, + + /** + * 需要在生成出来的函数上追加的注解信息。(不需要指定 `@Generated`) + */ + val syntheticFunctionIncludeAnnotations: List, + + /** + * 是否复制源函数上的注解到新的函数上。 + * 如果生成的是属性类型,则表示是否复制到 `getter` 上。 + */ + val copyAnnotationsToSyntheticFunction: Boolean, + + /** + * 复制原函数上注解时需要排除掉的注解。 + */ + val copyAnnotationExcludes: List, + + /** + * 如果是生成属性的话,是否复制源函数上的注解到新的属性上 + * + * @since 0.9.0 + */ + val copyAnnotationsToSyntheticProperty: Boolean = false +) + +@Serializable +class SuspendTransformConfiguration @InternalSuspendTransformConstructorApi constructor( + val enabled: Boolean, + val transformers: Map> +) + +/** + * Some constants for configuration. + */ +@OptIn(InternalSuspendTransformConstructorApi::class) +object SuspendTransformConfigurations { + private const val KOTLIN = "kotlin" + private const val KOTLIN_JVM = "kotlin.jvm" + private const val KOTLIN_JS = "kotlin.js" + + private const val SUSPENDTRANS_ANNOTATION_PACKAGE = "love.forte.plugin.suspendtrans.annotation" + private const val SUSPENDTRANS_RUNTIME_PACKAGE = "love.forte.plugin.suspendtrans.runtime" + + private const val JVM_RUN_IN_BLOCKING_FUNCTION_FUNCTION_NAME = "\$runInBlocking\$" + private const val JVM_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME = "\$runInAsync\$" + + private const val JS_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME = "\$runInAsync\$" + + //region JVM Defaults + @JvmStatic + val jvmSyntheticClassInfo = ClassInfo( + packageName = KOTLIN_JVM, + className = "JvmSynthetic" + ) + + @JvmStatic + val kotlinOptInClassInfo = ClassInfo( + packageName = KOTLIN, + className = "OptIn" + ) + + @JvmStatic + val jvmApi4JAnnotationClassInfo = ClassInfo( + packageName = SUSPENDTRANS_ANNOTATION_PACKAGE, + className = "Api4J" + ) + + @JvmStatic + val jvmBlockingMarkAnnotationClassInfo = ClassInfo( + packageName = SUSPENDTRANS_ANNOTATION_PACKAGE, + className = "JvmBlocking" + ) + + @JvmStatic + val jvmBlockingAnnotationInfo = MarkAnnotation( + classInfo = jvmBlockingMarkAnnotationClassInfo, + defaultSuffix = "Blocking" + ) + + @JvmStatic + val jvmBlockingTransformFunction = FunctionInfo( + packageName = SUSPENDTRANS_RUNTIME_PACKAGE, + functionName = JVM_RUN_IN_BLOCKING_FUNCTION_FUNCTION_NAME, + ) + + @JvmStatic + val jvmAsyncMarkAnnotationClassInfo = ClassInfo( + packageName = SUSPENDTRANS_ANNOTATION_PACKAGE, + className = "JvmAsync" + ) + + @JvmStatic + val jvmAsyncAnnotationInfo = MarkAnnotation( + classInfo = jvmAsyncMarkAnnotationClassInfo, + defaultSuffix = "Async" + ) + + @JvmStatic + val jvmAsyncTransformFunction = FunctionInfo( + packageName = SUSPENDTRANS_RUNTIME_PACKAGE, + functionName = JVM_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME, + ) + + @JvmStatic + val jvmBlockingTransformer = Transformer( + markAnnotation = jvmBlockingAnnotationInfo, + transformFunctionInfo = jvmBlockingTransformFunction, + transformReturnType = null, + transformReturnTypeGeneric = false, + originFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmSyntheticClassInfo)), + syntheticFunctionIncludeAnnotations = listOf( + IncludeAnnotation( + classInfo = jvmApi4JAnnotationClassInfo, + includeProperty = true + ) + ), + copyAnnotationsToSyntheticFunction = true, + copyAnnotationExcludes = listOf( + jvmSyntheticClassInfo, + jvmBlockingMarkAnnotationClassInfo, + jvmAsyncMarkAnnotationClassInfo, + kotlinOptInClassInfo, + ), + ) + + @JvmStatic + val jvmAsyncTransformer = Transformer( + markAnnotation = jvmAsyncAnnotationInfo, + transformFunctionInfo = jvmAsyncTransformFunction, + transformReturnType = ClassInfo("java.util.concurrent", "CompletableFuture"), + transformReturnTypeGeneric = true, + originFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmSyntheticClassInfo)), + syntheticFunctionIncludeAnnotations = listOf( + IncludeAnnotation(jvmApi4JAnnotationClassInfo, includeProperty = true) + ), + copyAnnotationsToSyntheticFunction = true, + copyAnnotationExcludes = listOf( + jvmSyntheticClassInfo, + jvmBlockingMarkAnnotationClassInfo, + jvmAsyncMarkAnnotationClassInfo, + kotlinOptInClassInfo, + ), + ) + //endregion + + //region JS Defaults + @JvmStatic + val jsApi4JsAnnotationInfo = ClassInfo( + packageName = SUSPENDTRANS_ANNOTATION_PACKAGE, + className = "Api4Js" + ) + + @JvmStatic + val jsAsyncMarkAnnotationClassInfo = ClassInfo( + packageName = SUSPENDTRANS_ANNOTATION_PACKAGE, + className = "JsPromise" + ) + + @JvmStatic + val jsAsyncAnnotationInfo = MarkAnnotation( + classInfo = jsAsyncMarkAnnotationClassInfo, + defaultSuffix = "Async" + ) + + @JvmStatic + val jsAsyncTransformFunction = FunctionInfo( + SUSPENDTRANS_RUNTIME_PACKAGE, + JS_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME, + ) + + @JvmStatic + val jsPromiseTransformer = Transformer( + markAnnotation = jsAsyncAnnotationInfo, + transformFunctionInfo = jsAsyncTransformFunction, + transformReturnType = ClassInfo(KOTLIN_JS, "Promise"), + transformReturnTypeGeneric = true, + originFunctionIncludeAnnotations = listOf(), + syntheticFunctionIncludeAnnotations = listOf( + IncludeAnnotation(jsApi4JsAnnotationInfo, includeProperty = true) + ), + copyAnnotationsToSyntheticFunction = true, + copyAnnotationExcludes = listOf( + jsAsyncMarkAnnotationClassInfo, + kotlinOptInClassInfo, + ) + ) + //endregion +} diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt index 9aede47..6b21ef2 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt @@ -71,7 +71,7 @@ data class Transformer( /** * 转化后的返回值类型中,是否存在需要与原本返回值类型一致的泛型。 */ - val transformReturnTypeGeneric: Boolean, + val transformReturnTypeGeneric: Boolean, /** * 函数生成后,需要在原函数上追加的注解信息。 diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d011c27..6982b43 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,9 @@ kotlinx-coroutines-jdk8 = { group = "org.jetbrains.kotlinx", name = "kotlinx-cor kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } # kotlinx-serialization +kotlinx-serialization-core = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-core", version.ref = "kotlinx-serialization" } kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "kotlinx-serialization" } +kotlinx-serialization-protobuf = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-protobuf", version.ref = "kotlinx-serialization" } # google auto-service diff --git a/plugins/suspend-transform-plugin-gradle/build.gradle.kts b/plugins/suspend-transform-plugin-gradle/build.gradle.kts index 2efccde..49b174a 100644 --- a/plugins/suspend-transform-plugin-gradle/build.gradle.kts +++ b/plugins/suspend-transform-plugin-gradle/build.gradle.kts @@ -30,9 +30,17 @@ dependencies { compileOnly(kotlin("gradle-plugin")) compileOnly(kotlin("gradle-plugin-api")) api(project(":compiler:suspend-transform-plugin")) + api(project(":compiler:suspend-transform-plugin-cli")) + api(project(":compiler:suspend-transform-plugin-configuration")) } +kotlin { + compilerOptions { + freeCompilerArgs.addAll("-Xjvm-default=all") + } +} + buildConfig { className("SuspendTransPluginConstants") useKotlinOutput { diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index e5b7ec5..d10fbcf 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -15,6 +15,15 @@ import org.jetbrains.kotlin.gradle.plugin.* open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { override fun apply(target: Project) { target.extensions.create("suspendTransform", SuspendTransformGradleExtension::class.java) + + val createdExtensions = target.extensions.create( + "suspendTransformPlugin", + SuspendTransformPluginExtension::class.java, + // AbstractSuspendTransformPluginExtension::class.java, + ) + + createdExtensions.defaults(target.objects, target.providers) + target.configureDependencies() } diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt new file mode 100644 index 0000000..e9d7a15 --- /dev/null +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -0,0 +1,390 @@ +package love.forte.plugin.suspendtrans.gradle + +import love.forte.plugin.suspendtrans.configuration.* +import org.gradle.api.Action +import org.gradle.api.DomainObjectSet +import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.* +import javax.inject.Inject + +abstract class TransformerContainer +@Inject constructor(private val objects: ObjectFactory) { + internal val transformers: MutableMap> = mutableMapOf() + + private fun getTransformers(platform: TargetPlatform): ListProperty = + transformers.computeIfAbsent(platform) { objects.listProperty(TransformerSpec::class.java) } + + fun add(platform: TargetPlatform, action: Action) { + val listProperty = getTransformers(platform) + listProperty.add(objects.newInstance(TransformerSpec::class.java).also(action::execute)) + } + + fun add(platform: TargetPlatform, transformer: TransformerSpec) { + val listProperty = getTransformers(platform) + listProperty.add(transformer) + } + + fun add(platform: TargetPlatform, transformer: Provider) { + val listProperty = getTransformers(platform) + listProperty.add(transformer) + } + + fun add(platform: TargetPlatform, transformer: Transformer) { + add(platform) { + it.from(transformer) + } + } + + fun addJvm(transformer: TransformerSpec) = add(TargetPlatform.JVM, transformer) + fun addJvm(transformer: Transformer) = addJvm { it.from(transformer) } + fun addJvm(transformer: Provider) = add(TargetPlatform.JVM, transformer) + fun addJvm(action: Action) = add(TargetPlatform.JVM, action) + + fun addJs(transformer: TransformerSpec) = add(TargetPlatform.JS, transformer) + fun addJs(transformer: Transformer) = addJs { it.from(transformer) } + fun addJs(transformer: Provider) = add(TargetPlatform.JS, transformer) + fun addJs(action: Action) = add(TargetPlatform.JS, action) + + fun addNative(transformer: TransformerSpec) = add(TargetPlatform.NATIVE, transformer) + fun addNative(transformer: Transformer) = addNative { it.from(transformer) } + fun addNative(transformer: Provider) = add(TargetPlatform.NATIVE, transformer) + fun addNative(action: Action) = add(TargetPlatform.NATIVE, action) + + fun addWasm(transformer: TransformerSpec) = add(TargetPlatform.WASM, transformer) + fun addWasm(transformer: Transformer) = addWasm { it.from(transformer) } + fun addWasm(transformer: Provider) = add(TargetPlatform.WASM, transformer) + fun addWasm(action: Action) = add(TargetPlatform.WASM, action) + + fun addCommon(transformer: TransformerSpec) = add(TargetPlatform.COMMON, transformer) + fun addCommon(transformer: Transformer) = addCommon { it.from(transformer) } + fun addCommon(transformer: Provider) = add(TargetPlatform.COMMON, transformer) + fun addCommon(action: Action) = add(TargetPlatform.COMMON, action) + + fun addJvmDefaults() { + + } +} + + +interface SuspendTransformPluginExtension { + val enabled: Property + + val transformers: TransformerContainer + + fun transformers(action: Action) { + action.execute(transformers) + } + + fun transformers(block: TransformerContainer.() -> Unit) { + transformers.block() + } + + fun useJvmDefault() { + transformers.addJvm(SuspendTransformConfigurations.jvmBlockingTransformer) + transformers.addJvm(SuspendTransformConfigurations.jvmAsyncTransformer) + } + + fun useJsDefault() { + transformers.addJs(SuspendTransformConfigurations.jsPromiseTransformer) + } + + fun useDefault() { + useJvmDefault() + useJsDefault() + } + + val includeAnnotation: Property + val includeRuntime: Property + + val annotationDependency: Property + + fun annotationDependency(action: Action) { + annotationDependency.set(annotationDependency.get().also(action::execute)) + } + + val runtimeDependency: Property + + fun runtimeDependency(action: Action) { + runtimeDependency.set(runtimeDependency.get().also(action::execute)) + } + + fun runtimeAsApi() { + runtimeDependency.get().configurationName.set("api") + } +} + +interface DependencySpec { + val version: Property + val configurationName: Property +} + +interface AnnotationDependencySpec : DependencySpec +interface RuntimeDependencySpec : DependencySpec + +internal fun SuspendTransformPluginExtension.defaults( + objects: ObjectFactory, + providers: ProviderFactory +) { + enabled.convention(true) + includeAnnotation.convention(true) + includeRuntime.convention(true) + annotationDependency.convention(providers.provider { + objects.newInstance(AnnotationDependencySpec::class.java).apply { + version.convention(SuspendTransPluginConstants.ANNOTATION_VERSION) + configurationName.convention("compileOnly") + } + }) + runtimeDependency.convention(providers.provider { + objects.newInstance(RuntimeDependencySpec::class.java).apply { + version.convention(SuspendTransPluginConstants.RUNTIME_VERSION) + configurationName.convention("implementation") + } + }) +} + +abstract class TransformerSpec @Inject constructor(private val objects: ObjectFactory) { + abstract val markAnnotation: Property + + fun markAnnotation(action: Action) { + markAnnotation.set(markAnnotation.get().also(action::execute)) + } + + fun markAnnotation(block: MarkAnnotationSpec.() -> Unit) { + markAnnotation(Action(block)) + } + + /** + * 用于转化的函数信息。 + * + * 这个函数的实际格式必须为 + * + * ```kotlin + * fun (block: suspend () -> T[, scope: CoroutineScope = ...]): T { + * // ... + * } + * ``` + * + * 其中,此异步函数可以有第二个参数,此参数格式必须为 [kotlinx.coroutines.CoroutineScope]。 + * 如果存在此参数,当转化函数所处类型自身实现了 [kotlinx.coroutines.CoroutineScope] 时,将会将其自身作为参数填入,类似于: + * + * ```kotlin + * class Bar : CoroutineScope { + * @Xxx + * suspend fun foo(): Foo + * + * @Api4J fun fooXxx(): CompletableFuture = transform(block = { foo() }, scope = this) + * } + */ + abstract val transformFunctionInfo: Property + + fun transformFunctionInfo(action: Action) { + transformFunctionInfo.set(transformFunctionInfo.get().also(action::execute)) + } + + fun transformFunctionInfo(block: FunctionInfoSpec.() -> Unit) { + transformFunctionInfo(Action(block)) + } + + /** + * 转化后的返回值类型, 为null时代表与原函数一致。 + */ + abstract val transformReturnType: Property + + fun transformReturnType(action: Action) { + transformReturnType.set(transformReturnType.get().also(action::execute)) + } + + fun transformReturnType(block: ClassInfoSpec.() -> Unit) { + transformReturnType(Action(block)) + } + + /** + * 转化后的返回值类型中,是否存在需要与原本返回值类型一致的泛型。 + */ + abstract val transformReturnTypeGeneric: Property + + /** + * 函数生成后,需要在原函数上追加的注解信息。 + * + * 例如追加个 `@kotlin.jvm.JvmSynthetic` 之类的。 + */ + abstract val originFunctionIncludeAnnotations: DomainObjectSet + + private fun newIncludeAnnotationSpec(): IncludeAnnotationSpec = + objects.newInstance(IncludeAnnotationSpec::class.java) + + fun addOriginFunctionIncludeAnnotation(action: Action) { + originFunctionIncludeAnnotations.add( + newIncludeAnnotationSpec().also(action::execute) + ) + } + + abstract val syntheticFunctionIncludeAnnotations: DomainObjectSet + + fun addSyntheticFunctionIncludeAnnotation(action: Action) { + syntheticFunctionIncludeAnnotations.add( + newIncludeAnnotationSpec().also(action::execute) + ) + } + + /** + * 是否复制源函数上的注解到新的函数上。 + * 如果生成的是属性类型,则表示是否复制到 `getter` 上。 + */ + abstract val copyAnnotationsToSyntheticFunction: Property + + /** + * 复制原函数上注解时需要排除掉的注解。 + */ + abstract val copyAnnotationExcludes: DomainObjectSet + + fun addCopyAnnotationExclude(action: Action) { + copyAnnotationExcludes.add(objects.newInstance(ClassInfoSpec::class.java).also(action::execute)) + } + + /** + * 如果是生成属性的话,是否复制源函数上的注解到新的属性上 + * + * @since 0.9.0 + */ + abstract val copyAnnotationsToSyntheticProperty: Property // = false + + /** + * Configures the current specification using a [Transformer]. + * + * @param transformer see [Transformer] or the constants in [SuspendTransformConfigurations], + * e.g. [SuspendTransformConfigurations.jvmBlockingTransformer]. + */ + fun from(transformer: Transformer) { + markAnnotation { from(transformer.markAnnotation) } + transformFunctionInfo { from(transformer.transformFunctionInfo) } + transformer.transformReturnType?.also { transformReturnType { from(it) } } + transformReturnTypeGeneric.set(transformer.transformReturnTypeGeneric) + for (originFunctionIncludeAnnotation in transformer.originFunctionIncludeAnnotations) { + addOriginFunctionIncludeAnnotation { + it.from(originFunctionIncludeAnnotation) + } + } + + for (syntheticFunctionIncludeAnnotation in transformer.syntheticFunctionIncludeAnnotations) { + addSyntheticFunctionIncludeAnnotation { + it.from(syntheticFunctionIncludeAnnotation) + } + } + + copyAnnotationsToSyntheticFunction.set(transformer.copyAnnotationsToSyntheticFunction) + + for (copyAnnotationExclude in transformer.copyAnnotationExcludes) { + addCopyAnnotationExclude { + it.from(copyAnnotationExclude) + } + } + + copyAnnotationsToSyntheticProperty.set(transformer.copyAnnotationsToSyntheticProperty) + } +} + +/** + * @see MarkAnnotation + */ +interface MarkAnnotationSpec { + /** + * 注解类信息 + */ + val classInfo: Property + + fun classInfo(action: Action) { + classInfo.set(classInfo.get().also(action::execute)) + } + + fun classInfo(block: ClassInfoSpec.() -> Unit) { + classInfo(Action(block)) + } + + /** + * 用于标记生成函数需要使用的基础函数名的注解属性名。 + */ + val baseNameProperty: Property // = "baseName", + + /** + * 用于标记生成函数需要使用的基础函数名之后的后缀的注解属性名。 + */ + val suffixProperty: Property // = "suffix", + + /** + * 用于标记生成函数是否需要转化为 property 类型的注解属性名。 + */ + val asPropertyProperty: Property // = "asProperty", + + /** + * 当 [suffixProperty] 不存在时使用的默认后缀 + */ + val defaultSuffix: Property // = "" + + /** + * 当 [asPropertyProperty] 不存在时使用的默认值 + */ + val defaultAsProperty: Property // = false, + + fun from(markAnnotation: MarkAnnotation) { + classInfo { + from(markAnnotation.classInfo) + } + baseNameProperty.set(markAnnotation.baseNameProperty) + suffixProperty.set(markAnnotation.suffixProperty) + asPropertyProperty.set(markAnnotation.asPropertyProperty) + defaultSuffix.set(markAnnotation.defaultSuffix) + defaultAsProperty.set(markAnnotation.defaultAsProperty) + } +} + +/** + * @see ClassInfo + */ +interface ClassInfoSpec { + val packageName: Property + val className: Property + val local: Property + val nullable: Property + + fun from(classInfo: ClassInfo) { + packageName.set(classInfo.packageName) + className.set(classInfo.className) + local.set(classInfo.local) + nullable.set(classInfo.nullable) + } +} + +interface FunctionInfoSpec { + val packageName: Property + val functionName: Property + + fun from(functionInfo: FunctionInfo) { + packageName.set(functionInfo.packageName) + functionName.set(functionInfo.functionName) + } +} + +interface IncludeAnnotationSpec { + val classInfo: Property + + fun classInfo(action: Action) { + classInfo.set(classInfo.get().also(action::execute)) + } + + fun classInfo(block: ClassInfoSpec.() -> Unit) { + classInfo(Action(block)) + } + + val repeatable: Property + + val includeProperty: Property + + fun from(includeAnnotation: IncludeAnnotation) { + classInfo { + from(includeAnnotation.classInfo) + } + repeatable.set(includeAnnotation.repeatable) + includeProperty.set(includeAnnotation.includeProperty) + } +} diff --git a/settings.gradle.kts b/settings.gradle.kts index 656f762..5667b82 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,5 @@ rootProject.name = "kotlin-suspend-transform-compiler-plugin" -// compose for test enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") pluginManagement { repositories { @@ -8,19 +7,23 @@ pluginManagement { google() gradlePluginPortal() mavenCentral() + mavenLocal() } } + @Suppress("UnstableApiUsage") dependencyResolutionManagement { repositories { google() mavenCentral() maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + // mavenLocal() } } include(":compiler:suspend-transform-plugin") include(":compiler:suspend-transform-plugin-cli") +include(":compiler:suspend-transform-plugin-configuration") include(":compiler:suspend-transform-plugin-embeddable") include(":runtime:suspend-transform-annotation") @@ -31,7 +34,7 @@ include(":plugins:suspend-transform-plugin-gradle") // include(":local-helper") //Samples -// include(":tests:test-jvm") +include(":tests:test-jvm") // include(":tests:test-js") // include(":tests:test-kmp") // include(":tests:test-android") diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index 979f8b1..3af7a2c 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -1,28 +1,21 @@ -import love.forte.plugin.suspendtrans.ClassInfo -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration.Companion.jvmAsyncTransformer -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration.Companion.jvmBlockingTransformer -import love.forte.plugin.suspendtrans.TargetPlatform -import love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension +// buildscript { +// this@buildscript.repositories { +// mavenLocal() +// mavenCentral() +// } +// dependencies { +// classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:2.1.20-0.12.0") +// } +// } plugins { `java-library` kotlin("jvm") -// id("love.forte.plugin.suspend-transform") + id("love.forte.plugin.suspend-transform") version "2.1.20-0.12.0" // id("suspend-transform.jvm-maven-publish") // id(project(":suspend-transform-plugin-gradle")) } - -buildscript { - this@buildscript.repositories { - mavenLocal() - mavenCentral() - } - dependencies { - classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:2.1.0-0.11.1") - } -} - kotlin { compilerOptions { freeCompilerArgs.add("-Xjvm-default=all") @@ -34,7 +27,7 @@ repositories { mavenLocal() } -apply(plugin = "love.forte.plugin.suspend-transform") +// apply(plugin = "love.forte.plugin.suspend-transform") dependencies { api(kotlin("stdlib")) @@ -45,29 +38,66 @@ dependencies { api(libs.kotlinx.coroutines.core) } -extensions.getByType().apply { - includeRuntime = false - includeAnnotation = false -// useJvmDefault() - transformers[TargetPlatform.JVM] = mutableListOf( - // Add `kotlin.OptIn` to copyAnnotationExcludes - jvmBlockingTransformer.copy( - copyAnnotationExcludes = buildList { - addAll(jvmBlockingTransformer.copyAnnotationExcludes) - add(ClassInfo("kotlin", "OptIn")) - } - ), - - // Add `kotlin.OptIn` to copyAnnotationExcludes - jvmAsyncTransformer.copy( - copyAnnotationExcludes = buildList { - addAll(jvmAsyncTransformer.copyAnnotationExcludes) - add(ClassInfo("kotlin", "OptIn")) - } - ) - ) +suspendTransformPlugin { + transformers { + addJvm { + originFunctionIncludeAnnotations + // originFunctionIncludeAnnotations { + // create("demo1") { + // classInfo { from(SuspendTransformConfigurations.jvmSyntheticClassInfo) } + // } + // } + } + } } +// suspendTransformPlugin { +// includeRuntime = false +// transformers { +// // addJvm { +// // originFunctionIncludeAnnotations { +// // create("Hi~") { +// // classInfo { +// // } +// // } +// // } +// // } +// } +// // transformers { +// // addJvm { +// // originFunctionIncludeAnnotations.create("any name") { +// // +// // } +// // } +// // } +// // transformers.addJvm { +// // originFunctionIncludeAnnotations +// // } +// } + +// extensions.getByType().apply { +// includeRuntime = false +// includeAnnotation = false +// // useJvmDefault() +// transformers[TargetPlatform.JVM] = mutableListOf( +// // Add `kotlin.OptIn` to copyAnnotationExcludes +// jvmBlockingTransformer.copy( +// copyAnnotationExcludes = buildList { +// addAll(jvmBlockingTransformer.copyAnnotationExcludes) +// add(ClassInfo("kotlin", "OptIn")) +// } +// ), +// +// // Add `kotlin.OptIn` to copyAnnotationExcludes +// jvmAsyncTransformer.copy( +// copyAnnotationExcludes = buildList { +// addAll(jvmAsyncTransformer.copyAnnotationExcludes) +// add(ClassInfo("kotlin", "OptIn")) +// } +// ) +// ) +// } + tasks.withType { useJUnitPlatform() } From 3ce1577c309dcd54e8fb52faf22882812f1afa30 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 11 Apr 2025 18:42:21 +0800 Subject: [PATCH 03/21] improve: new Gradle plugin API --- .../gradle/SuspendTransformPluginExtension.kt | 87 ++++++++++--------- tests/test-jvm/build.gradle.kts | 28 +++--- 2 files changed, 62 insertions(+), 53 deletions(-) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index e9d7a15..8cbc11b 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -5,6 +5,7 @@ import org.gradle.api.Action import org.gradle.api.DomainObjectSet import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.* +import org.gradle.api.tasks.Nested import javax.inject.Inject abstract class TransformerContainer @@ -59,26 +60,18 @@ abstract class TransformerContainer fun addCommon(transformer: Transformer) = addCommon { it.from(transformer) } fun addCommon(transformer: Provider) = add(TargetPlatform.COMMON, transformer) fun addCommon(action: Action) = add(TargetPlatform.COMMON, action) - - fun addJvmDefaults() { - - } } - interface SuspendTransformPluginExtension { val enabled: Property + @get:Nested val transformers: TransformerContainer fun transformers(action: Action) { action.execute(transformers) } - fun transformers(block: TransformerContainer.() -> Unit) { - transformers.block() - } - fun useJvmDefault() { transformers.addJvm(SuspendTransformConfigurations.jvmBlockingTransformer) transformers.addJvm(SuspendTransformConfigurations.jvmAsyncTransformer) @@ -146,11 +139,8 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa abstract val markAnnotation: Property fun markAnnotation(action: Action) { - markAnnotation.set(markAnnotation.get().also(action::execute)) - } - - fun markAnnotation(block: MarkAnnotationSpec.() -> Unit) { - markAnnotation(Action(block)) + val old = markAnnotation.getOrElse(objects.newInstance()) + markAnnotation.set(old.also(action::execute)) } /** @@ -178,11 +168,11 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa abstract val transformFunctionInfo: Property fun transformFunctionInfo(action: Action) { - transformFunctionInfo.set(transformFunctionInfo.get().also(action::execute)) - } - - fun transformFunctionInfo(block: FunctionInfoSpec.() -> Unit) { - transformFunctionInfo(Action(block)) + transformFunctionInfo.set( + transformFunctionInfo.getOrElse( + objects.newInstance() + ).also(action::execute) + ) } /** @@ -191,11 +181,11 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa abstract val transformReturnType: Property fun transformReturnType(action: Action) { - transformReturnType.set(transformReturnType.get().also(action::execute)) - } - - fun transformReturnType(block: ClassInfoSpec.() -> Unit) { - transformReturnType(Action(block)) + transformReturnType.set( + transformReturnType.getOrElse( + objects.newInstance() + ).also(action::execute) + ) } /** @@ -211,7 +201,7 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa abstract val originFunctionIncludeAnnotations: DomainObjectSet private fun newIncludeAnnotationSpec(): IncludeAnnotationSpec = - objects.newInstance(IncludeAnnotationSpec::class.java) + objects.newInstance() fun addOriginFunctionIncludeAnnotation(action: Action) { originFunctionIncludeAnnotations.add( @@ -239,7 +229,7 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa abstract val copyAnnotationExcludes: DomainObjectSet fun addCopyAnnotationExclude(action: Action) { - copyAnnotationExcludes.add(objects.newInstance(ClassInfoSpec::class.java).also(action::execute)) + copyAnnotationExcludes.add(objects.newInstance().also(action::execute)) } /** @@ -247,7 +237,8 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa * * @since 0.9.0 */ - abstract val copyAnnotationsToSyntheticProperty: Property // = false + val copyAnnotationsToSyntheticProperty: Property = + objects.property(Boolean::class.java).convention(false) /** * Configures the current specification using a [Transformer]. @@ -256,9 +247,11 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa * e.g. [SuspendTransformConfigurations.jvmBlockingTransformer]. */ fun from(transformer: Transformer) { - markAnnotation { from(transformer.markAnnotation) } - transformFunctionInfo { from(transformer.transformFunctionInfo) } - transformer.transformReturnType?.also { transformReturnType { from(it) } } + markAnnotation { it.from(transformer.markAnnotation) } + transformFunctionInfo { it.from(transformer.transformFunctionInfo) } + transformer.transformReturnType?.also { transformReturnType -> + transformReturnType { it.from(transformReturnType) } + } transformReturnTypeGeneric.set(transformer.transformReturnTypeGeneric) for (originFunctionIncludeAnnotation in transformer.originFunctionIncludeAnnotations) { addOriginFunctionIncludeAnnotation { @@ -287,14 +280,14 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa /** * @see MarkAnnotation */ -interface MarkAnnotationSpec { +abstract class MarkAnnotationSpec @Inject constructor(private val objects: ObjectFactory) { /** * 注解类信息 */ - val classInfo: Property + abstract val classInfo: Property fun classInfo(action: Action) { - classInfo.set(classInfo.get().also(action::execute)) + classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } fun classInfo(block: ClassInfoSpec.() -> Unit) { @@ -304,27 +297,32 @@ interface MarkAnnotationSpec { /** * 用于标记生成函数需要使用的基础函数名的注解属性名。 */ - val baseNameProperty: Property // = "baseName", + val baseNameProperty: Property = + objects.property(String::class.java).convention("baseName") /** * 用于标记生成函数需要使用的基础函数名之后的后缀的注解属性名。 */ - val suffixProperty: Property // = "suffix", + val suffixProperty: Property = + objects.property(String::class.java).convention("suffix") /** * 用于标记生成函数是否需要转化为 property 类型的注解属性名。 */ - val asPropertyProperty: Property // = "asProperty", + val asPropertyProperty: Property = + objects.property(String::class.java).convention("asProperty") /** * 当 [suffixProperty] 不存在时使用的默认后缀 */ - val defaultSuffix: Property // = "" + val defaultSuffix: Property = + objects.property(String::class.java).convention("") /** * 当 [asPropertyProperty] 不存在时使用的默认值 */ - val defaultAsProperty: Property // = false, + val defaultAsProperty: Property = + objects.property(Boolean::class.java).convention(false) fun from(markAnnotation: MarkAnnotation) { classInfo { @@ -365,20 +363,20 @@ interface FunctionInfoSpec { } } -interface IncludeAnnotationSpec { - val classInfo: Property +abstract class IncludeAnnotationSpec @Inject constructor(private val objects: ObjectFactory) { + abstract val classInfo: Property fun classInfo(action: Action) { - classInfo.set(classInfo.get().also(action::execute)) + classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } fun classInfo(block: ClassInfoSpec.() -> Unit) { classInfo(Action(block)) } - val repeatable: Property + abstract val repeatable: Property - val includeProperty: Property + abstract val includeProperty: Property fun from(includeAnnotation: IncludeAnnotation) { classInfo { @@ -388,3 +386,6 @@ interface IncludeAnnotationSpec { includeProperty.set(includeAnnotation.includeProperty) } } + + +private inline fun ObjectFactory.newInstance(): T = newInstance(T::class.java) diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index 3af7a2c..443cf87 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -39,18 +39,26 @@ dependencies { } suspendTransformPlugin { - transformers { - addJvm { - originFunctionIncludeAnnotations - // originFunctionIncludeAnnotations { - // create("demo1") { - // classInfo { from(SuspendTransformConfigurations.jvmSyntheticClassInfo) } - // } - // } - } - } + + // transformers { + // useJvmDefault() + // + // } } +// suspendTransformPlugin { +// transformers { +// addJvm { +// originFunctionIncludeAnnotations +// // originFunctionIncludeAnnotations { +// // create("demo1") { +// // classInfo { from(SuspendTransformConfigurations.jvmSyntheticClassInfo) } +// // } +// // } +// } +// } +// } + // suspendTransformPlugin { // includeRuntime = false // transformers { From 75e1d9953dff92a0a4d7fbfea12a5bb115c73e08 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Mon, 14 Apr 2025 17:55:13 +0800 Subject: [PATCH 04/21] =?UTF-8?q?=E5=88=87=E6=8D=A2=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E6=96=B0=E7=9A=84Configuration=E5=B9=B6=E5=BA=9F=E5=BC=83?= =?UTF-8?q?=E6=97=A7=E7=9A=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- README_CN.md | 2 +- .../build.gradle.kts | 46 +---- .../cli/GradlePluginCliOptions.kt | 26 ++- .../cli/SuspendTransformCliOption.kt | 4 +- .../cli/SuspendTransformCliOptions.kt | 12 +- .../cli/ConfigurationSerializeTests.kt | 37 ++++ .../build.gradle.kts | 37 +--- .../SuspendTransformConfiguration.kt | 184 +++++++++++++++++- .../suspend-transform-plugin/build.gradle.kts | 7 +- .../forte/plugin/suspendtrans/CliOptions.kt | 4 + .../SuspendTransformCommandLineProcessor.kt | 32 +-- .../SuspendTransformComponentRegistrar.kt | 17 +- .../SuspendTransformConfiguration.kt | 37 +++- .../suspendtrans/SuspendTransformUserData.kt | 1 + .../SuspendTransformFirExtensionRegistrar.kt | 5 +- .../fir/SuspendTransformFirTransformer.kt | 43 ++-- .../SuspendTransformIrGenerationExtension.kt | 2 +- .../ir/SuspendTransformTransformer.kt | 6 +- ...tractSuspendTransformFunctionDescriptor.kt | 2 +- ...impleSuspendTransformFunctionDescriptor.kt | 2 +- ...spendTransformSyntheticResolveExtension.kt | 7 +- .../utils/AnnotationDescriptorUtils.kt | 2 +- .../suspendtrans/utils/CopyAnnotationUtils.kt | 2 +- .../suspendtrans/utils/TransformUtil.kt | 7 +- ...spendTransformerEnvironmentConfigurator.kt | 21 +- .../codegen/implOverridenGeneric.fir.ir.txt | 76 ++++---- .../codegen/implOverridenGeneric.fir.txt | 14 +- .../codegen/implOverridenGeneric.fir.ir.txt | 76 ++++---- .../codegen/implOverridenGeneric.fir.txt | 14 +- .../src/main/resources/META-INF/plugin.xml | 4 +- .../build.gradle.kts | 2 +- .../gradle/SuspendTransformGradleExtension.kt | 8 + .../gradle/SuspendTransformGradlePlugin.kt | 124 +++++++----- .../gradle/SuspendTransformPluginExtension.kt | 79 ++++++-- tests/test-jvm/build.gradle.kts | 64 +----- 36 files changed, 636 insertions(+), 372 deletions(-) create mode 100644 compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt diff --git a/README.md b/README.md index ae8230d..a8418d6 100644 --- a/README.md +++ b/README.md @@ -742,7 +742,7 @@ copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FITNESS FOR love.forte.plugin.suspendtrans.A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE diff --git a/README_CN.md b/README_CN.md index 0cff1cf..6f3a35b 100644 --- a/README_CN.md +++ b/README_CN.md @@ -745,7 +745,7 @@ copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FITNESS FOR love.forte.plugin.suspendtrans.A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE diff --git a/compiler/suspend-transform-plugin-cli/build.gradle.kts b/compiler/suspend-transform-plugin-cli/build.gradle.kts index 5165ffb..24dc011 100644 --- a/compiler/suspend-transform-plugin-cli/build.gradle.kts +++ b/compiler/suspend-transform-plugin-cli/build.gradle.kts @@ -1,5 +1,4 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") @@ -15,56 +14,21 @@ dependencies { api(libs.kotlinx.serialization.core) api(libs.kotlinx.serialization.protobuf) - // testImplementation("junit:junit:4.13.2") - testImplementation(kotlin("stdlib")) - testImplementation(kotlin("test-junit5")) - + testImplementation(libs.kotlinx.serialization.json) + testImplementation(kotlin("test")) testImplementation(kotlin("compiler")) - testImplementation(kotlin("reflect")) - -// testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.4.9") -// testImplementation("org.bitbucket.mstrobel:procyon-compilertools:0.6.0") - - testImplementation(libs.kotlinx.coroutines.core) + // testImplementation(libs.kotlinx.coroutines.core) } kotlin { compilerOptions { jvmTarget.set(JvmTarget.JVM_1_8) - // optIn.addAll( - // "kotlin.RequiresOptIn", - // "org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI" - // ) freeCompilerArgs.addAll( "-Xjvm-default=all", -// "-opt-in=kotlin.RequiresOptIn", -// "-opt-in=org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI", ) } } -tasks.withType(KotlinCompile::class.java).configureEach { - // see https://youtrack.jetbrains.com/issue/KTIJ-21563 - // see https://youtrack.jetbrains.com/issue/KT-57297 -// kotlinOptions { -// languageVersion = "1.9" -// apiVersion = "1.9" -// } +tasks.test { + useJUnitPlatform() } - -repositories { - maven { - url = uri("https://oss.sonatype.org/content/repositories/snapshots/") - mavenContent { - snapshotsOnly() - } - } -} - -// buildConfig { -// useKotlinOutput { -// internalVisibility = true -// } -// withoutPackage() -// buildConfigField("String", "KOTLIN_PLUGIN_ID", "\"${rootProject.extra["kotlin_plugin_id"]}\"") -// } diff --git a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/GradlePluginCliOptions.kt b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/GradlePluginCliOptions.kt index 8dea49e..4e93c2c 100644 --- a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/GradlePluginCliOptions.kt +++ b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/GradlePluginCliOptions.kt @@ -1,11 +1,25 @@ package love.forte.plugin.suspendtrans.cli +import kotlinx.serialization.ExperimentalSerializationApi +import kotlinx.serialization.decodeFromHexString +import kotlinx.serialization.encodeToHexString +import kotlinx.serialization.protobuf.ProtoBuf +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration.Companion.serializer + // Cli Options for gradle plugin -interface GradlePluginSuspendTransformCliOption : SuspendTransformCliOption { - /** - * Encode a value [T] to a String CLI option. - * _Should use base64(protobuf(value))_ - */ - fun encode(value: T): String +@OptIn(ExperimentalSerializationApi::class) +private val SERIALIZER = ProtoBuf { + encodeDefaults = true +} + +@OptIn(ExperimentalSerializationApi::class) +fun SuspendTransformConfiguration.encodeToHex(): String { + return SERIALIZER.encodeToHexString(serializer(), this) +} + +@OptIn(ExperimentalSerializationApi::class) +fun decodeSuspendTransformConfigurationFromHex(hex: String): SuspendTransformConfiguration { + return SERIALIZER.decodeFromHexString(serializer(), hex) } diff --git a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt index 2b58567..a4713cf 100644 --- a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt +++ b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt @@ -35,8 +35,8 @@ private data class AbstractCliOptionImpl( * Creates an instance of [SuspendTransformCliOption] to describe and define a CLI option. * * @param optionName The name of the option used to identify it in the CLI. - * @param valueDescription A description of the option's value, defaults to the option name. - * @param description A textual description of the option, defaults to an empty string. + * @param valueDescription love.forte.plugin.suspendtrans.A description of the option's value, defaults to the option name. + * @param description love.forte.plugin.suspendtrans.A textual description of the option, defaults to an empty string. * @param required Whether this option is mandatory, defaults to not required (`false`). * @param allowMultipleOccurrences Whether this option can appear multiple times in the CLI, * defaults to not allowed (`false`). diff --git a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOptions.kt b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOptions.kt index cce0308..a661d31 100644 --- a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOptions.kt +++ b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOptions.kt @@ -3,11 +3,11 @@ package love.forte.plugin.suspendtrans.cli object SuspendTransformCliOptions { const val CONFIGURATION = "configuration" - val ENABLED = SuspendTransformCliOption( - optionName = "enabled", - valueDescription = "Whether to enable the plugin", - description = "Whether to enable the plugin", + val CLI_CONFIGURATION = SuspendTransformCliOption( + optionName = "configuration", + valueDescription = "Configuration hex string", + description = "Configuration serialized protobuf hex string value", + required = true, + allowMultipleOccurrences = false, ) - - } diff --git a/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt b/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt new file mode 100644 index 0000000..18aa6e9 --- /dev/null +++ b/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt @@ -0,0 +1,37 @@ +package love.forte.plugin.suspendtrans.cli + +import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConstructorApi +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jsPromiseTransformer +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmAsyncTransformer +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingTransformer +import love.forte.plugin.suspendtrans.configuration.TargetPlatform +import kotlin.test.Test +import kotlin.test.assertEquals + +/** + * + * @author ForteScarlet + */ +class ConfigurationSerializeTests { + @OptIn(InternalSuspendTransformConstructorApi::class) + @Test + fun testDecode() { + assertEquals("0801", SuspendTransformConfiguration(true, emptyMap()).encodeToHex()) + + val config = SuspendTransformConfiguration( + enabled = true, + transformers = mapOf( + TargetPlatform.JVM to listOf(jvmBlockingTransformer, jvmAsyncTransformer), + TargetPlatform.JS to listOf(jsPromiseTransformer), + ) + ) + + val hex = config.encodeToHex() + assertEquals( + config, + decodeSuspendTransformConfigurationFromHex(hex) + ) + } + +} diff --git a/compiler/suspend-transform-plugin-configuration/build.gradle.kts b/compiler/suspend-transform-plugin-configuration/build.gradle.kts index 3ef63d8..3595f12 100644 --- a/compiler/suspend-transform-plugin-configuration/build.gradle.kts +++ b/compiler/suspend-transform-plugin-configuration/build.gradle.kts @@ -1,5 +1,4 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { kotlin("jvm") @@ -9,45 +8,24 @@ plugins { } dependencies { - compileOnly(kotlin("stdlib")) - // compileOnly(kotlin("compiler")) api(libs.kotlinx.serialization.core) // api(libs.kotlinx.serialization.protobuf) - // testImplementation("junit:junit:4.13.2") - testImplementation(kotlin("stdlib")) - testImplementation(kotlin("test-junit5")) - - // testImplementation(kotlin("compiler")) - testImplementation(kotlin("reflect")) - -// testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.4.9") -// testImplementation("org.bitbucket.mstrobel:procyon-compilertools:0.6.0") - // testImplementation(libs.kotlinx.coroutines.core) + testImplementation(kotlin("test")) } kotlin { compilerOptions { jvmTarget.set(JvmTarget.JVM_1_8) - // optIn.addAll( - // "kotlin.RequiresOptIn", - // "org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI" - // ) freeCompilerArgs.addAll( "-Xjvm-default=all", -// "-opt-in=kotlin.RequiresOptIn", -// "-opt-in=org.jetbrains.kotlin.ir.symbols.UnsafeDuringIrConstructionAPI", ) } + } -tasks.withType(KotlinCompile::class.java).configureEach { - // see https://youtrack.jetbrains.com/issue/KTIJ-21563 - // see https://youtrack.jetbrains.com/issue/KT-57297 -// kotlinOptions { -// languageVersion = "1.9" -// apiVersion = "1.9" -// } +tasks.test { + useJUnitPlatform() } repositories { @@ -59,10 +37,3 @@ repositories { } } -// buildConfig { -// useKotlinOutput { -// internalVisibility = true -// } -// withoutPackage() -// buildConfigField("String", "KOTLIN_PLUGIN_ID", "\"${rootProject.extra["kotlin_plugin_id"]}\"") -// } diff --git a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt index 7f31eb4..e171ec0 100644 --- a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt +++ b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt @@ -2,6 +2,10 @@ package love.forte.plugin.suspendtrans.configuration import kotlinx.serialization.Serializable +// NOTE: +// 可序列号的配置信息均使用 `Protobuf` 进行序列化 +// 虽然序列化行为是内部的,但是还是应该尽可能避免出现字段的顺序错乱或删改。 + @RequiresOptIn( "This is an internal suspend transform config api. " + "It may be changed in the future without notice.", RequiresOptIn.Level.ERROR @@ -12,7 +16,27 @@ annotation class InternalSuspendTransformConstructorApi class FunctionInfo @InternalSuspendTransformConstructorApi constructor( val packageName: String, val functionName: String -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is FunctionInfo) return false + + if (packageName != other.packageName) return false + if (functionName != other.functionName) return false + + return true + } + + override fun hashCode(): Int { + var result = packageName.hashCode() + result = 31 * result + functionName.hashCode() + return result + } + + override fun toString(): String { + return "FunctionInfo(functionName='$functionName', packageName='$packageName')" + } +} @Serializable class ClassInfo @InternalSuspendTransformConstructorApi constructor( @@ -20,7 +44,31 @@ class ClassInfo @InternalSuspendTransformConstructorApi constructor( val className: String, val local: Boolean = false, val nullable: Boolean = false, -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is ClassInfo) return false + + if (local != other.local) return false + if (nullable != other.nullable) return false + if (packageName != other.packageName) return false + if (className != other.className) return false + + return true + } + + override fun hashCode(): Int { + var result = local.hashCode() + result = 31 * result + nullable.hashCode() + result = 31 * result + packageName.hashCode() + result = 31 * result + className.hashCode() + return result + } + + override fun toString(): String { + return "ClassInfo(className='$className', packageName='$packageName', local=$local, nullable=$nullable)" + } +} @Serializable enum class TargetPlatform { @@ -56,7 +104,35 @@ class MarkAnnotation @InternalSuspendTransformConstructorApi constructor( * 当 [asPropertyProperty] 不存在时使用的默认值 */ val defaultAsProperty: Boolean = false, -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is MarkAnnotation) return false + + if (defaultAsProperty != other.defaultAsProperty) return false + if (classInfo != other.classInfo) return false + if (baseNameProperty != other.baseNameProperty) return false + if (suffixProperty != other.suffixProperty) return false + if (asPropertyProperty != other.asPropertyProperty) return false + if (defaultSuffix != other.defaultSuffix) return false + + return true + } + + override fun hashCode(): Int { + var result = defaultAsProperty.hashCode() + result = 31 * result + classInfo.hashCode() + result = 31 * result + baseNameProperty.hashCode() + result = 31 * result + suffixProperty.hashCode() + result = 31 * result + asPropertyProperty.hashCode() + result = 31 * result + defaultSuffix.hashCode() + return result + } + + override fun toString(): String { + return "MarkAnnotation(asPropertyProperty='$asPropertyProperty', classInfo=$classInfo, baseNameProperty='$baseNameProperty', suffixProperty='$suffixProperty', defaultSuffix='$defaultSuffix', defaultAsProperty=$defaultAsProperty)" + } +} @Serializable class IncludeAnnotation @InternalSuspendTransformConstructorApi constructor( @@ -68,7 +144,29 @@ class IncludeAnnotation @InternalSuspendTransformConstructorApi constructor( * @since 0.9.0 */ val includeProperty: Boolean = false -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is IncludeAnnotation) return false + + if (repeatable != other.repeatable) return false + if (includeProperty != other.includeProperty) return false + if (classInfo != other.classInfo) return false + + return true + } + + override fun hashCode(): Int { + var result = repeatable.hashCode() + result = 31 * result + includeProperty.hashCode() + result = 31 * result + classInfo.hashCode() + return result + } + + override fun toString(): String { + return "IncludeAnnotation(classInfo=$classInfo, repeatable=$repeatable, includeProperty=$includeProperty)" + } +} @Serializable class Transformer @InternalSuspendTransformConstructorApi constructor( @@ -142,13 +240,87 @@ class Transformer @InternalSuspendTransformConstructorApi constructor( * @since 0.9.0 */ val copyAnnotationsToSyntheticProperty: Boolean = false -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is Transformer) return false + + if (transformReturnTypeGeneric != other.transformReturnTypeGeneric) return false + if (copyAnnotationsToSyntheticFunction != other.copyAnnotationsToSyntheticFunction) return false + if (copyAnnotationsToSyntheticProperty != other.copyAnnotationsToSyntheticProperty) return false + if (markAnnotation != other.markAnnotation) return false + if (transformFunctionInfo != other.transformFunctionInfo) return false + if (transformReturnType != other.transformReturnType) return false + if (originFunctionIncludeAnnotations != other.originFunctionIncludeAnnotations) return false + if (syntheticFunctionIncludeAnnotations != other.syntheticFunctionIncludeAnnotations) return false + if (copyAnnotationExcludes != other.copyAnnotationExcludes) return false + + return true + } + + override fun hashCode(): Int { + var result = transformReturnTypeGeneric.hashCode() + result = 31 * result + copyAnnotationsToSyntheticFunction.hashCode() + result = 31 * result + copyAnnotationsToSyntheticProperty.hashCode() + result = 31 * result + markAnnotation.hashCode() + result = 31 * result + transformFunctionInfo.hashCode() + result = 31 * result + (transformReturnType?.hashCode() ?: 0) + result = 31 * result + originFunctionIncludeAnnotations.hashCode() + result = 31 * result + syntheticFunctionIncludeAnnotations.hashCode() + result = 31 * result + copyAnnotationExcludes.hashCode() + return result + } + + override fun toString(): String { + return "Transformer(copyAnnotationExcludes=$copyAnnotationExcludes, markAnnotation=$markAnnotation, transformFunctionInfo=$transformFunctionInfo, transformReturnType=$transformReturnType, transformReturnTypeGeneric=$transformReturnTypeGeneric, originFunctionIncludeAnnotations=$originFunctionIncludeAnnotations, syntheticFunctionIncludeAnnotations=$syntheticFunctionIncludeAnnotations, copyAnnotationsToSyntheticFunction=$copyAnnotationsToSyntheticFunction, copyAnnotationsToSyntheticProperty=$copyAnnotationsToSyntheticProperty)" + } +} +/** + * 可序列化的配置信息。 + */ @Serializable class SuspendTransformConfiguration @InternalSuspendTransformConstructorApi constructor( val enabled: Boolean, val transformers: Map> -) +) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is SuspendTransformConfiguration) return false + + if (enabled != other.enabled) return false + if (transformers != other.transformers) return false + + return true + } + + override fun hashCode(): Int { + var result = enabled.hashCode() + result = 31 * result + transformers.hashCode() + return result + } + + override fun toString(): String { + return "SuspendTransformConfiguration(enabled=$enabled, transformers=$transformers)" + } +} + +/** + * Merge both + */ +@InternalSuspendTransformConstructorApi +operator fun SuspendTransformConfiguration.plus(other: SuspendTransformConfiguration): SuspendTransformConfiguration { + return SuspendTransformConfiguration( + enabled = enabled && other.enabled, + transformers = transformers.toMutableMap().apply { + other.transformers.forEach { (platform, transformers) -> + compute(platform) { _, old -> + if (old == null) transformers.toList() else old + transformers + } + } + } + ) +} /** * Some constants for configuration. diff --git a/compiler/suspend-transform-plugin/build.gradle.kts b/compiler/suspend-transform-plugin/build.gradle.kts index d67ccd3..50bb6f7 100644 --- a/compiler/suspend-transform-plugin/build.gradle.kts +++ b/compiler/suspend-transform-plugin/build.gradle.kts @@ -9,17 +9,14 @@ plugins { id("suspend-transform.jvm-maven-publish") } -//testWithEmbedded0() - - dependencies { compileOnly(kotlin("stdlib")) implementation(kotlin("compiler")) compileOnly(libs.kotlinx.coroutines.core) + // TODO remove JSON api(libs.kotlinx.serialization.json) - // TODO 改成二进制的,比如 protobuf + api(project(":compiler:suspend-transform-plugin-cli")) - testImplementation("junit:junit:4.13.2") testImplementation(kotlin("stdlib")) testImplementation(kotlin("test-junit5")) diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt index 03ab61e..fdf6d39 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt @@ -11,6 +11,7 @@ private val defaultJson = Json { encodeDefaults = true } +@Deprecated("Use the cli module's type") object CliOptions { const val CONFIGURATION = "configuration" @@ -71,6 +72,7 @@ object CliOptions { } +@Deprecated("Use the cli module's type") private class ResolveBuilder { var outc: SuspendTransformConfiguration.() -> String = { error("no outc") } var inc: SuspendTransformConfiguration.(String) -> Unit = { error("no inc") } @@ -132,12 +134,14 @@ private fun String.option( ) } +@Deprecated("Use the cli module's type") interface ICliOption { val oName: String fun resolveToValue(configuration: SuspendTransformConfiguration): String fun resolveFromValue(configuration: SuspendTransformConfiguration, value: String) } +@Deprecated("Use the cli module's type") class SimpleCliOption( override val optionName: String, override val valueDescription: String, diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformCommandLineProcessor.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformCommandLineProcessor.kt index e002793..f5625bd 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformCommandLineProcessor.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformCommandLineProcessor.kt @@ -1,38 +1,46 @@ package love.forte.plugin.suspendtrans import BuildConfig +import love.forte.plugin.suspendtrans.cli.SuspendTransformCliOptions +import love.forte.plugin.suspendtrans.cli.decodeSuspendTransformConfigurationFromHex +import love.forte.plugin.suspendtrans.cli.toAbstractCliOption +import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConstructorApi +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.plus import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption import org.jetbrains.kotlin.compiler.plugin.CommandLineProcessor import org.jetbrains.kotlin.compiler.plugin.ExperimentalCompilerApi import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfigurationKey - @OptIn(ExperimentalCompilerApi::class) class SuspendTransformCommandLineProcessor : CommandLineProcessor { companion object { - val CONFIGURATION: CompilerConfigurationKey = - CompilerConfigurationKey.create(CliOptions.CONFIGURATION) + val CONFIGURATION_KEY: CompilerConfigurationKey = + CompilerConfigurationKey.create(SuspendTransformCliOptions.CONFIGURATION) } override val pluginId: String = BuildConfig.KOTLIN_PLUGIN_ID - override val pluginOptions: Collection = CliOptions.allOptions.map { it as SimpleCliOption } + override val pluginOptions: Collection = + listOf(SuspendTransformCliOptions.CLI_CONFIGURATION.toAbstractCliOption()) + @OptIn(InternalSuspendTransformConstructorApi::class) override fun processOption( option: AbstractCliOption, value: String, configuration: CompilerConfiguration ) { - fun getConf(): SuspendTransformConfiguration { - return configuration[CONFIGURATION] ?: SuspendTransformConfiguration().also { - configuration.put( - CONFIGURATION, - it - ) + // The 'configuration' option + if (SuspendTransformCliOptions.CLI_CONFIGURATION.optionName == option.optionName) { + // Decode from protobuf hex value + val decodedConfiguration = decodeSuspendTransformConfigurationFromHex(value) + val currentConfig = configuration[CONFIGURATION_KEY] + if (currentConfig == null) { + configuration.put(CONFIGURATION_KEY, decodedConfiguration) + } else { + configuration.put(CONFIGURATION_KEY, currentConfig + decodedConfiguration) } } - - CliOptions.allOptionsMap[option.optionName]?.resolveFromValue(getConf(), value) } } diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt index 7a057cd..862fd86 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt @@ -1,5 +1,7 @@ package love.forte.plugin.suspendtrans +import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConstructorApi +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration import love.forte.plugin.suspendtrans.fir.SuspendTransformFirExtensionRegistrar import love.forte.plugin.suspendtrans.ir.SuspendTransformIrGenerationExtension import love.forte.plugin.suspendtrans.symbol.SuspendTransformSyntheticResolveExtension @@ -49,10 +51,21 @@ class SuspendTransformComponentRegistrar : CompilerPluginRegistrar() { } } +// @Deprecated("Use Cli module's type") +// private fun CompilerConfiguration.resolveToSuspendTransformConfiguration(): SuspendTransformConfiguration { +// // val compilerConfiguration = this +// return get(SuspendTransformCommandLineProcessor.CONFIGURATION_KEY, SuspendTransformConfiguration()) +// // return SuspendTransformConfiguration().apply { +// // enabled = compilerConfiguration.get(SuspendTransformCommandLineProcessor.ENABLED, true) +// // } +// } +@OptIn(InternalSuspendTransformConstructorApi::class) private fun CompilerConfiguration.resolveToSuspendTransformConfiguration(): SuspendTransformConfiguration { -// val compilerConfiguration = this - return get(SuspendTransformCommandLineProcessor.CONFIGURATION, SuspendTransformConfiguration()) + return get( + SuspendTransformCommandLineProcessor.CONFIGURATION_KEY, + SuspendTransformConfiguration(true, mutableMapOf()) + ) // return SuspendTransformConfiguration().apply { // enabled = compilerConfiguration.get(SuspendTransformCommandLineProcessor.ENABLED, true) // } diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt index 6b21ef2..a97a8fb 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt @@ -3,9 +3,12 @@ package love.forte.plugin.suspendtrans import kotlinx.serialization.Serializable // TODO 序列化改成二进制的,比如 protobuf, -// 然后使用base64或hash进行传递,避免谜之转义 @Serializable +@Deprecated( + "Use new `love.forte.plugin.suspendtrans.configuration.FunctionInfo` instead.", + ReplaceWith("FunctionInfo", "love.forte.plugin.suspendtrans.configuration.FunctionInfo") +) data class FunctionInfo( var packageName: String, @Deprecated("Top-Level function supported only") @@ -14,6 +17,10 @@ data class FunctionInfo( ) @Serializable +@Deprecated( + "Use new `love.forte.plugin.suspendtrans.configuration.ClassInfo` instead.", + ReplaceWith("ClassInfo", "love.forte.plugin.suspendtrans.configuration.ClassInfo") +) data class ClassInfo @JvmOverloads constructor( var packageName: String, var className: String, @@ -22,6 +29,10 @@ data class ClassInfo @JvmOverloads constructor( ) @Serializable +@Deprecated( + "Use new `love.forte.plugin.suspendtrans.configuration.TargetPlatform` instead.", + ReplaceWith("TargetPlatform", "love.forte.plugin.suspendtrans.configuration.TargetPlatform") +) enum class TargetPlatform { COMMON, JVM, JS, WASM, NATIVE } @@ -32,6 +43,13 @@ enum class TargetPlatform { * */ @Serializable +@Deprecated( + "Use new `love.forte.plugin.suspendtrans.configuration.Transformer` instead.", + replaceWith = ReplaceWith( + "Transformer", + "love.forte.plugin.suspendtrans.configuration.Transformer" + ) +) data class Transformer( /** 函数上的某种标记。 */ val markAnnotation: MarkAnnotation, @@ -71,7 +89,7 @@ data class Transformer( /** * 转化后的返回值类型中,是否存在需要与原本返回值类型一致的泛型。 */ - val transformReturnTypeGeneric: Boolean, + val transformReturnTypeGeneric: Boolean, /** * 函数生成后,需要在原函数上追加的注解信息。 @@ -108,6 +126,10 @@ data class Transformer( * 用于标记的注解信息. */ @Serializable +@Deprecated( + "Use new `love.forte.plugin.suspendtrans.configuration.MarkAnnotation` instead.", + ReplaceWith("MarkAnnotation", "love.forte.plugin.suspendtrans.configuration.MarkAnnotation") +) data class MarkAnnotation @JvmOverloads constructor( /** * 注解类信息 @@ -141,6 +163,10 @@ data class MarkAnnotation @JvmOverloads constructor( @Serializable +@Deprecated( + "Use new `love.forte.plugin.suspendtrans.configuration.IncludeAnnotation` instead.", + ReplaceWith("IncludeAnnotation", "love.forte.plugin.suspendtrans.configuration.IncludeAnnotation") +) data class IncludeAnnotation( val classInfo: ClassInfo, val repeatable: Boolean = false ) { @@ -158,6 +184,13 @@ data class IncludeAnnotation( */ @Suppress("unused") @Serializable +@Deprecated( + message = "Use new `love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration` instead.", + replaceWith = ReplaceWith( + "SuspendTransformConfiguration", + "love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration" + ) +) open class SuspendTransformConfiguration { open var enabled: Boolean = true diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformUserData.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformUserData.kt index 9207100..3613442 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformUserData.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformUserData.kt @@ -1,5 +1,6 @@ package love.forte.plugin.suspendtrans +import love.forte.plugin.suspendtrans.configuration.Transformer import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.fir.FirSession diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirExtensionRegistrar.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirExtensionRegistrar.kt index 19ef9e1..24c0efd 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirExtensionRegistrar.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirExtensionRegistrar.kt @@ -1,6 +1,6 @@ package love.forte.plugin.suspendtrans.fir -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration import org.jetbrains.kotlin.fir.extensions.FirDeclarationGenerationExtension import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar @@ -8,7 +8,8 @@ import org.jetbrains.kotlin.fir.extensions.FirExtensionRegistrar * * @author ForteScarlet */ -class SuspendTransformFirExtensionRegistrar(private val suspendTransformConfiguration: SuspendTransformConfiguration) : FirExtensionRegistrar() { +class SuspendTransformFirExtensionRegistrar(private val suspendTransformConfiguration: SuspendTransformConfiguration) : + FirExtensionRegistrar() { override fun ExtensionRegistrarContext.configurePlugin() { FirDeclarationGenerationExtension.Factory { session -> SuspendTransformFirTransformer( diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt index b44cbf7..d5d58e2 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt @@ -1,6 +1,9 @@ package love.forte.plugin.suspendtrans.fir -import love.forte.plugin.suspendtrans.* +import love.forte.plugin.suspendtrans.configuration.MarkAnnotation +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.Transformer +import love.forte.plugin.suspendtrans.fqn import love.forte.plugin.suspendtrans.utils.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.* @@ -74,7 +77,8 @@ class SuspendTransformFirTransformer( private val suspendTransformConfiguration: SuspendTransformConfiguration ) : FirDeclarationGenerationExtension(session) { - private val transformerFunctionSymbolMap = ConcurrentHashMap() + private val transformerFunctionSymbolMap = + ConcurrentHashMap() private lateinit var coroutineScopeSymbol: FirClassLikeSymbol<*> @@ -114,15 +118,6 @@ class SuspendTransformFirTransformer( val packageName = transformFunctionInfo.packageName val functionName = transformFunctionInfo.functionName - @Suppress("DEPRECATION") - val className = transformFunctionInfo.className - if (className != null) { - error( - "Not support `className` (`$className`) in transformer function info: " + - "top level function supported only." - ) - } - // TODO 校验funcs? val functionNameIdentifier = Name.identifier(functionName) @@ -509,14 +504,16 @@ class SuspendTransformFirTransformer( } ) operation = FirOperation.SAFE_AS - conversionTypeRef = parameterTypeNotNullable.toFirResolvedTypeRef() + conversionTypeRef = + parameterTypeNotNullable.toFirResolvedTypeRef() }, parameterFir ) } else { // coroutine not nullable // put if this is `CoroutineScope` or it is optional, otherwise throw error - var ownerIsCoroutineScopeOrParameterIsOptional = parameterSymbol.hasDefaultValue + var ownerIsCoroutineScopeOrParameterIsOptional = + parameterSymbol.hasDefaultValue for (superType in owner.getSuperTypes(session, recursive = false)) { if (superType.isCoroutineScope()) { put(thisReceiverExpression(), parameterFir) @@ -611,11 +608,11 @@ class SuspendTransformFirTransformer( // Copy the typeParameters. // Otherwise, in functions like the following, an error will occur - // suspend fun data(value: A): T = ... - // Functions for which function-scoped generalizations (``) exist. - // In the generated IR, data and dataBlocking will share an `A`, generating the error. + // suspend fun data(value: love.forte.plugin.suspendtrans.A): T = ... + // Functions for which function-scoped generalizations (``) exist. + // In the generated IR, data and dataBlocking will share an `love.forte.plugin.suspendtrans.A`, generating the error. // The error: Duplicate IR node - // [IR VALIDATION] JvmIrValidationBeforeLoweringPhase: Duplicate IR node: TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false of FUN GENERATED[...] + // [IR VALIDATION] JvmIrValidationBeforeLoweringPhase: Duplicate IR node: TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false of FUN GENERATED[...] copyParameters() // resolve returnType (with wrapped) after copyParameters @@ -904,15 +901,15 @@ class SuspendTransformFirTransformer( ): Map>? { if (declaredScope == null) return null - fun check(targetPlatform: TargetPlatform): Boolean { + fun check(targetPlatform: love.forte.plugin.suspendtrans.configuration.TargetPlatform): Boolean { val platform = classSymbol.moduleData.platform return when { - platform.isJvm() && targetPlatform == TargetPlatform.JVM -> true - platform.isJs() && targetPlatform == TargetPlatform.JS -> true - platform.isWasm() && targetPlatform == TargetPlatform.WASM -> true - platform.isNative() && targetPlatform == TargetPlatform.NATIVE -> true - platform.isCommon() && targetPlatform == TargetPlatform.COMMON -> true + platform.isJvm() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.JVM -> true + platform.isJs() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.JS -> true + platform.isWasm() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.WASM -> true + platform.isNative() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.NATIVE -> true + platform.isCommon() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.COMMON -> true else -> false } } diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformIrGenerationExtension.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformIrGenerationExtension.kt index afdd84b..7aa4d4e 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformIrGenerationExtension.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/ir/SuspendTransformIrGenerationExtension.kt @@ -1,7 +1,7 @@ package love.forte.plugin.suspendtrans.ir import love.forte.plugin.suspendtrans.PluginAvailability -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrPluginContext import org.jetbrains.kotlin.ir.declarations.IrModuleFragment 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 19f8a18..18dcd4a 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,10 +1,14 @@ package love.forte.plugin.suspendtrans.ir -import love.forte.plugin.suspendtrans.* +import love.forte.plugin.suspendtrans.SuspendTransformUserDataKey +import love.forte.plugin.suspendtrans.checkSame +import love.forte.plugin.suspendtrans.configuration.IncludeAnnotation +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration import love.forte.plugin.suspendtrans.fir.SuspendTransformBridgeFunctionKey import love.forte.plugin.suspendtrans.fir.SuspendTransformGeneratedDeclarationKey import love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key import love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey +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.IrPluginContext diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/AbstractSuspendTransformFunctionDescriptor.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/AbstractSuspendTransformFunctionDescriptor.kt index 44cff6d..60b1e79 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/AbstractSuspendTransformFunctionDescriptor.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/AbstractSuspendTransformFunctionDescriptor.kt @@ -2,7 +2,7 @@ package love.forte.plugin.suspendtrans.symbol import love.forte.plugin.suspendtrans.SuspendTransformUserData import love.forte.plugin.suspendtrans.SuspendTransformUserDataKey -import love.forte.plugin.suspendtrans.Transformer +import love.forte.plugin.suspendtrans.configuration.Transformer import love.forte.plugin.suspendtrans.utils.TransformAnnotationData import love.forte.plugin.suspendtrans.utils.copy import love.forte.plugin.suspendtrans.utils.findClassDescriptor diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SimpleSuspendTransformFunctionDescriptor.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SimpleSuspendTransformFunctionDescriptor.kt index d9df2d9..3c6cc13 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SimpleSuspendTransformFunctionDescriptor.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SimpleSuspendTransformFunctionDescriptor.kt @@ -1,7 +1,7 @@ package love.forte.plugin.suspendtrans.symbol import love.forte.plugin.suspendtrans.SuspendTransformUserData -import love.forte.plugin.suspendtrans.Transformer +import love.forte.plugin.suspendtrans.configuration.Transformer import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.SimpleFunctionDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SuspendTransformSyntheticResolveExtension.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SuspendTransformSyntheticResolveExtension.kt index a08294d..7121a46 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SuspendTransformSyntheticResolveExtension.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/symbol/SuspendTransformSyntheticResolveExtension.kt @@ -1,6 +1,11 @@ package love.forte.plugin.suspendtrans.symbol -import love.forte.plugin.suspendtrans.* +import love.forte.plugin.suspendtrans.PluginAvailability +import love.forte.plugin.suspendtrans.SuspendTransformUserData +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.TargetPlatform +import love.forte.plugin.suspendtrans.configuration.Transformer +import love.forte.plugin.suspendtrans.generatedAnnotationClassId import love.forte.plugin.suspendtrans.utils.* import org.jetbrains.kotlin.backend.common.descriptors.allParameters import org.jetbrains.kotlin.descriptors.* diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/AnnotationDescriptorUtils.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/AnnotationDescriptorUtils.kt index 3a1228d..ae95288 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/AnnotationDescriptorUtils.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/AnnotationDescriptorUtils.kt @@ -1,6 +1,6 @@ package love.forte.plugin.suspendtrans.utils -import love.forte.plugin.suspendtrans.Transformer +import love.forte.plugin.suspendtrans.configuration.Transformer import love.forte.plugin.suspendtrans.toJsPromiseAnnotationName import love.forte.plugin.suspendtrans.toJvmAsyncAnnotationName import love.forte.plugin.suspendtrans.toJvmBlockingAnnotationName diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/CopyAnnotationUtils.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/CopyAnnotationUtils.kt index aef4652..5611cd3 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/CopyAnnotationUtils.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/CopyAnnotationUtils.kt @@ -1,6 +1,6 @@ package love.forte.plugin.suspendtrans.utils -import love.forte.plugin.suspendtrans.IncludeAnnotation +import love.forte.plugin.suspendtrans.configuration.IncludeAnnotation import org.jetbrains.kotlin.name.ClassId data class CopyAnnotationsData( diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/TransformUtil.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/TransformUtil.kt index 8ee48b4..dd1b3d7 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/TransformUtil.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/utils/TransformUtil.kt @@ -1,7 +1,7 @@ package love.forte.plugin.suspendtrans.utils -import love.forte.plugin.suspendtrans.ClassInfo -import love.forte.plugin.suspendtrans.FunctionInfo +import love.forte.plugin.suspendtrans.configuration.ClassInfo +import love.forte.plugin.suspendtrans.configuration.FunctionInfo import love.forte.plugin.suspendtrans.fqn import org.jetbrains.kotlin.name.CallableId import org.jetbrains.kotlin.name.ClassId @@ -11,6 +11,5 @@ import org.jetbrains.kotlin.name.Name fun ClassInfo.toClassId(): ClassId = ClassId(packageName.fqn, className.fqn, local) -@Suppress("DEPRECATION") fun FunctionInfo.toCallableId(): CallableId = - CallableId(packageName.fqn, className?.fqn, Name.identifier(functionName)) + CallableId(packageName.fqn, null, Name.identifier(functionName)) diff --git a/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt b/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt index 8b63a10..2273dfe 100644 --- a/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt +++ b/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt @@ -1,7 +1,11 @@ package love.forte.plugin.suspendtrans.services import love.forte.plugin.suspendtrans.SuspendTransformComponentRegistrar -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConstructorApi +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jsPromiseTransformer +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmAsyncTransformer +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingTransformer +import love.forte.plugin.suspendtrans.configuration.TargetPlatform import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoot import org.jetbrains.kotlin.cli.jvm.config.configureJdkClasspathRoots import org.jetbrains.kotlin.compiler.plugin.CompilerPluginRegistrar @@ -19,15 +23,20 @@ import java.io.File */ class SuspendTransformerEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) { - @OptIn(ExperimentalCompilerApi::class) + @OptIn(ExperimentalCompilerApi::class, InternalSuspendTransformConstructorApi::class) override fun CompilerPluginRegistrar.ExtensionStorage.registerCompilerExtensions( module: TestModule, configuration: CompilerConfiguration ) { + val testConfiguration = love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration( + enabled = true, + transformers = mapOf( + TargetPlatform.JS to listOf(jsPromiseTransformer), + TargetPlatform.JVM to listOf(jvmBlockingTransformer, jvmAsyncTransformer) + ) + ) // register plugin - SuspendTransformComponentRegistrar.register(this, SuspendTransformConfiguration().apply { - useDefault() - }) + SuspendTransformComponentRegistrar.register(this, testConfiguration) } override fun configureCompilerConfiguration(configuration: CompilerConfiguration, module: TestModule) { @@ -71,7 +80,7 @@ class SuspendTransformerEnvironmentConfigurator(testServices: TestServices) : En private fun getRuntimeJarFile(clazz: Class<*>): File { // try { - return PathUtil.getResourcePathForClass(clazz) + return PathUtil.getResourcePathForClass(clazz) // } catch (e: ClassNotFoundException) { // System.err.println("Runtime jar '$clazz' not found!") //// assert(false) { "Runtime jar '$className' not found!" } diff --git a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.ir.txt b/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.ir.txt index 8df2699..bd320c5 100644 --- a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.ir.txt +++ b/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.ir.txt @@ -19,24 +19,24 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in .FooInterface1 $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:A of .FooInterface1Impl.data2Blocking) returnType:T of .FooInterface1Impl + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking) returnType:T of .FooInterface1Impl annotations: Api4J - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface1Impl.data2Blocking + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface1Impl.data2Blocking): T of .FooInterface1Impl declared in .FooInterface1Impl' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface1Impl origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface1Impl> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface1Impl [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface1Impl declared in .FooInterface1Impl.data2Blocking' - CALL 'public open fun data2 (value: A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null - : + CALL 'public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null + : $this: GET_VAR ': .FooInterface1Impl.FooInterface1Impl> declared in .FooInterface1Impl.data2Blocking' type=.FooInterface1Impl.FooInterface1Impl> origin=null - value: GET_VAR 'value: A of .FooInterface1Impl.data2Blocking declared in .FooInterface1Impl.data2Blocking' type=A of .FooInterface1Impl.data2Blocking origin=null + value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking declared in .FooInterface1Impl.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface1Impl annotations: Api4J @@ -77,17 +77,17 @@ FILE fqName: fileName:/Main.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:A of .FooInterface1Impl.data2) returnType:T of .FooInterface1Impl [suspend] + FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2) returnType:T of .FooInterface1Impl [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) JvmSynthetic overridden: - public abstract fun data2 (value: A of .FooInterface1.data2): T of .FooInterface1 declared in .FooInterface1 - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1.data2): T of .FooInterface1 declared in .FooInterface1 + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface1Impl.data2 + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2 BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' + RETURN type=kotlin.Nothing from='public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface1Impl [suspend] annotations: @@ -218,26 +218,26 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in .FooInterface3 $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:A of .FooInterface3Impl.data2Blocking) returnType:T of .FooInterface3Impl + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking) returnType:T of .FooInterface3Impl annotations: Api4J overridden: - public open fun data2Blocking (value: A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3 - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3 + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface3Impl.data2Blocking + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface3Impl.data2Blocking): T of .FooInterface3Impl declared in .FooInterface3Impl' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface3Impl origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3Impl> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3Impl [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3Impl declared in .FooInterface3Impl.data2Blocking' - CALL 'public open fun data2 (value: A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null - : + CALL 'public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null + : $this: GET_VAR ': .FooInterface3Impl.FooInterface3Impl> declared in .FooInterface3Impl.data2Blocking' type=.FooInterface3Impl.FooInterface3Impl> origin=null - value: GET_VAR 'value: A of .FooInterface3Impl.data2Blocking declared in .FooInterface3Impl.data2Blocking' type=A of .FooInterface3Impl.data2Blocking origin=null + value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking declared in .FooInterface3Impl.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface3Impl annotations: Api4J @@ -282,17 +282,17 @@ FILE fqName: fileName:/Main.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:A of .FooInterface3Impl.data2) returnType:T of .FooInterface3Impl [suspend] + FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2) returnType:T of .FooInterface3Impl [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) JvmSynthetic overridden: - public abstract fun data2 (value: A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3 - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3 + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface3Impl.data2 + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2 BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' + RETURN type=kotlin.Nothing from='public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface3Impl [suspend] annotations: @@ -457,10 +457,10 @@ FILE fqName: fileName:/Main.kt $this: VALUE_PARAMETER name: type:kotlin.Any FUN name:data visibility:public modality:ABSTRACT <> ($this:.FooInterface1.FooInterface1>) returnType:T of .FooInterface1 [suspend] $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface1.FooInterface1>, value:A of .FooInterface1.data2) returnType:T of .FooInterface1 [suspend] - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface1.FooInterface1>, value:love.forte.plugin.suspendtrans.A of .FooInterface1.data2) returnType:T of .FooInterface1 [suspend] + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface1.data2 + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1.data2 FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface1.FooInterface1>, $receiver:kotlin.Int) returnType:T of .FooInterface1 [suspend] $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> $receiver: VALUE_PARAMETER name: type:kotlin.Int @@ -504,24 +504,24 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3.FooInterface3>, value:A of .FooInterface3.data2Blocking) returnType:T of .FooInterface3 + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3.FooInterface3>, value:love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking) returnType:T of .FooInterface3 annotations: Api4J - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface3.data2Blocking + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface3 origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3 [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3 declared in .FooInterface3.data2Blocking' - CALL 'public abstract fun data2 (value: A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null - : + CALL 'public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null + : $this: GET_VAR ': .FooInterface3.FooInterface3> declared in .FooInterface3.data2Blocking' type=.FooInterface3.FooInterface3> origin=null - value: GET_VAR 'value: A of .FooInterface3.data2Blocking declared in .FooInterface3.data2Blocking' type=A of .FooInterface3.data2Blocking origin=null + value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking declared in .FooInterface3.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface3.FooInterface3>, $receiver:kotlin.Int) returnType:T of .FooInterface3 annotations: Api4J @@ -557,13 +557,13 @@ FILE fqName: fileName:/Main.kt JvmBlocking(baseName = , suffix = , asProperty = ) JvmSynthetic $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface3.FooInterface3>, value:A of .FooInterface3.data2) returnType:T of .FooInterface3 [suspend] + FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface3.FooInterface3>, value:love.forte.plugin.suspendtrans.A of .FooInterface3.data2) returnType:T of .FooInterface3 [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) JvmSynthetic - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface3.data2 + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3.data2 FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface3.FooInterface3>, $receiver:kotlin.Int) returnType:T of .FooInterface3 [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) diff --git a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.txt b/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.txt index e01f208..5bce210 100644 --- a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.txt +++ b/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.txt @@ -6,7 +6,7 @@ FILE: Main.kt public abstract interface FooInterface1 : R|kotlin/Any| { public abstract suspend fun data(): R|T| - public abstract suspend fun data2(value: R|A|): R|T| + public abstract suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| public abstract suspend fun R|kotlin/Int|.data3(): R|T| @@ -20,7 +20,7 @@ FILE: Main.kt ^data R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public open override suspend fun data2(value: R|A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public open override suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| { ^data2 R|kotlin/TODO|() } @@ -28,7 +28,7 @@ FILE: Main.kt ^data3 R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| { ^data2Blocking R|love/forte/plugin/suspendtrans/runtime/$runInBlocking$|(suspend fun (): R|T| { ^ this@R|/FooInterface1Impl|.R|/FooInterface1Impl.data2|(R|/value|) } @@ -100,11 +100,11 @@ FILE: Main.kt public abstract interface FooInterface3 : R|kotlin/Any| { @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public abstract suspend fun data(): R|T| - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public abstract suspend fun data2(value: R|A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public abstract suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public abstract suspend fun R|kotlin/Int|.data3(): R|T| - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| { ^data2Blocking R|love/forte/plugin/suspendtrans/runtime/$runInBlocking$|(suspend fun (): R|T| { ^ this@R|/FooInterface3|.R|/FooInterface3.data2|(R|/value|) } @@ -135,7 +135,7 @@ FILE: Main.kt ^data R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public open override suspend fun data2(value: R|A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public open override suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| { ^data2 R|kotlin/TODO|() } @@ -143,7 +143,7 @@ FILE: Main.kt ^data3 R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| { ^data2Blocking R|love/forte/plugin/suspendtrans/runtime/$runInBlocking$|(suspend fun (): R|T| { ^ this@R|/FooInterface3Impl|.R|/FooInterface3Impl.data2|(R|/value|) } diff --git a/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.ir.txt b/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.ir.txt index 7b2e294..1c4e3b3 100644 --- a/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.ir.txt +++ b/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.ir.txt @@ -19,24 +19,24 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in .FooInterface1 $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:A of .FooInterface1Impl.data2Blocking) returnType:T of .FooInterface1Impl + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking) returnType:T of .FooInterface1Impl annotations: Api4J - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface1Impl.data2Blocking + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface1Impl.data2Blocking): T of .FooInterface1Impl declared in .FooInterface1Impl' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface1Impl> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface1Impl [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface1Impl declared in .FooInterface1Impl.data2Blocking' - CALL 'public open fun data2 (value: A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null - : + CALL 'public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null + : $this: GET_VAR ': .FooInterface1Impl.FooInterface1Impl> declared in .FooInterface1Impl.data2Blocking' type=.FooInterface1Impl.FooInterface1Impl> origin=null - value: GET_VAR 'value: A of .FooInterface1Impl.data2Blocking declared in .FooInterface1Impl.data2Blocking' type=A of .FooInterface1Impl.data2Blocking origin=null + value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking declared in .FooInterface1Impl.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface1Impl annotations: Api4J @@ -78,18 +78,18 @@ FILE fqName: fileName:/Main.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:A of .FooInterface1Impl.data2) returnType:T of .FooInterface1Impl [suspend] + FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2) returnType:T of .FooInterface1Impl [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) TargetMarker(value = "ZGF0YTJGb29JbnRlcmZhY2UxSW1wbDxUPm51bGxB") JvmSynthetic overridden: - public abstract fun data2 (value: A of .FooInterface1.data2): T of .FooInterface1 declared in .FooInterface1 - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1.data2): T of .FooInterface1 declared in .FooInterface1 + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface1Impl.data2 + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2 BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' + RETURN type=kotlin.Nothing from='public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface1Impl [suspend] annotations: @@ -224,26 +224,26 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in .FooInterface3 $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:A of .FooInterface3Impl.data2Blocking) returnType:T of .FooInterface3Impl + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking) returnType:T of .FooInterface3Impl annotations: Api4J overridden: - public open fun data2Blocking (value: A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3 - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3 + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface3Impl.data2Blocking + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface3Impl.data2Blocking): T of .FooInterface3Impl declared in .FooInterface3Impl' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3Impl> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3Impl [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3Impl declared in .FooInterface3Impl.data2Blocking' - CALL 'public open fun data2 (value: A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null - : + CALL 'public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null + : $this: GET_VAR ': .FooInterface3Impl.FooInterface3Impl> declared in .FooInterface3Impl.data2Blocking' type=.FooInterface3Impl.FooInterface3Impl> origin=null - value: GET_VAR 'value: A of .FooInterface3Impl.data2Blocking declared in .FooInterface3Impl.data2Blocking' type=A of .FooInterface3Impl.data2Blocking origin=null + value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking declared in .FooInterface3Impl.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface3Impl annotations: Api4J @@ -289,18 +289,18 @@ FILE fqName: fileName:/Main.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:A of .FooInterface3Impl.data2) returnType:T of .FooInterface3Impl [suspend] + FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2) returnType:T of .FooInterface3Impl [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) TargetMarker(value = "ZGF0YTJGb29JbnRlcmZhY2UzSW1wbDxUPm51bGxB") JvmSynthetic overridden: - public abstract fun data2 (value: A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3 - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3 + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface3Impl.data2 + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2 BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' + RETURN type=kotlin.Nothing from='public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface3Impl [suspend] annotations: @@ -469,10 +469,10 @@ FILE fqName: fileName:/Main.kt $this: VALUE_PARAMETER name: type:kotlin.Any FUN name:data visibility:public modality:ABSTRACT <> ($this:.FooInterface1.FooInterface1>) returnType:T of .FooInterface1 [suspend] $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface1.FooInterface1>, value:A of .FooInterface1.data2) returnType:T of .FooInterface1 [suspend] - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface1.FooInterface1>, value:love.forte.plugin.suspendtrans.A of .FooInterface1.data2) returnType:T of .FooInterface1 [suspend] + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface1.data2 + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1.data2 FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface1.FooInterface1>, $receiver:kotlin.Int) returnType:T of .FooInterface1 [suspend] $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> $receiver: VALUE_PARAMETER name: type:kotlin.Int @@ -516,24 +516,24 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3.FooInterface3>, value:A of .FooInterface3.data2Blocking) returnType:T of .FooInterface3 + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3.FooInterface3>, value:love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking) returnType:T of .FooInterface3 annotations: Api4J - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface3.data2Blocking + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3 [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3 declared in .FooInterface3.data2Blocking' - CALL 'public abstract fun data2 (value: A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null - : + CALL 'public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null + : $this: GET_VAR ': .FooInterface3.FooInterface3> declared in .FooInterface3.data2Blocking' type=.FooInterface3.FooInterface3> origin=null - value: GET_VAR 'value: A of .FooInterface3.data2Blocking declared in .FooInterface3.data2Blocking' type=A of .FooInterface3.data2Blocking origin=null + value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking declared in .FooInterface3.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface3.FooInterface3>, $receiver:kotlin.Int) returnType:T of .FooInterface3 annotations: Api4J @@ -570,14 +570,14 @@ FILE fqName: fileName:/Main.kt TargetMarker(value = "ZGF0YUZvb0ludGVyZmFjZTM8VD5udWxs") JvmSynthetic $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface3.FooInterface3>, value:A of .FooInterface3.data2) returnType:T of .FooInterface3 [suspend] + FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface3.FooInterface3>, value:love.forte.plugin.suspendtrans.A of .FooInterface3.data2) returnType:T of .FooInterface3 [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) TargetMarker(value = "ZGF0YTJGb29JbnRlcmZhY2UzPFQ+bnVsbEE=") JvmSynthetic - TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - VALUE_PARAMETER name:value index:0 type:A of .FooInterface3.data2 + VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3.data2 FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface3.FooInterface3>, $receiver:kotlin.Int) returnType:T of .FooInterface3 [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) diff --git a/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.txt b/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.txt index 50347f6..ef6d65d 100644 --- a/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.txt +++ b/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.txt @@ -6,7 +6,7 @@ FILE: Main.kt public abstract interface FooInterface1 : R|kotlin/Any| { public abstract suspend fun data(): R|T| - public abstract suspend fun data2(value: R|A|): R|T| + public abstract suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| public abstract suspend fun R|kotlin/Int|.data3(): R|T| @@ -20,7 +20,7 @@ FILE: Main.kt ^data R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UxSW1wbDxUPm51bGxB)) public open override suspend fun data2(value: R|A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UxSW1wbDxUPm51bGxB)) public open override suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| { ^data2 R|kotlin/TODO|() } @@ -28,7 +28,7 @@ FILE: Main.kt ^data3 R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun dataBlocking(): R|T| @@ -70,11 +70,11 @@ FILE: Main.kt public abstract interface FooInterface3 : R|kotlin/Any| { @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YUZvb0ludGVyZmFjZTM8VD5udWxs)) public abstract suspend fun data(): R|T| - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UzPFQ+bnVsbEE=)) public abstract suspend fun data2(value: R|A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UzPFQ+bnVsbEE=)) public abstract suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTNGb29JbnRlcmZhY2UzPFQ+a290bGluL0ludA==)) public abstract suspend fun R|kotlin/Int|.data3(): R|T| - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun dataBlocking(): R|T| @@ -90,7 +90,7 @@ FILE: Main.kt ^data R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UzSW1wbDxUPm51bGxB)) public open override suspend fun data2(value: R|A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UzSW1wbDxUPm51bGxB)) public open override suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| { ^data2 R|kotlin/TODO|() } @@ -98,7 +98,7 @@ FILE: Main.kt ^data3 R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open override fun dataBlocking(): R|T| diff --git a/plugins/ide/suspend-transform-plugin-idea/src/main/resources/META-INF/plugin.xml b/plugins/ide/suspend-transform-plugin-idea/src/main/resources/META-INF/plugin.xml index 39a345a..6ad4215 100644 --- a/plugins/ide/suspend-transform-plugin-idea/src/main/resources/META-INF/plugin.xml +++ b/plugins/ide/suspend-transform-plugin-idea/src/main/resources/META-INF/plugin.xml @@ -9,7 +9,7 @@ - + ForteScarlet @@ -44,4 +44,4 @@ - \ No newline at end of file + diff --git a/plugins/suspend-transform-plugin-gradle/build.gradle.kts b/plugins/suspend-transform-plugin-gradle/build.gradle.kts index 49b174a..59a0c68 100644 --- a/plugins/suspend-transform-plugin-gradle/build.gradle.kts +++ b/plugins/suspend-transform-plugin-gradle/build.gradle.kts @@ -29,7 +29,7 @@ dependencies { compileOnly(gradleApi()) compileOnly(kotlin("gradle-plugin")) compileOnly(kotlin("gradle-plugin-api")) - api(project(":compiler:suspend-transform-plugin")) + compileOnly(project(":compiler:suspend-transform-plugin")) api(project(":compiler:suspend-transform-plugin-cli")) api(project(":compiler:suspend-transform-plugin-configuration")) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt index 363d639..1df8b11 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt @@ -7,6 +7,14 @@ import love.forte.plugin.suspendtrans.SuspendTransformConfiguration * * @author ForteScarlet */ +@Deprecated( + "Use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + + "(`suspendTransformPlugin { ... }`)", + ReplaceWith( + "SuspendTransformPluginExtension", + "love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension" + ) +) open class SuspendTransformGradleExtension : SuspendTransformConfiguration() { /** diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index d10fbcf..3d4855d 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -1,6 +1,8 @@ package love.forte.plugin.suspendtrans.gradle import love.forte.plugin.suspendtrans.CliOptions +import love.forte.plugin.suspendtrans.cli.SuspendTransformCliOptions +import love.forte.plugin.suspendtrans.cli.encodeToHex import love.forte.plugin.suspendtrans.gradle.DependencyConfigurationName.* import org.gradle.api.Project import org.gradle.api.provider.Provider @@ -14,7 +16,13 @@ import org.jetbrains.kotlin.gradle.plugin.* */ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { override fun apply(target: Project) { - target.extensions.create("suspendTransform", SuspendTransformGradleExtension::class.java) + // TODO 想办法兼容过渡一下 + // try { + // Class.forName("love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension") + // target.extensions.create("suspendTransform", SuspendTransformGradleExtension::class.java) + // } catch (ignore: ClassNotFoundException) { + // } catch (ignore: NoClassDefFoundError) { + // } val createdExtensions = target.extensions.create( "suspendTransformPlugin", @@ -31,7 +39,7 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { val project = kotlinCompilation.target.project val isApplicable = project.plugins.hasPlugin(SuspendTransformGradlePlugin::class.java) - && project.configOrNull?.enabled != false + && project.configOrNull?.enabled?.get() != false return isApplicable } @@ -50,29 +58,34 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { override fun applyToCompilation(kotlinCompilation: KotlinCompilation<*>): Provider> { val target = kotlinCompilation.target val project = target.project - val extension = project.extensions.getByType(SuspendTransformGradleExtension::class.java) + @Suppress("DEPRECATION") val oldExtension = + project.extensions.getByType(SuspendTransformGradleExtension::class.java) + if (oldExtension.transformers.isNotEmpty()) { + project.logger.warn( + "The `love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension` " + + "(`suspendTransform { ... }`) is deprecated, " + + "please use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + + "(`suspendTransformPlugin { ... }`) instead." + ) + } -// val dependencies = project.dependencies -// dependencies.add( -// "compileOnly", -// "${SuspendTransPluginConstants.ANNOTATION_GROUP}:${SuspendTransPluginConstants.ANNOTATION_NAME}:${SuspendTransPluginConstants.ANNOTATION_VERSION}" -// ) -// if (extension.includeRuntime) { -// dependencies.add( -// extension.runtimeConfigurationName, -// "${SuspendTransPluginConstants.RUNTIME_GROUP}:${SuspendTransPluginConstants.RUNTIME_NAME}:${SuspendTransPluginConstants.RUNTIME_VERSION}" -// ) -// } + val extension = project.extensions.getByType(SuspendTransformPluginExtension::class.java) return project.provider { extension.toSubpluginOptions() } } - } +@Deprecated( + message = "Use `SuspendTransformPluginExtension`", + replaceWith = ReplaceWith( + "SuspendTransformPluginExtension", + "love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension" + ) +) private fun SuspendTransformGradleExtension.toSubpluginOptions(): List { return CliOptions.allOptions.map { SubpluginOption(it.oName, it.resolveToValue(this)) @@ -80,10 +93,16 @@ private fun SuspendTransformGradleExtension.toSubpluginOptions(): List { + val cliConfig = SuspendTransformCliOptions.CLI_CONFIGURATION + val configuration = toConfiguration() + return listOf(SubpluginOption(cliConfig.optionName, configuration.encodeToHex())) +} + private fun Project.configureDependencies() { - fun Project.include(platform: Platform, conf: SuspendTransformGradleExtension) { - if (!conf.enabled) { + fun Project.include(platform: Platform, conf: SuspendTransformPluginExtension) { + if (conf.enabled.get()) { logger.info( "The `SuspendTransformGradleExtension.enable` in project {} for platform {} is `false`, skip config.", this, @@ -92,32 +111,42 @@ private fun Project.configureDependencies() { return } - if (conf.includeAnnotation) { + if (conf.includeAnnotation.get()) { + // val notation = getDependencyNotation( val notation = getDependencyNotation( SuspendTransPluginConstants.ANNOTATION_GROUP, SuspendTransPluginConstants.ANNOTATION_NAME, platform, - conf.annotationDependencyVersion + conf.annotationDependency.flatMap { it.version } ) - if (platform == Platform.JVM) { - dependencies.add(conf.annotationConfigurationName, notation) - } else { - // JS, native 似乎不支持 compileOnly - dependencies.add("implementation", notation) + + var configName = conf.annotationDependency.get().configurationName.get() + if (configName == "compileOnly" && platform != Platform.JVM) { + configName = "implementation" } + + dependencies.add(configName, notation) dependencies.add("testImplementation", notation) } - if (conf.includeRuntime) { + + if (conf.includeRuntime.get()) { val notation = getDependencyNotation( SuspendTransPluginConstants.RUNTIME_GROUP, SuspendTransPluginConstants.RUNTIME_NAME, platform, - conf.runtimeDependencyVersion + conf.runtimeDependency.flatMap { it.version } ) - dependencies.add(conf.runtimeConfigurationName, notation) + var configName = conf.runtimeDependency.get().configurationName.get() + if (configName == "compileOnly" && platform != Platform.JVM) { + // JS, native 似乎不支持 compileOnly,因此如果不是JVM,更换为 implementation + configName = "implementation" + } + + dependencies.add(configName, notation) dependencies.add("testImplementation", notation) } } + withPluginWhenEvaluatedConf("kotlin") { conf -> include(Platform.JVM, conf) } @@ -148,7 +177,7 @@ fun Project.withPluginWhenEvaluated(plugin: String, fn: Project.() -> Unit) { fun Project.withPluginWhenEvaluatedConf( plugin: String, - fn: Project.(conf: SuspendTransformGradleExtension) -> Unit + fn: Project.(conf: SuspendTransformPluginExtension) -> Unit ) { withPluginWhenEvaluated(plugin) { fn(config) @@ -159,8 +188,8 @@ private enum class DependencyConfigurationName { API, IMPLEMENTATION, COMPILE_ONLY } -fun Project.configureMultiplatformDependency(conf: SuspendTransformGradleExtension) { - if (!conf.enabled) { +fun Project.configureMultiplatformDependency(conf: SuspendTransformPluginExtension) { + if (!conf.enabled.get()) { logger.info( "The `SuspendTransformGradleExtension.enable` in project {} for multiplatform is `false`, skip config.", this, @@ -177,23 +206,23 @@ fun Project.configureMultiplatformDependency(conf: SuspendTransformGradleExtensi val commonTestSourceSets = multiplatformExtensions.sourceSets.getByName(KotlinSourceSet.COMMON_TEST_SOURCE_SET_NAME) - if (conf.includeAnnotation) { + if (conf.includeAnnotation.get()) { val notation = getDependencyNotation( SuspendTransPluginConstants.ANNOTATION_GROUP, SuspendTransPluginConstants.ANNOTATION_NAME, Platform.MULTIPLATFORM, - conf.annotationDependencyVersion + conf.annotationDependency.flatMap { it.version } ) dependencies.add(commonMainSourceSets.compileOnlyConfigurationName, notation) dependencies.add(commonTestSourceSets.implementationConfigurationName, notation) } - if (conf.includeRuntime) { + if (conf.includeRuntime.get()) { val notation = getDependencyNotation( SuspendTransPluginConstants.RUNTIME_GROUP, SuspendTransPluginConstants.RUNTIME_NAME, Platform.MULTIPLATFORM, - conf.annotationDependencyVersion + conf.runtimeDependency.flatMap { it.version } ) dependencies.add(commonMainSourceSets.implementationConfigurationName, notation) dependencies.add(commonTestSourceSets.implementationConfigurationName, notation) @@ -208,23 +237,23 @@ fun Project.configureMultiplatformDependency(conf: SuspendTransformGradleExtensi } if (isSharedSourceSet) { - if (conf.includeAnnotation) { + if (conf.includeAnnotation.get()) { val notation = getDependencyNotation( SuspendTransPluginConstants.ANNOTATION_GROUP, SuspendTransPluginConstants.ANNOTATION_NAME, Platform.MULTIPLATFORM, - conf.annotationDependencyVersion + conf.annotationDependency.flatMap { it.version } ) val configuration = sourceSet.implementationConfigurationName dependencies.add(configuration, notation) } - if (conf.includeRuntime) { + if (conf.includeRuntime.get()) { val notation = getDependencyNotation( SuspendTransPluginConstants.RUNTIME_GROUP, SuspendTransPluginConstants.RUNTIME_NAME, Platform.MULTIPLATFORM, - conf.annotationDependencyVersion + conf.runtimeDependency.flatMap { it.version } ) val configuration = sourceSet.implementationConfigurationName dependencies.add(configuration, notation) @@ -266,7 +295,7 @@ fun Project.configureMultiplatformDependency(conf: SuspendTransformGradleExtensi } } - if (conf.includeAnnotation) { + if (conf.includeAnnotation.get()) { val configurationName = when { // impl dependency for native (there is no transformation) platform == Platform.NATIVE -> IMPLEMENTATION // sourceSet.implementationConfigurationName @@ -281,7 +310,7 @@ fun Project.configureMultiplatformDependency(conf: SuspendTransformGradleExtensi SuspendTransPluginConstants.ANNOTATION_GROUP, SuspendTransPluginConstants.ANNOTATION_NAME, platform, - conf.annotationDependencyVersion + conf.annotationDependency.flatMap { it.version } ) sourceSet.dependencies { @@ -309,14 +338,14 @@ fun Project.configureMultiplatformDependency(conf: SuspendTransformGradleExtensi ) } - if (conf.includeRuntime) { + if (conf.includeRuntime.get()) { // val configurationName = sourceSet.implementationConfigurationName val notation = getDependencyNotation( SuspendTransPluginConstants.RUNTIME_GROUP, SuspendTransPluginConstants.RUNTIME_NAME, platform, - conf.runtimeDependencyVersion + conf.runtimeDependency.flatMap { it.version } ) sourceSet.dependencies { implementation(notation) @@ -362,11 +391,11 @@ private fun String.compilationNameToType(): CompilationType? = when (this) { else -> null } -private val Project.config: SuspendTransformGradleExtension - get() = configOrNull ?: SuspendTransformGradleExtension() +private val Project.config: SuspendTransformPluginExtension + get() = configOrNull ?: objects.newInstance(SuspendTransformPluginExtension::class.java) -private val Project.configOrNull: SuspendTransformGradleExtension? - get() = extensions.findByType(SuspendTransformGradleExtension::class.java) +private val Project.configOrNull: SuspendTransformPluginExtension? + get() = extensions.findByType(SuspendTransformPluginExtension::class.java) private enum class Platform(val suffix: String) { JVM("-jvm"), JS("-js"), NATIVE(""), MULTIPLATFORM("") @@ -375,5 +404,8 @@ private enum class Platform(val suffix: String) { private fun getDependencyNotation(group: String, name: String, platform: Platform, version: String): String = "$group:$name${platform.suffix}:$version" +private fun getDependencyNotation(group: String, name: String, platform: Platform, version: Provider): Provider = + version.map { versionValue -> getDependencyNotation(group, name, platform, versionValue) } + private fun Project.getBooleanProperty(name: String) = rootProject.findProperty(name)?.toString()?.toBooleanStrict() ?: false diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index 8cbc11b..2fce2a0 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -5,7 +5,6 @@ import org.gradle.api.Action import org.gradle.api.DomainObjectSet import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.* -import org.gradle.api.tasks.Nested import javax.inject.Inject abstract class TransformerContainer @@ -62,11 +61,17 @@ abstract class TransformerContainer fun addCommon(action: Action) = add(TargetPlatform.COMMON, action) } -interface SuspendTransformPluginExtension { - val enabled: Property +abstract class SuspendTransformPluginExtension @Inject constructor(objects: ObjectFactory) { + /** + * Enabled plugin. + * + * Default is `true`. + */ + abstract val enabled: Property + - @get:Nested - val transformers: TransformerContainer + val transformers: TransformerContainer = + objects.newInstance() fun transformers(action: Action) { action.execute(transformers) @@ -86,16 +91,31 @@ interface SuspendTransformPluginExtension { useJsDefault() } - val includeAnnotation: Property - val includeRuntime: Property + /** + * Include the `love.forte.plugin.suspend-transform:suspend-transform-annotation`. + * Default is `true`. + */ + abstract val includeAnnotation: Property + + /** + * Include the `love.forte.plugin.suspend-transform:suspend-transform-runtime`. + * Default is `true`. + */ + abstract val includeRuntime: Property - val annotationDependency: Property + /** + * Default is `compileOnly` with [SuspendTransPluginConstants.ANNOTATION_VERSION] + */ + abstract val annotationDependency: Property fun annotationDependency(action: Action) { annotationDependency.set(annotationDependency.get().also(action::execute)) } - val runtimeDependency: Property + /** + * Default is `implementation` with [SuspendTransPluginConstants.RUNTIME_VERSION] + */ + abstract val runtimeDependency: Property fun runtimeDependency(action: Action) { runtimeDependency.set(runtimeDependency.get().also(action::execute)) @@ -106,13 +126,44 @@ interface SuspendTransformPluginExtension { } } -interface DependencySpec { +@OptIn(InternalSuspendTransformConstructorApi::class) +internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransformConfiguration { + return SuspendTransformConfiguration( + enabled = enabled.getOrElse(true), + transformers = transformers.transformers.mapValuesTo(mutableMapOf()) { (_, values) -> + values.map { valueList -> valueList.map { it.toTransformer() } }.getOrElse(emptyList()) + } + ) +} + +sealed interface DependencySpec { val version: Property val configurationName: Property } -interface AnnotationDependencySpec : DependencySpec -interface RuntimeDependencySpec : DependencySpec +interface AnnotationDependencySpec : DependencySpec { + /** + * Default is `compileOnly`. + */ + override val configurationName: Property + + /** + * Default is [SuspendTransPluginConstants.ANNOTATION_VERSION] + */ + override val version: Property +} + +interface RuntimeDependencySpec : DependencySpec { + /** + * Default is `implementation`. + */ + override val configurationName: Property + + /** + * Default is [SuspendTransPluginConstants.RUNTIME_VERSION] + */ + override val version: Property +} internal fun SuspendTransformPluginExtension.defaults( objects: ObjectFactory, @@ -275,6 +326,10 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa copyAnnotationsToSyntheticProperty.set(transformer.copyAnnotationsToSyntheticProperty) } + + internal fun toTransformer(): Transformer { + TODO() + } } /** diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index 443cf87..aa724ab 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -11,7 +11,7 @@ plugins { `java-library` kotlin("jvm") - id("love.forte.plugin.suspend-transform") version "2.1.20-0.12.0" + id("love.forte.plugin.suspend-transform") version "2.1.20-0.11.1" // id("suspend-transform.jvm-maven-publish") // id(project(":suspend-transform-plugin-gradle")) } @@ -38,7 +38,7 @@ dependencies { api(libs.kotlinx.coroutines.core) } -suspendTransformPlugin { +suspendTransform { // transformers { // useJvmDefault() @@ -46,66 +46,6 @@ suspendTransformPlugin { // } } -// suspendTransformPlugin { -// transformers { -// addJvm { -// originFunctionIncludeAnnotations -// // originFunctionIncludeAnnotations { -// // create("demo1") { -// // classInfo { from(SuspendTransformConfigurations.jvmSyntheticClassInfo) } -// // } -// // } -// } -// } -// } - -// suspendTransformPlugin { -// includeRuntime = false -// transformers { -// // addJvm { -// // originFunctionIncludeAnnotations { -// // create("Hi~") { -// // classInfo { -// // } -// // } -// // } -// // } -// } -// // transformers { -// // addJvm { -// // originFunctionIncludeAnnotations.create("any name") { -// // -// // } -// // } -// // } -// // transformers.addJvm { -// // originFunctionIncludeAnnotations -// // } -// } - -// extensions.getByType().apply { -// includeRuntime = false -// includeAnnotation = false -// // useJvmDefault() -// transformers[TargetPlatform.JVM] = mutableListOf( -// // Add `kotlin.OptIn` to copyAnnotationExcludes -// jvmBlockingTransformer.copy( -// copyAnnotationExcludes = buildList { -// addAll(jvmBlockingTransformer.copyAnnotationExcludes) -// add(ClassInfo("kotlin", "OptIn")) -// } -// ), -// -// // Add `kotlin.OptIn` to copyAnnotationExcludes -// jvmAsyncTransformer.copy( -// copyAnnotationExcludes = buildList { -// addAll(jvmAsyncTransformer.copyAnnotationExcludes) -// add(ClassInfo("kotlin", "OptIn")) -// } -// ) -// ) -// } - tasks.withType { useJUnitPlatform() } From ce3774f45e70ab94fbb353ce9f1bebe91f293a3c Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Mon, 14 Apr 2025 20:04:49 +0800 Subject: [PATCH 05/21] Refactor and deprecate legacy Gradle extension support Reorganized Gradle plugin structure by introducing a separate module for deprecated configurations. Deprecated `SuspendTransformGradleExtension`, redirecting users to `SuspendTransformPluginExtension`. Added compatibility handling to maintain backward support while preparing for full removal of deprecated features. --- .../SuspendTransformConfiguration.kt | 2 +- .../README.md | 7 + .../build.gradle.kts | 29 ++++ .../forte/plugin/suspendtrans/CliOptions.kt | 2 + ...eprecatedSuspendTransformConfiguration.kt} | 40 +++++- .../suspend-transform-plugin/build.gradle.kts | 3 +- .../build.gradle.kts | 3 +- .../gradle/SuspendTransformGradleExtension.kt | 21 ++- .../gradle/SuspendTransformGradlePlugin.kt | 85 +++++++----- .../gradle/SuspendTransformPluginExtension.kt | 126 +++++++++++++++--- settings.gradle.kts | 1 + tests/test-jvm/build.gradle.kts | 7 +- 12 files changed, 254 insertions(+), 72 deletions(-) create mode 100644 compiler/suspend-transform-plugin-deprecated-configuration/README.md create mode 100644 compiler/suspend-transform-plugin-deprecated-configuration/build.gradle.kts rename compiler/{suspend-transform-plugin => suspend-transform-plugin-deprecated-configuration}/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt (99%) rename compiler/{suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt => suspend-transform-plugin-deprecated-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/DeprecatedSuspendTransformConfiguration.kt} (87%) diff --git a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt index e171ec0..f2a042e 100644 --- a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt +++ b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt @@ -139,7 +139,7 @@ class IncludeAnnotation @InternalSuspendTransformConstructorApi constructor( val classInfo: ClassInfo, val repeatable: Boolean = false, /** - * 如果是追加,是否追加到property上 + * 是否追加到property上 * * @since 0.9.0 */ diff --git a/compiler/suspend-transform-plugin-deprecated-configuration/README.md b/compiler/suspend-transform-plugin-deprecated-configuration/README.md new file mode 100644 index 0000000..c6d37a2 --- /dev/null +++ b/compiler/suspend-transform-plugin-deprecated-configuration/README.md @@ -0,0 +1,7 @@ +# Module suspend-transform-plugin-deprecated-configuration + +此模块将原本在 `suspend-transform-plugin` 中的 +`love.forte.plugin.suspendtrans.CliOptions.kt` +和 +`love.forte.plugin.suspendtrans.SuspendTransformConfiguration.kt` +提取出来作为单独的模块,以便兼容和过渡。 diff --git a/compiler/suspend-transform-plugin-deprecated-configuration/build.gradle.kts b/compiler/suspend-transform-plugin-deprecated-configuration/build.gradle.kts new file mode 100644 index 0000000..49a6a0b --- /dev/null +++ b/compiler/suspend-transform-plugin-deprecated-configuration/build.gradle.kts @@ -0,0 +1,29 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget + +plugins { + kotlin("jvm") + kotlin("plugin.serialization") + id("suspend-transform.jvm-maven-publish") +} + +dependencies { + compileOnly(kotlin("compiler")) + api(libs.kotlinx.serialization.core) + api(libs.kotlinx.serialization.json) + testImplementation(kotlin("test")) +} + +kotlin { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_1_8) + freeCompilerArgs.addAll( + "-Xjvm-default=all", + ) + } + +} + +tasks.test { + useJUnitPlatform() +} + diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt b/compiler/suspend-transform-plugin-deprecated-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt similarity index 99% rename from compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt rename to compiler/suspend-transform-plugin-deprecated-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt index fdf6d39..6856426 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt +++ b/compiler/suspend-transform-plugin-deprecated-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/CliOptions.kt @@ -1,3 +1,5 @@ +@file:Suppress("DEPRECATION") + package love.forte.plugin.suspendtrans import kotlinx.serialization.builtins.ListSerializer diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt b/compiler/suspend-transform-plugin-deprecated-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/DeprecatedSuspendTransformConfiguration.kt similarity index 87% rename from compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt rename to compiler/suspend-transform-plugin-deprecated-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/DeprecatedSuspendTransformConfiguration.kt index a97a8fb..31905e6 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformConfiguration.kt +++ b/compiler/suspend-transform-plugin-deprecated-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/DeprecatedSuspendTransformConfiguration.kt @@ -1,8 +1,22 @@ +@file:Suppress("DEPRECATION") + package love.forte.plugin.suspendtrans import kotlinx.serialization.Serializable -// TODO 序列化改成二进制的,比如 protobuf, + +private const val JVM_RUN_IN_BLOCKING_FUNCTION_PACKAGE_NAME: String = "love.forte.plugin.suspendtrans.runtime" +private val JVM_RUN_IN_BLOCKING_FUNCTION_CLASS_NAME: String? = null +private const val JVM_RUN_IN_BLOCKING_FUNCTION_FUNCTION_NAME: String = "\$runInBlocking\$" + +private const val JVM_RUN_IN_ASYNC_FUNCTION_PACKAGE_NAME: String = "love.forte.plugin.suspendtrans.runtime" +private val JVM_RUN_IN_ASYNC_FUNCTION_CLASS_NAME: String? = null +private const val JVM_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME: String = "\$runInAsync\$" + +private const val JS_RUN_IN_ASYNC_FUNCTION_PACKAGE_NAME: String = "love.forte.plugin.suspendtrans.runtime" +private val JS_RUN_IN_ASYNC_FUNCTION_CLASS_NAME: String? = null +private const val JS_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME: String = "\$runInAsync\$" + @Serializable @Deprecated( @@ -178,6 +192,9 @@ data class IncludeAnnotation( var includeProperty: Boolean = false } +const val USE_NEW_EXTENSION = "Please use the `love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration`" + + "(`suspendTransformPlugin { ... }`) instead." + /** * * @author ForteScarlet @@ -185,15 +202,17 @@ data class IncludeAnnotation( @Suppress("unused") @Serializable @Deprecated( - message = "Use new `love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration` instead.", + message = USE_NEW_EXTENSION, replaceWith = ReplaceWith( "SuspendTransformConfiguration", "love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration" ) ) open class SuspendTransformConfiguration { + @Deprecated(USE_NEW_EXTENSION) open var enabled: Boolean = true + @Deprecated(USE_NEW_EXTENSION) open var transformers: MutableMap> = mutableMapOf() /** @@ -206,23 +225,28 @@ open class SuspendTransformConfiguration { @Deprecated("Unused after *-0.11.0") open var targetMarker: ClassInfo? = targetMarkerClassInfo + @Deprecated(USE_NEW_EXTENSION) open fun clear() { transformers.clear() } + @Deprecated(USE_NEW_EXTENSION) open fun useJvmDefault() { transformers[TargetPlatform.JVM] = mutableListOf(jvmBlockingTransformer, jvmAsyncTransformer) } + @Deprecated(USE_NEW_EXTENSION) open fun useJsDefault() { transformers[TargetPlatform.JS] = mutableListOf(jsPromiseTransformer) } + @Deprecated(USE_NEW_EXTENSION) open fun useDefault() { useJvmDefault() useJsDefault() } + @Deprecated(USE_NEW_EXTENSION) open fun addTransformers(target: TargetPlatform, vararg transformers: Transformer) { this.transformers.compute(target) { _, list -> if (list != null) { @@ -233,6 +257,7 @@ open class SuspendTransformConfiguration { } } + @Deprecated(USE_NEW_EXTENSION) open fun addTransformers(target: TargetPlatform, transformers: Collection) { this.transformers.compute(target) { _, list -> if (list != null) { @@ -243,18 +268,22 @@ open class SuspendTransformConfiguration { } } + @Deprecated(USE_NEW_EXTENSION) open fun addJvmTransformers(vararg transformers: Transformer) { addTransformers(target = TargetPlatform.JVM, transformers = transformers) } + @Deprecated(USE_NEW_EXTENSION) open fun addJvmTransformers(transformers: Collection) { addTransformers(target = TargetPlatform.JVM, transformers = transformers) } + @Deprecated(USE_NEW_EXTENSION) open fun addJsTransformers(vararg transformers: Transformer) { addTransformers(target = TargetPlatform.JS, transformers = transformers) } + @Deprecated(USE_NEW_EXTENSION) open fun addJsTransformers(transformers: Collection) { addTransformers(target = TargetPlatform.JS, transformers = transformers) } @@ -263,6 +292,7 @@ open class SuspendTransformConfiguration { return "SuspendTransformConfiguration(enabled=$enabled, transformers=$transformers)" } + @Deprecated(USE_NEW_EXTENSION) companion object { val targetMarkerClassInfo = ClassInfo("love.forte.plugin.suspendtrans.annotation", "TargetMarker") @@ -362,9 +392,9 @@ open class SuspendTransformConfiguration { @JvmStatic val jsAsyncTransformFunction = FunctionInfo( - JS_RUN_IN_ASYNC_FUNCTION_PACKAGE_NAME, - JS_RUN_IN_ASYNC_FUNCTION_CLASS_NAME, - JS_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME, + love.forte.plugin.suspendtrans.JS_RUN_IN_ASYNC_FUNCTION_PACKAGE_NAME, + love.forte.plugin.suspendtrans.JS_RUN_IN_ASYNC_FUNCTION_CLASS_NAME, + love.forte.plugin.suspendtrans.JS_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME, ) @JvmStatic diff --git a/compiler/suspend-transform-plugin/build.gradle.kts b/compiler/suspend-transform-plugin/build.gradle.kts index 50bb6f7..04e55ec 100644 --- a/compiler/suspend-transform-plugin/build.gradle.kts +++ b/compiler/suspend-transform-plugin/build.gradle.kts @@ -13,8 +13,7 @@ dependencies { compileOnly(kotlin("stdlib")) implementation(kotlin("compiler")) compileOnly(libs.kotlinx.coroutines.core) - // TODO remove JSON - api(libs.kotlinx.serialization.json) + api(project(":compiler:suspend-transform-plugin-deprecated-configuration")) api(project(":compiler:suspend-transform-plugin-cli")) testImplementation(kotlin("stdlib")) diff --git a/plugins/suspend-transform-plugin-gradle/build.gradle.kts b/plugins/suspend-transform-plugin-gradle/build.gradle.kts index 59a0c68..763cfb8 100644 --- a/plugins/suspend-transform-plugin-gradle/build.gradle.kts +++ b/plugins/suspend-transform-plugin-gradle/build.gradle.kts @@ -29,9 +29,10 @@ dependencies { compileOnly(gradleApi()) compileOnly(kotlin("gradle-plugin")) compileOnly(kotlin("gradle-plugin-api")) - compileOnly(project(":compiler:suspend-transform-plugin")) + // compileOnly(project(":compiler:suspend-transform-plugin")) api(project(":compiler:suspend-transform-plugin-cli")) api(project(":compiler:suspend-transform-plugin-configuration")) + api(project(":compiler:suspend-transform-plugin-deprecated-configuration")) } diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt index 1df8b11..ff69979 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt @@ -1,49 +1,60 @@ package love.forte.plugin.suspendtrans.gradle -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration - +const val USE_NEW_EXTENSION = "Use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + + "(`suspendTransformPlugin { ... }`)" /** * * @author ForteScarlet */ +@Suppress("DEPRECATION") @Deprecated( - "Use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + - "(`suspendTransformPlugin { ... }`)", + USE_NEW_EXTENSION, ReplaceWith( "SuspendTransformPluginExtension", "love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension" ) ) -open class SuspendTransformGradleExtension : SuspendTransformConfiguration() { +open class SuspendTransformGradleExtension : love.forte.plugin.suspendtrans.SuspendTransformConfiguration() { + @Deprecated("Please use the " + + "`love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration` " + + "(`suspendTransformPlugin { ... }`) instead.") + override var enabled: Boolean = false /** * 是否增加 `love.forte.plugin.suspend-transform:suspend-transform-annotation` 的运行时。 */ + @Deprecated(USE_NEW_EXTENSION) open var includeAnnotation: Boolean = true + @Deprecated(USE_NEW_EXTENSION) open var annotationDependencyVersion: String = SuspendTransPluginConstants.ANNOTATION_VERSION /** * 当 [includeAnnotation] 为 true 时,配置runtime环境的依赖方式。默认为 `compileOnly` (在JVM中) 。 */ + @Deprecated(USE_NEW_EXTENSION) open var annotationConfigurationName: String = "compileOnly" /** * 是否增加 `love.forte.plugin.suspend-transform:suspend-transform-runtime` 的运行时。 */ + @Deprecated(USE_NEW_EXTENSION) open var includeRuntime: Boolean = true + @Deprecated(USE_NEW_EXTENSION) open var runtimeDependencyVersion: String = SuspendTransPluginConstants.RUNTIME_VERSION /** * 当 [includeRuntime] 为 true 时,配置runtime环境的依赖方式。默认为 `implementation` (在JVM中)。 */ + @Deprecated(USE_NEW_EXTENSION) open var runtimeConfigurationName: String = "implementation" /** * 将runtime环境作为 `api` 的方式进行配置(在JVM中)。 */ + @Deprecated(USE_NEW_EXTENSION) open fun runtimeAsApi() { runtimeConfigurationName = "api" } diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index 3d4855d..933e7fe 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -1,6 +1,5 @@ package love.forte.plugin.suspendtrans.gradle -import love.forte.plugin.suspendtrans.CliOptions import love.forte.plugin.suspendtrans.cli.SuspendTransformCliOptions import love.forte.plugin.suspendtrans.cli.encodeToHex import love.forte.plugin.suspendtrans.gradle.DependencyConfigurationName.* @@ -15,19 +14,21 @@ import org.jetbrains.kotlin.gradle.plugin.* * @author ForteScarlet */ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { + companion object { + const val EXTENSION_NAME = "suspendTransform" + const val PLUGIN_EXTENSION_NAME = "suspendTransformPlugin" + } + override fun apply(target: Project) { - // TODO 想办法兼容过渡一下 - // try { - // Class.forName("love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension") - // target.extensions.create("suspendTransform", SuspendTransformGradleExtension::class.java) - // } catch (ignore: ClassNotFoundException) { - // } catch (ignore: NoClassDefFoundError) { - // } + @Suppress("DEPRECATION") + target.extensions.create( + EXTENSION_NAME, + SuspendTransformGradleExtension::class.java + ) val createdExtensions = target.extensions.create( - "suspendTransformPlugin", + PLUGIN_EXTENSION_NAME, SuspendTransformPluginExtension::class.java, - // AbstractSuspendTransformPluginExtension::class.java, ) createdExtensions.defaults(target.objects, target.providers) @@ -59,18 +60,40 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { val target = kotlinCompilation.target val project = target.project + val extension = project.extensions.getByType(SuspendTransformPluginExtension::class.java) + @Suppress("DEPRECATION") val oldExtension = project.extensions.getByType(SuspendTransformGradleExtension::class.java) - if (oldExtension.transformers.isNotEmpty()) { - project.logger.warn( - "The `love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension` " + - "(`suspendTransform { ... }`) is deprecated, " + - "please use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + - "(`suspendTransformPlugin { ... }`) instead." - ) - } + @Suppress("DEPRECATION") + if (oldExtension.enabled || oldExtension.transformers.isNotEmpty()) { + val showError = + project.providers.gradleProperty("love.forte.plugin.suspend-transform.deprecatedExtensionError") + .map { it.toBoolean() }.getOrElse(true) + + val showWarn = + project.providers.gradleProperty("love.forte.plugin.suspend-transform.deprecatedExtensionWarn") + .map { it.toBoolean() }.getOrElse(false) + + val msg = "The `love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension` " + + "(`suspendTransform { ... }`) is deprecated, " + + "please use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + + "(`suspendTransformPlugin { ... }`) instead. " + + "The SuspendTransformGradleExtension property " + + "will currently be aggregated with `SuspendTransformPluginExtension`, " + + "but it will soon be deprecated completely." + + when { + showError -> { + project.logger.error(msg) + } - val extension = project.extensions.getByType(SuspendTransformPluginExtension::class.java) + showWarn -> { + project.logger.warn(msg) + } + } + + oldExtension.mergeTo(extension) + } return project.provider { extension.toSubpluginOptions() @@ -78,19 +101,9 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { } } - -@Deprecated( - message = "Use `SuspendTransformPluginExtension`", - replaceWith = ReplaceWith( - "SuspendTransformPluginExtension", - "love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension" - ) -) -private fun SuspendTransformGradleExtension.toSubpluginOptions(): List { - return CliOptions.allOptions.map { - SubpluginOption(it.oName, it.resolveToValue(this)) - } - +@Suppress("DEPRECATION") +private fun SuspendTransformGradleExtension.mergeTo(extension: SuspendTransformPluginExtension) { + TODO() } private fun SuspendTransformPluginExtension.toSubpluginOptions(): List { @@ -99,7 +112,6 @@ private fun SuspendTransformPluginExtension.toSubpluginOptions(): List): Provider = +private fun getDependencyNotation( + group: String, + name: String, + platform: Platform, + version: Provider +): Provider = version.map { versionValue -> getDependencyNotation(group, name, platform, versionValue) } private fun Project.getBooleanProperty(name: String) = diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index 2fce2a0..0b85241 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -77,15 +77,27 @@ abstract class SuspendTransformPluginExtension @Inject constructor(objects: Obje action.execute(transformers) } - fun useJvmDefault() { + fun addJvmBlockingTransformer() { transformers.addJvm(SuspendTransformConfigurations.jvmBlockingTransformer) + } + + fun addJvmAsyncTransformer() { transformers.addJvm(SuspendTransformConfigurations.jvmAsyncTransformer) } - fun useJsDefault() { + fun useJvmDefault() { + addJvmBlockingTransformer() + addJvmAsyncTransformer() + } + + fun addJsPromiseTransformer() { transformers.addJs(SuspendTransformConfigurations.jsPromiseTransformer) } + fun useJsDefault() { + addJsPromiseTransformer() + } + fun useDefault() { useJvmDefault() useJsDefault() @@ -187,6 +199,9 @@ internal fun SuspendTransformPluginExtension.defaults( } abstract class TransformerSpec @Inject constructor(private val objects: ObjectFactory) { + /** + * @see Transformer.markAnnotation + */ abstract val markAnnotation: Property fun markAnnotation(action: Action) { @@ -228,6 +243,8 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa /** * 转化后的返回值类型, 为null时代表与原函数一致。 + * + * Will be used when [transformReturnTypeGeneric] is `true`. */ abstract val transformReturnType: Property @@ -241,8 +258,13 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa /** * 转化后的返回值类型中,是否存在需要与原本返回值类型一致的泛型。 + * 这里指的是返回值类型中嵌套的范型,例如 `CompletableFuture` 中的 `T`。 + * 如果是直接返回 `T`,则不需要设置为 `true`。 + * + * Default value is `false`. */ - abstract val transformReturnTypeGeneric: Property + val transformReturnTypeGeneric: Property = + objects.property(Boolean::class.java).convention(false) /** * 函数生成后,需要在原函数上追加的注解信息。 @@ -271,8 +293,11 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa /** * 是否复制源函数上的注解到新的函数上。 * 如果生成的是属性类型,则表示是否复制到 `getter` 上。 + * + * Default value is `false`. */ - abstract val copyAnnotationsToSyntheticFunction: Property + val copyAnnotationsToSyntheticFunction: Property = + objects.property(Boolean::class.java).convention(false) /** * 复制原函数上注解时需要排除掉的注解。 @@ -326,10 +351,6 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa copyAnnotationsToSyntheticProperty.set(transformer.copyAnnotationsToSyntheticProperty) } - - internal fun toTransformer(): Transformer { - TODO() - } } /** @@ -337,7 +358,7 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa */ abstract class MarkAnnotationSpec @Inject constructor(private val objects: ObjectFactory) { /** - * 注解类信息 + * The mark annotation's class info. */ abstract val classInfo: Property @@ -345,30 +366,34 @@ abstract class MarkAnnotationSpec @Inject constructor(private val objects: Objec classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } - fun classInfo(block: ClassInfoSpec.() -> Unit) { - classInfo(Action(block)) - } - /** * 用于标记生成函数需要使用的基础函数名的注解属性名。 + * + * Default value is `"baseName"` */ val baseNameProperty: Property = objects.property(String::class.java).convention("baseName") /** * 用于标记生成函数需要使用的基础函数名之后的后缀的注解属性名。 + * + * Default value is `"suffix"` */ val suffixProperty: Property = objects.property(String::class.java).convention("suffix") /** * 用于标记生成函数是否需要转化为 property 类型的注解属性名。 + * + * Default value is `"asProperty"` */ val asPropertyProperty: Property = objects.property(String::class.java).convention("asProperty") /** * 当 [suffixProperty] 不存在时使用的默认后缀 + * + * Default value is `""` */ val defaultSuffix: Property = objects.property(String::class.java).convention("") @@ -381,7 +406,7 @@ abstract class MarkAnnotationSpec @Inject constructor(private val objects: Objec fun from(markAnnotation: MarkAnnotation) { classInfo { - from(markAnnotation.classInfo) + it.from(markAnnotation.classInfo) } baseNameProperty.set(markAnnotation.baseNameProperty) suffixProperty.set(markAnnotation.suffixProperty) @@ -397,7 +422,15 @@ abstract class MarkAnnotationSpec @Inject constructor(private val objects: Objec interface ClassInfoSpec { val packageName: Property val className: Property + + /** + * Default value is `false` + */ val local: Property + + /** + * Default value is `false` + */ val nullable: Property fun from(classInfo: ClassInfo) { @@ -425,22 +458,77 @@ abstract class IncludeAnnotationSpec @Inject constructor(private val objects: Ob classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } - fun classInfo(block: ClassInfoSpec.() -> Unit) { - classInfo(Action(block)) - } - + /** + * Default value is `false` + */ abstract val repeatable: Property + /** + * Default value is `false` + */ abstract val includeProperty: Property fun from(includeAnnotation: IncludeAnnotation) { classInfo { - from(includeAnnotation.classInfo) + it.from(includeAnnotation.classInfo) } repeatable.set(includeAnnotation.repeatable) includeProperty.set(includeAnnotation.includeProperty) } } +@OptIn(InternalSuspendTransformConstructorApi::class) +internal fun TransformerSpec.toTransformer(): Transformer { + return Transformer( + markAnnotation = markAnnotation.get().toMarkAnnotation(), + transformFunctionInfo = transformFunctionInfo.get().toFunctionInfo(), + transformReturnType = transformReturnType.orNull?.toClassInfo(), + transformReturnTypeGeneric = transformReturnTypeGeneric.getOrElse(false), + originFunctionIncludeAnnotations = originFunctionIncludeAnnotations.map { it.toIncludeAnnotation() }.toList(), + syntheticFunctionIncludeAnnotations = syntheticFunctionIncludeAnnotations.map { it.toIncludeAnnotation() }.toList(), + copyAnnotationsToSyntheticFunction = copyAnnotationsToSyntheticFunction.getOrElse(false), + copyAnnotationExcludes = copyAnnotationExcludes.map { it.toClassInfo() }.toList(), + copyAnnotationsToSyntheticProperty = copyAnnotationsToSyntheticProperty.get() + ) +} + +@OptIn(InternalSuspendTransformConstructorApi::class) +internal fun MarkAnnotationSpec.toMarkAnnotation(): MarkAnnotation { + return MarkAnnotation( + classInfo = classInfo.get().toClassInfo(), + baseNameProperty = baseNameProperty.get(), + suffixProperty = suffixProperty.get(), + asPropertyProperty = asPropertyProperty.get(), + defaultSuffix = defaultSuffix.get(), + defaultAsProperty = defaultAsProperty.get() + ) +} + +@OptIn(InternalSuspendTransformConstructorApi::class) +internal fun ClassInfoSpec.toClassInfo(): ClassInfo { + return ClassInfo( + packageName = packageName.get(), + className = className.get(), + local = local.getOrElse(false), + nullable = nullable.getOrElse(false) + ) +} + +@OptIn(InternalSuspendTransformConstructorApi::class) +internal fun FunctionInfoSpec.toFunctionInfo(): FunctionInfo { + return FunctionInfo( + packageName = packageName.get(), + functionName = functionName.get() + ) +} + +@OptIn(InternalSuspendTransformConstructorApi::class) +internal fun IncludeAnnotationSpec.toIncludeAnnotation(): IncludeAnnotation { + return IncludeAnnotation( + classInfo = classInfo.get().toClassInfo(), + repeatable = repeatable.getOrElse(false), + includeProperty = includeProperty.getOrElse(false) + ) +} private inline fun ObjectFactory.newInstance(): T = newInstance(T::class.java) diff --git a/settings.gradle.kts b/settings.gradle.kts index 5667b82..ffeb6f5 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -23,6 +23,7 @@ dependencyResolutionManagement { include(":compiler:suspend-transform-plugin") include(":compiler:suspend-transform-plugin-cli") +include(":compiler:suspend-transform-plugin-deprecated-configuration") include(":compiler:suspend-transform-plugin-configuration") include(":compiler:suspend-transform-plugin-embeddable") diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index aa724ab..85e7a74 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -11,7 +11,7 @@ plugins { `java-library` kotlin("jvm") - id("love.forte.plugin.suspend-transform") version "2.1.20-0.11.1" + id("love.forte.plugin.suspend-transform") version "2.1.20-0.12.0" // id("suspend-transform.jvm-maven-publish") // id(project(":suspend-transform-plugin-gradle")) } @@ -40,10 +40,7 @@ dependencies { suspendTransform { - // transformers { - // useJvmDefault() - // - // } + enabled = true } tasks.withType { From caa480f171ddc0e047891a096fd4ec6464824201 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Tue, 15 Apr 2025 17:40:03 +0800 Subject: [PATCH 06/21] Refactor suspend transform configuration and tests Reorganized plugin configuration by refactoring `SuspendTransformConfiguration` to improve modularity and readability. The README_CN was updated for enhanced documentation and clarity. --- README.md | 1006 +++++++++++------ README_CN.md | 999 ++++++++-------- .../SuspendTransformConfiguration.kt | 26 +- .../fir/SuspendTransformFirTransformer.kt | 27 +- .../gradle/SuspendTransformGradleExtension.kt | 10 +- .../gradle/SuspendTransformGradlePlugin.kt | 181 ++- .../gradle/SuspendTransformPluginExtension.kt | 187 ++- settings.gradle.kts | 2 +- tests/build.gradle.kts | 3 + tests/test-js/build.gradle.kts | 65 +- tests/test-jvm/build.gradle.kts | 69 +- tests/test-kmp/build.gradle.kts | 90 +- .../src/commonMain/kotlin/example/MyClass.kt | 9 + .../src/jsMain/kotlin/example/MyClass.js.kt | 4 +- 14 files changed, 1699 insertions(+), 979 deletions(-) create mode 100644 tests/build.gradle.kts diff --git a/README.md b/README.md index a8418d6..872bf27 100644 --- a/README.md +++ b/README.md @@ -152,9 +152,9 @@ If the version is less than or equal to `0.9.0`, you can refer to this compariso _build.gradle.kts_ -```kotlin +```Kotlin plugins { - id("org.jetbrains.kotlin.jvm") version "$KOTLIN_VERSION" // or js? or multiplatform? + kotlin("jvm") version "$KOTLIN_VERSION" // or multiplatform id("love.forte.plugin.suspend-transform") version "$PLUGIN_VERSION" // other... } @@ -162,56 +162,8 @@ plugins { // other... // config it. -suspendTransform { - enabled = true // default: true - includeRuntime = true // default: true - includeAnnotation = true // default: true - // Note: If you disable includeAnnotation, you need to customise the `targetMarker` or set it to `null`. - // see also: https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin/pull/73 - // targetMarker = ... - - /* - * Use both `useJvmDefault` and `useJsDefault`. - * Need to include the runtime and annotation. - */ - // useDefault() - - /* - * Use the default configuration for JVM platform, - * Equivalent: - * addJvmTransformers( - * SuspendTransformConfiguration.jvmBlockingTransformer, - * SuspendTransformConfiguration.jvmAsyncTransformer, - * ) - * - * Need to include the runtime and annotation. - */ - useJvmDefault() - - // or custom by yourself - jvm { - // ... - } - // or - addJvmTransformers(...) - - /* - * Use the default configuration for JS platform, - * Equivalent: - * addJvmTransformers( - * SuspendTransformConfiguration.jsPromiseTransformer, - * ) - * - * Need to include the runtime and annotation. - */ - useJsDefault() - - // or custom by yourself - js { - // ... - } - // or - addJsTransformers(...) +suspendTransformPlugin { + // Config the SuspendTransformPluginExtension ... } ``` @@ -219,7 +171,7 @@ suspendTransform { _build.gradle.kts_ -```kotlin +```Kotlin buildscript { repositories { mavenCentral() @@ -231,7 +183,7 @@ buildscript { } plugins { - id("org.jetbrains.kotlin.jvm") // or js? or multiplatform? + id("org.jetbrains.kotlin.jvm") // or multiplatform? id("love.forte.plugin.suspend-transform") // other... } @@ -239,58 +191,663 @@ plugins { // other... // config it. -suspendTransform { - enabled = true // default: true - includeRuntime = true // default: true - includeAnnotation = true // default: true - - /* - * Use both `useJvmDefault` and `useJsDefault`. - * Need to include the runtime and annotation. - */ - // useDefault() - - /* - * Use the default configuration for JVM platform, - * Equivalent: - * addJvmTransformers( - * SuspendTransformConfiguration.jvmBlockingTransformer, - * SuspendTransformConfiguration.jvmAsyncTransformer, - * ) - * - * Need to include the runtime and annotation. - */ - useJvmDefault() - - // or custom by yourself - jvm { - // ... +suspendTransformPlugin { + // Config the SuspendTransformPluginExtension ... +} +``` + +## Config the extension + +### Enabled + +Enable the Kotlin compiler plugin. +Default value is `true`. + +```Kotlin +suspendTransformPlugin { + enabled = true +} +``` + +### Include the default annotations and runtime + +If you wish to use the Transformer we provide, then you may need to add the `annotation` and `runtime` dependencies. + +You can add them automatically via configuration. + +```Kotlin +suspendTransformPlugin { + // include the annotation + // Default is `true` + includeAnnotation = true + // The default can be left unconfigured and the default values are used exclusively. + annotationDependency { + // Default is `compileOnly` + configurationName = "compileOnly" + // Default is same as the plugin version + version = "" + } + + // Include the runtime + // Default is `true` + includeRuntime = true + // The default can be left unconfigured and the default values are used exclusively. + runtimeDependency { + // Default is `implementation` + configurationName = "implementation" + // Default is same as the plugin version + version = "" } - // or - addJvmTransformers(...) - - /* - * Use the default configuration for JS platform, - * Equivalent: - * addJvmTransformers( - * SuspendTransformConfiguration.jsPromiseTransformer, - * ) - * - * Need to include the runtime and annotation. - */ - useJsDefault() - - // or custom by yourself - js { +} +``` + +You can also disable them and add dependencies manually. + +```Kotlin +plugin { + kotlin("jvm") version "..." // Take the Kotlin/JVM as an example + id("love.forte.plugin.suspend-transform") version "2.1.20-0.12.0" +} + +dependencies { + // annotation + compileOnly("love.forte.plugin.suspend-transform:suspend-transform-annotation:") + // runtime + implementation("love.forte.plugin.suspend-transform:suspend-transform-runtime:") +} + +suspendTransformPlugin { + // Disable them + includeAnnotation = false + includeRuntime = false +} +``` + +### Add transformers + +`Transformer` is the type used to describe how the suspend function is transformed. +You need to add some `Transformer`s to make the compiler plugin actually work. + + +```Kotlin +suspendTransformPlugin { + // Config the transformers + transformers { + add(TargetPlatform.JVM) { // this: TransformerSpec + // Config the TransformerSpec... + } + + addJvm { // this: TransformerSpec + // Config the TransformerSpec... + } + + // Use a default transformer we provided from `SuspendTransformConfigurations` + add(TargetPlatform.JVM, SuspendTransformConfigurations.jvmBlockingTransformer) + + addJvm { // this: TransformerSpec + // Modify and adjust from a Transformer + from(SuspendTransformConfigurations.jvmBlockingTransformer) + // Further configurations... + } + } +} +``` + +#### Add the default transformers + +First, we provide some simple and commonly used implementations. +You can use them simply and quickly through configuration. + +> [!note] +> The default `Transformer`s depend on the `annotation` and `runtime` we provide. +> Make sure you include them before using it. + +**JVM blocking** + +```Kotlin +suspendTransformPlugin { + transformers { + // The 1st way: + addJvmBlocking() + + // Or the 2ed way: + addJvm(SuspendTransformConfigurations.jvmBlockingTransformer) + // Or use transformers.add(TargetPlatform.JVM, jvmBlockingTransformer), etc. + } +} +``` + +`JvmBlocking` allows you to mark `@JvmBlocking` on the suspend function, +which generates a `xxxBlocking` function. + +```Kotlin +class Cat { + @JvmBLocking + suspend fun meow() { // ... } - // or - addJsTransformers(...) + + // Generated: + fun meowBlocking() { + `$runInBlocking$` { meow() } + } } ``` -## Cautions +The `$runInBlocking$` based on `kotlinx.coroutines.runBlocking` 。 + +**JVM Async** + +```Kotlin +suspendTransformPlugin { + transformers { + // The 1st way: + addJvmAsync() + + // Or the 2ed way: + addJvm(SuspendTransformConfigurations.jvmAsyncTransformer) + // Or use transformers.add(TargetPlatform.JVM, jvmAsyncTransformer), etc. + } +} +``` + +`JvmAsync` allows you to mark `@JvmAsync` on the suspend function, +which generates a `xxxAsync` function. + +```Kotlin +class Cat { + @JvmBLocking + suspend fun meow(): String = "Meow!" + + // Generated: + fun meowAsync(): CompletableFuture { + `$runInAsync$`(block = { meow() }, scope = this as? CoroutineScope) + } +} +``` + +The `block` is the original suspend function that needs to be executed +and the `scope` is the `CoroutineScope` that will be used. + +If the current scope is a `CoroutineScope`, it takes precedence over itself. +Otherwise, `GlobalScope` is used internally. + +Why use `GlobalScope`: When using an internal scope, this scope qualifies: +1. global. +2. is never visible externally, so it is not artificially closed. +3. is not intended for IO and does not require a custom dispatcher. + +We believe `GlobalScope` meets these conditions. + +_Have a different point? Feel free to create issue!_ + +**JS Promise** + +```Kotlin +suspendTransformPlugin { + transformers { + // The 1st way: + addJsPromise() + + // Or the 2ed way: + addJs(SuspendTransformConfigurations.jsPromiseTransformer) + // Or use transformers.add(TargetPlatform.JS, jsPromiseTransformer), etc. + } +} +``` + +```Kotlin +class Cat { + @JsPromise + suspend fun meow(): String = "Meow!" + + // Generated: + fun meowAsync(): Promise { + `$runInAsync$`(block = { meow() }, scope = this as? CoroutineScope) + } +} +``` + +The `block` is the original suspend function that needs to be executed +and the `scope` is the `CoroutineScope` that will be used. + +#### Use the defaults + +The `addJvmBlocking()` and `addJvmAsync()` may be combined as `useJvmDefault()`. + +```Kotlin +suspendTransformPlugin { + transformers { + // Includes addJvmBlocking() and addJvmAsync() + useJvmDefault() + } +} +``` + +The `addJsPromise()` may be combined as `useJsDefault()`. + +```Kotlin +suspendTransformPlugin { + transformers { + // Includes addJsPromise() + useJsDefault() + } +} +``` + +The `useJvmDefault()` and `useJsDefault()` may be combined as `useDefault()`. + +```Kotlin +suspendTransformPlugin { + transformers { + // Includes useJvmDefault() and useJsDefault() + useDefault() + } +} +``` + +#### Use custom transformers + +You can also customize your `Transformer` if the default `Transformer`s don't meet your needs, +e.g. if you want to fully implement blocking logic and don't want to use `kotlinx.coroutines.runBlocking`. + +> A fully customized implementation of JVM Blocking/Async Transformers reference: +> https://github.com/simple-robot/simpler-robot/blob/v4-main/simbot-commons/simbot-common-suspend-runner/src/jvmMain/kotlin/love/forte/simbot/suspendrunner/BlockingRunner.kt + +```Kotlin +suspendTransformPlugin { + // If customized, then you may not use the annotation and runtime we provide. + includeAnnotation = false + includeRuntime = false + + transformer { + // See below for details + } +} +``` + +As an example, you intend to create a custom annotation: `@JBlock`, +which is executed via the function `inBlock` when the suspend function uses this annotation. + +```Kotlin +// Your annotation +annotation class JBlock(...) +// Your top-level transform function +fun inBlock(block: suspend () -> T): T { + TODO("Your impl") +} +``` + +First, let's agree that the following properties should be included in the annotation: + +- `baseName`: The generated function's **base name**. + When the value of this property is empty, the name of the original function is used by default. + ```Kotlin + @JBlock(baseName = "") + suspend fun meow1() // Generated function name: ${baseName}${suffix} -> meow1Blocking + + @JBlock(baseName = "meow999") + suspend fun meow2() // Generated function name: ${baseName}${suffix} -> meow999Blocking + ``` +- `suffix`: The generated function name's suffix. +- `asProperty`: Make the generated function a property. + Can be used in cases where the original function has no arguments. + ```Kotlin + @JBlock + suspend fun value(): Int + + // Generated: + val valueBlocking: Int + get() = inBlock { value() } + ``` + +So your annotation should look like this: + +```Kotlin +annotation class JBlock( + val baseName: String = "", + val suffix: String = "Blocking", + val asProperty: Boolean = false +) +``` + +The configuration: + +```Kotlin +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + addJvm { + markAnnotation { + // Your annotation class's info. + classInfo { + packageName = "com.example" + className = "JBlock" + } + + // The property names. + baseNameProperty = "baseName" // Default is `baseName` + suffixProperty = "suffix" // Default is `suffix` + asPropertyProperty = "asProperty" // Default is `asProperty` + + // The compiler plugin doesn't seem to be able to get the default values for annotations + // (or I haven't found a way to do it yet). + // So here you need to configure the default value of the annotation, which needs to be consistent with your definition. + defaultSuffix = "Blocking" + defaultAsProperty = false // For the same reasons as above. + } + } + } +} +``` + +However, the property names do not have to be the same as these three, as long as the function and type correspond. So we can adjust it like this: + +```Kotlin +annotation class JBlock( + val myBaseName: String = "", + val mySuffix: String = "Blocking", + val myAsProperty: Boolean = false +) +``` + +The configuration: + +```Kotlin +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + addJvm { + markAnnotation { + // Your annotation class's info. + classInfo { + packageName = "com.example" + className = "JBlock" + } + + // The property names. + baseNameProperty = "myBaseName" + suffixProperty = "mySuffix" + asPropertyProperty = "myAsProperty" + + // The default values. + defaultSuffix = "Blocking" + defaultAsProperty = false + } + } + } +} +``` + +Then configure the information for your transform function. + +```Kotlin +// Your top-level transform function +fun inBlock(block: suspend () -> T): T { + TODO("Your impl") +} +``` + +The configuration: + +```Kotlin +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + addJvm { + markAnnotation { + // ... + } + + // The function info + transformFunctionInfo { + packageName = "com.example" + functionName = "inBlock" + } + + // The return type configs + + // The return type. + // If `null` it means the same type as the original function return. + // If you return a specific type (e.g. `CompletableFuture`) you need to configure that type. + // + // Default value is null. + transformReturnType = null + + // Whether the returned type contains a generic type that is of the same type as the original function. + // e.g. CompletableFuture, The `T` represents the value returned by the original function. + // In this case it is set to `true`. + // + // Set to `false` if the return type is of a specific type, + // but without a generic (a rare case, an example: `Job`). + // Valid if `transformReturnType` is not null. + // + // Default value is false. + transformReturnTypeGeneric = false + } + } +} +``` + +Finally, in the process of generating the function, we allow some manipulation of the annotations. +- Copy annotations from original function to generated synthetic function. + - exclude some annotations from copying. +- Include some annotations to original function. +- Include some annotations to generated synthetic function. + +Now let's assume: +- We want to add `@JvmSynthetic` to the original function. +- We want to add `@JApi` to the generated synthetic function. +- Copy the annotations without copying `@JvmSynthetic` (exclude `@JvmSynthetic`). + +The `@JApi`: + +```Kotlin +@RequiresOptIn(message = "Api for Java", level = RequiresOptIn.Level.WARNING) +@Retention(AnnotationRetention.BINARY) +annotation class JApi +``` + +The configuration: + +```Kotlin +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + addJvm { + markAnnotation { + // ... + } + transformFunctionInfo { + // ... + } + + // Enabling annotated copies + // Default is FALSE + copyAnnotationsToSyntheticFunction = true + // If the generated synthetic function is property (asProperty=true), + // Copy annotations to the property. + // Otherwise, copy to the property's getter function. + // Default is FALSE + copyAnnotationsToSyntheticProperty = true + + // Include `@kotlin.jvm.JvmSynthetic` to original function. + addOriginFunctionIncludeAnnotation { + // Some common types are defined in SuspendTransformConfigurations. See below. + classInfo { + packageName = "kotlin.jvm" + className = "JvmSynthetic" + } + // Default is false + repeatable = false + } + + // Include `@com.example.JApi` to generated synthetic function + addSyntheticFunctionIncludeAnnotation { + classInfo { + packageName = "com.example" + className = "JApi" + } + // Marks whether this annotation supports being added to a property. + // Default is FALSE + includeProperty = true + } + + // Exclude `@kotlin.jvm.JvmSynthetic` when copying. + addCopyAnnotationExclude { + // SuspendTransformConfigurations provides a small number of + // common annotations or type definitions that can be used directly. + from(SuspendTransformConfigurations.jvmSyntheticClassInfo) + } + } + } +} +``` + +The full example: + +Code: + +```Kotlin +annotation class JBlock( + val myBaseName: String = "", + val mySuffix: String = "Blocking", + val myAsProperty: Boolean = false +) + +@RequiresOptIn(message = "Api for Java", level = RequiresOptIn.Level.WARNING) +@Retention(AnnotationRetention.BINARY) +annotation class JApi + +fun inBlock(block: suspend () -> T): T { + TODO("Your impl") +} +``` + +Configuration: + +```Kotlin +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + addJvm { + markAnnotation { + classInfo { + packageName = "com.example" + className = "JBlock" + } + + baseNameProperty = "myBaseName" + suffixProperty = "mySuffix" + asPropertyProperty = "myAsProperty" + + defaultSuffix = "Blocking" + defaultAsProperty = false + } + + transformFunctionInfo { + packageName = "com.example" + functionName = "inBlock" + } + + copyAnnotationsToSyntheticFunction = true + copyAnnotationsToSyntheticProperty = true + + addOriginFunctionIncludeAnnotation { + classInfo { + from(SuspendTransformConfigurations.jvmSyntheticClassInfo) + } + repeatable = false + } + + addSyntheticFunctionIncludeAnnotation { + classInfo { + packageName = "com.example" + className = "JApi" + } + includeProperty = true + } + + addCopyAnnotationExclude { + from(SuspendTransformConfigurations.jvmSyntheticClassInfo) + } + } + } +} +``` + +> [!note] +> Since the property name is configurable, the same annotation can be reused on multiple transformers. +> Annotation: +> ```Kotlin +> annotation class JTrans( +> val blockingBaseName: String = "", +> val blockingSuffix: String = "Blocking", +> val blockingAsProperty: Boolean = false, +> +> val asyncBaseName: String = "", +> val asyncSuffix: String = "Async", +> val asyncAsProperty: Boolean = false +> ) +> ``` +> Configuration: +> ```Kotlin +> suspendTransformPlugin { +> includeAnnotation = false +> includeRuntime = false +> transformers { +> // For blocking +> addJvm { +> markAnnotation { +> classInfo { +> packageName = "com.example" +> className = "JTrans" +> } +> baseNameProperty = "blockingBaseName" +> suffixProperty = "blockingSuffix" +> asPropertyProperty = "blockingAsProperty" +> defaultSuffix = "Blocking" +> defaultAsProperty = false +> } +> +> transformFunctionInfo { +> packageName = "com.example" +> functionName = "inBlock" +> } +> +> // other config... +> } +> +> // For async +> addJvm { +> markAnnotation { +> classInfo { +> packageName = "com.example" +> className = "JTrans" +> } +> baseNameProperty = "asyncBaseName" +> suffixProperty = "asyncSuffix" +> asPropertyProperty = "asyncAsProperty" +> defaultSuffix = "Async" +> defaultAsProperty = false +> } +> +> transformFunctionInfo { +> packageName = "com.example" +> functionName = "inAsync" +> } +> } +> } +>} +> ``` + +## Cautions ### Gradle JVM **Gradle JVM** must be JDK11+ @@ -299,9 +856,6 @@ suspendTransform { K2 is supported since `v0.7.0`. -> [!warning] -> In experiments. - ### JsExport If you want to use `@JsExport` with default configuration in JS, @@ -311,18 +865,18 @@ _build.gradle.kts_ ```kotlin plugins { - ... + // ... } -suspendTransform { - addJsTransformers( - SuspendTransformConfiguration.jsPromiseTransformer.copy( - copyAnnotationExcludes = listOf( - // The generated function does not include `@JsExport.Ignore`. - ClassInfo("kotlin.js", "JsExport.Ignore") - ) - ) - ) +suspendTransformPlugin { + transformers { + addJsPromise { + addCopyAnnotationExclude { + // The generated function does not include `@JsExport.Ignore`. + from(kotlinJsExportIgnoreClassInfo) + } + } + } } ``` @@ -490,234 +1044,6 @@ class Bar { } ``` -## Customization - -```kotlin -plugin { - id("love.forte.plugin.suspend-transform") version "$VERSION" -} - -suspendTransform { - // enabled suspend transform plugin - enabled = true - // include 'love.forte.plugin.suspend-transform:suspend-transform-runtime' to the runtime environment - includeRuntime = true - // the configuration name for including 'love.forte.plugin.suspend-transform:suspend-transform-runtime' - runtimeConfigurationName = "implementation" - - val customJvmTransformer = Transformer( - // mark annotation info, e.g. `@JvmBlocking` - markAnnotation = MarkAnnotation( - classInfo = ClassInfo("love.forte.plugin.suspendtrans.annotation", "JvmBlocking"), // class info for this annotation - baseNameProperty = "baseName", // The property used to represent the 'base name' in the annotation, e.g. `@JvmBlocking(baseName = ...)` - suffixProperty = "suffix", // The property used to represent the 'suffix' in the annotation, e.g. `@JvmBlocking(suffix = ...)` - asPropertyProperty = "asProperty", // The property used to represent the 'asProperty' in the annotation, e.g. `@JvmBlocking(asProperty = true|false)` - defaultSuffix = "Blocking", // Default value used when property 'suffix' (the value of suffixProperty) does not exist (when not specified by the user) (the compiler plugin cannot detect property defaults directly, so the default value must be specified from here) - // e.g. @JvmBlocking(suffix = "Abc"), the suffix is 'Abc', but `@JvmBlocking()`, the suffix is null in compiler plugin, so use the default suffix value. - defaultAsProperty = false, // Default value used when property 'suffix' (the value of suffixProperty) does not exist (Similar to defaultSuffix) - ), - // the transform function, e.g. - // 👇 `love.forte.plugin.suspendtrans.runtime.$runInBlocking$` - // it will be like - // ``` - // @JvmBlocking suspend fun runXxx() { ... } - // fun runXxxBlocking() = `$runInBlocking$` { runXxx() /* suspend */ } // generated function - // ``` - transformFunctionInfo = FunctionInfo( - packageName = "love.forte.plugin.suspendtrans.runtime", - className = null, // null if top-level function - functionName = "\$runInBlocking\$" - ), - transformReturnType = null, // return type, or null if return the return type of origin function, e.g. `ClassInfo("java.util.concurrent", "CompletableFuture")` - transformReturnTypeGeneric = false, // if you return like `CompletableFuture`, make it `true` - originFunctionIncludeAnnotations = listOf(IncludeAnnotation(ClassInfo("kotlin.jvm", "JvmSynthetic"))), // include into origin function - copyAnnotationsToSyntheticFunction = true, - copyAnnotationExcludes = listOf(ClassInfo("kotlin.jvm", "JvmSynthetic")), // do not copy from origin function - syntheticFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmApi4JAnnotationClassInfo)) // include into synthetic function - ) - - addJvmTransformers( - customJvmTransformer, ... - ) - - // or addJsTransformers(...) - -} -``` - -For example, you want to use a single annotation to do the work of `@JvmAsync`, `@JvmBlocking`, and `@JsPromise`: - -```kotlin -// Your JVM transform functions -// e.g. com.example.Transforms.jvm.kt - -@Deprecated("Just used by compiler", level = DeprecationLevel.HIDDEN) -fun runInBlocking(block: suspend () -> T): T { - // run the `block` in blocking - runBlocking { block() } -} - -@Deprecated("Just used by compiler", level = DeprecationLevel.HIDDEN) -public fun runInAsync(block: suspend () -> T, scope: CoroutineScope? = null): CompletableFuture { - // run the `block` in async - val scope0 = scope ?: GlobalScope - return scope0.future { block() } - - /* - * the `scope` is the `block`'s container: - * ``` - * interface Container { - * @JvmAsync - * suspend fun run() - * 👇 compiled - * - * fun runAsync() = runInAsync(block = { run() }, scope = this as? CoroutineScope) - * } - * ``` - */ -} - -// Your JS transform function -// e.g. com.example.Transforms.js.kt -@Deprecated("Just used by compiler", level = DeprecationLevel.HIDDEN) -fun runInPromise(block: suspend () -> T, scope: CoroutineScope? = null): T { - val scope0 = scope ?: GlobalScope - return scope0.promise { block() } -} -``` - -Create your annotation: - -```kotlin -// Your single annotation -@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) -@Retention(AnnotationRetention.BINARY) -public annotation class SuspendTrans( - val blockingBaseName: String = "", - val blockingSuffix: String = "Blocking", - val blockingAsProperty: Boolean = false, - - val asyncBaseName: String = "", - val asyncSuffix: String = "Async", - val asyncAsProperty: Boolean = false, - - val jsPromiseBaseName: String = "", - val jsPromiseSuffix: String = "Async", - val jsPromiseAsProperty: Boolean = false, -) -``` - -Then, config your build script: - -```kotlin -// The annotation type -val suspendTransMarkAnnotationClassInfo = ClassInfo("love.forte.simbot.suspendrunner", "SuspendTrans") - -// The mark annotations -val jvmSuspendTransMarkAnnotationForBlocking = MarkAnnotation( - suspendTransMarkAnnotationClassInfo, - baseNameProperty = "blockingBaseName", - suffixProperty = "blockingSuffix", - asPropertyProperty = "blockingAsProperty", - defaultSuffix = "Blocking", -) -val jvmSuspendTransMarkAnnotationForAsync = MarkAnnotation( - suspendTransMarkAnnotationClassInfo, - baseNameProperty = "asyncBaseName", - suffixProperty = "asyncSuffix", - asPropertyProperty = "asyncAsProperty", - defaultSuffix = "Async", -) -val jsSuspendTransMarkAnnotationForPromise = MarkAnnotation( - suspendTransMarkAnnotationClassInfo, - baseNameProperty = "jsPromiseBaseName", - suffixProperty = "jsPromiseSuffix", - asPropertyProperty = "jsPromiseAsProperty", - defaultSuffix = "Async", -) - -// The transform functions -val jvmBlockingFunction = FunctionInfo("com.example", null, "runInBlocking") -val jvmAsyncFunction = FunctionInfo("com.example", null, "runInAsync") -val jsPromiseFunction = FunctionInfo("com.example", null, "runInPromise") - -// The transformers -val suspendTransTransformerForJvmBlocking: Transformer = Transformer( - markAnnotation = jvmSuspendTransMarkAnnotationForBlocking, - transformFunctionInfo = jvmBlockingFunction, - transformReturnType = null, // same as origin function - transformReturnTypeGeneric = false, - // include @JvmSynthetic into origin function - originFunctionIncludeAnnotations = listOf( - SuspendTransformConfiguration.jvmSyntheticClassInfo, - ), - copyAnnotationsToSyntheticFunction = true, - // excludes: @JvmSynthetic, @OptIn, @SuspendTrans - copyAnnotationExcludes = listOf( - SuspendTransformConfiguration.jvmSyntheticClassInfo, - SuspendTransformConfiguration.kotlinOptInClassInfo, - suspendTransMarkAnnotationClassInfo, - ), - // Include into synthetic function's annotations - syntheticFunctionIncludeAnnotations = listOf() -) - -val suspendTransTransformerForJvmAsync: Transformer = Transformer( - markAnnotation = jvmSuspendTransMarkAnnotationForAsync, - transformFunctionInfo = jvmAsyncFunction, - transformReturnType = ClassInfo("java.util.concurrent", "CompletableFuture"), - transformReturnTypeGeneric = true, // Future's generic type is origin function's return type. - // include @JvmSynthetic into origin function - originFunctionIncludeAnnotations = listOf( - SuspendTransformConfiguration.jvmSyntheticClassInfo, - ), - copyAnnotationsToSyntheticFunction = true, - // excludes: @JvmSynthetic, @OptIn, @SuspendTrans - copyAnnotationExcludes = listOf( - SuspendTransformConfiguration.jvmSyntheticClassInfo, - suspendTransMarkAnnotationClassInfo, - SuspendTransformConfiguration.kotlinOptInClassInfo, - ), - // Include into synthetic function's annotations - syntheticFunctionIncludeAnnotations = listOf() -) - -val suspendTransTransformerForJsPromise: Transformer = Transformer( - markAnnotation = jsSuspendTransMarkAnnotationForPromise, - transformFunctionInfo = jsPromiseFunction, - transformReturnType = ClassInfo("kotlin.js", "Promise"), - transformReturnTypeGeneric = true, // Promise's generic type is origin function's return type. - originFunctionIncludeAnnotations = listOf(), - copyAnnotationsToSyntheticFunction = true, - // excludes: @OptIn, @SuspendTrans - copyAnnotationExcludes = listOf( - SuspendTransformConfiguration.kotlinOptInClassInfo, - suspendTransMarkAnnotationClassInfo, - ), - syntheticFunctionIncludeAnnotations = listOf() -) - -// The above section can also be considered to be defined in `buildSrc`. - -suspendTransform { - // disable, use the runtime and the annotation by yourself - includeRuntime = false - includeAnnotation = false - // Note: If you disable includeAnnotation, you need to customise the `targetMarker` or set it to `null`. - // see also: https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin/pull/73 - targetMarker = null // or customise - - addJvmTransformers( - suspendTransTransformerForJvmBlocking, - suspendTransTransformerForJvmAsync - ) - addJsTransformers( - suspendTransTransformerForJsPromise - ) -} -``` - - ## Use Cases - [Simple Robot Frameworks](https://github.com/simple-robot/simpler-robot) (Fully customized) diff --git a/README_CN.md b/README_CN.md index 6f3a35b..e992836 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,16 +1,16 @@ -# Kotlin suspend transform compiler plugin -[![Maven Central](https://img.shields.io/maven-central/v/love.forte.plugin.suspend-transform/suspend-transform-plugin)](https://repo1.maven.org/maven2/love/forte/plugin/suspend-transform/suspend-transform-plugin/) +# Kotlin suspend transform 编译器插件 +[![Maven Central](https://img.shields.io/maven-central/v/love.forte.plugin.suspend-transform/suspend-transform-plugin)](https://repo1.maven.org/maven2/love/forte/plugin/suspend-transform/suspend-transform-plugin/) [![Gradle Plugin Portal](https://img.shields.io/gradle-plugin-portal/v/love.forte.plugin.suspend-transform)](https://plugins.gradle.org/plugin/love.forte.plugin.suspend-transform) -封面 +封面图 [GitHub](https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin) | [Gitee](https://gitee.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin) -[English](README.md) | **简体中文** +**English** | [简体中文](README_CN.md) -## 简介 +## 概述 -用于为Kotlin挂起函数自动生成平台兼容函数的Kotlin编译器插件。 +用于为挂起函数生成平台兼容函数的 Kotlin 编译器插件。 ### JVM @@ -29,21 +29,22 @@ class Foo { ```kotlin class Foo { - // 对Java隐藏 + // 对 Java 隐藏 @JvmSynthetic suspend fun waitAndGet(): String { delay(5) return "Hello" } - @Api4J // RequiresOptIn 注解, 向Kotlin开发者提供警告 - fun waitAndGetBlocking(): String = runInBlocking { waitAndGet() } // 'runInBlocking' 来自于插件提供的运行时依赖 + @Api4J // 需要显式启用的注解,向 Kotlin 提供警告 + fun waitAndGetBlocking(): String = runInBlocking { waitAndGet() } // 'runInBlocking' 来自插件提供的运行时 - @Api4J // RequiresOptIn 注解, 向Kotlin开发者提供警告 - fun waitAndGetAsync(): CompletableFuture = runInAsync { waitAndGet() } // 'runInAsync' 来自于插件提供的运行时依赖 + @Api4J // 需要显式启用的注解,向 Kotlin 提供警告 + fun waitAndGetAsync(): CompletableFuture = runInAsync { waitAndGet() } // 'runInAsync' 来自插件提供的运行时 } ``` ### JS + ```kotlin class Foo { @JsPromise @@ -62,19 +63,19 @@ class Foo { delay(5) return "Hello" } - @Api4Js // RequiresOptIn 注解, 向Kotlin开发者提供警告 - fun waitAndGetAsync(): Promise = runInAsync { waitAndGet() } // 'runInAsync' 来自于插件提供的运行时依赖 + @Api4Js // 需要显式启用的注解,向 Kotlin 提供警告 + fun waitAndGetAsync(): Promise = runInAsync { waitAndGet() } // 'runInAsync' 来自插件提供的运行时 } ``` -> ~~JS 目标平台暂不支持。原因参考: [KT-53993](https://youtrack.jetbrains.com/issue/KT-53993)~~ -> -> JS 平台从 `v0.6.0` 版本开始得到支持。 参考 [KT-53993](https://youtrack.jetbrains.com/issue/KT-53993) 了解过程, 以及从 [#39](https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin/pull/39) 查阅制胜一击! +> ~~JS 平台目标暂未支持。参见:[KT-53993](https://youtrack.jetbrains.com/issue/KT-53993)~~ +> +> 自 0.6.0 版本起已支持 JS!进展见 [KT-53993](https://youtrack.jetbrains.com/issue/KT-53993),最终实现见 [#39](https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin/pull/39)! ### WasmJS > [!warning] -> 从 `v0.6.0` 开始支持,实验中,不成熟、不稳定。 +> 自 `v0.6.0` 起处于实验阶段,不成熟且不稳定 ```kotlin class Foo { @@ -85,11 +86,12 @@ class Foo { } } -// 一些由**你**自定义的函数或类型... -// 它们不包含在 runtime 中。由于在 WasmJS 中,对于各种类型的使用会有很多限制, -// 因此我还不清楚如何完美地处理它们。 -// 在那之前,你可以自定义函数和类型来自行控制编译器插件的行为, -// 就像自定义其他平台那样。 +// 由**你**自定义的部分函数或类型... +// 这些不包含在运行时中。 +// 由于 WasmJS 对各类使用存在诸多限制... +// 目前尚未找到完美处理方式。 +// 在此之前,你可以自定义函数和类型来控制编译器插件的行为, +// 就像对其他平台所做的那样。 fun runInAsync(block: suspend () -> T): AsyncResult = AsyncResult(block) @@ -101,7 +103,7 @@ class AsyncResult(val block: suspend () -> T) { } ``` -compiled 👇 +编译后 👇 ```kotlin class Foo { @@ -109,117 +111,64 @@ class Foo { delay(5) return "Hello" } - @Api4Js // RequiresOptIn annotation, provide warnings to Kotlin - fun waitAndGetAsync(): AsyncResult = runInAsync { waitAndGet() } // 'runInAsync' from the runtime provided by the plugin - // AsyncResult is a custom type + @Api4Js // 需要显式启用的注解,向 Kotlin 提供警告 + fun waitAndGetAsync(): AsyncResult = runInAsync { waitAndGet() } // 'runInAsync' 来自插件提供的运行时 + // AsyncResult 是**你**自定义的类型 } ``` - -## 使用 +## 使用方式 ### 版本说明 -在 `0.9.0` (包括) 以前,版本的命名方式是 `x.y.z` 的形式。 -但是Kotlin编译器的内容集合每个Kotlin版本都有可能发生改变, -而这似乎无法体现出其构建于的Kotlin版本信息,进而导致产生一些混乱。 +`0.9.0` 及之前版本使用 `x.y.z` 的命名规则。但由于 Kotlin 编译器可能随版本变化, +这种命名方式无法反映对应的 Kotlin 版本,可能导致混淆。 -因此,从 `0.9.0` 之后的版本开始,版本的命名方式会改为 `$Kotlin-$plugin` 的形式, -例如 `2.0.20-0.9.1`。 -前半部分代表用于构建的Kotlin版本,而后半部分则为插件的版本。 +因此,`0.9.0` 之后的版本将采用 `$Kotlin-$plugin` 的命名形式, +例如 `2.0.20-0.9.1`。前半部分为构建所用的 Kotlin 版本,后半部分为插件版本。 -如果版本小于等于 `0.9.0`,你可以参考下面这个对照表: +若版本小于等于 `0.9.0`,可参考以下对照表: -| Kotlin版本 | 插件版本 | -|----------|-------------------------| -| `2.0.0` | `0.8.0-beta1` ~ `0.9.0` | -| `1.9.22` | `0.7.0-beta1` | -| `1.9.21` | `0.6.0` | -| `1.9.10` | `0.5.1` | -| `1.9.0` | `0.5.0` | -| `1.8.21` | `0.3.1` ~ `0.4.0` | +| Kotlin 版本 | 插件版本 | +|---------------|------------------------| +| `2.0.0` | `0.8.0-beta1` ~ `0.9.0` | +| `1.9.22` | `0.7.0-beta1` | +| `1.9.21` | `0.6.0` | +| `1.9.10` | `0.5.1` | +| `1.9.0` | `0.5.0` | +| `1.8.21` | `0.3.1` ~ `0.4.0` | > [!note] -> 我没有详细记录每一个Kotlin版本之间的编译器的兼容性。 -> 根据我的记忆和猜测,每当 minor 版本号增加时 (例如 `1.8.0` -> `1.9.0`) -> 则不兼容的概率较大,而当 patch 增加时 (例如 `1.9.0` -> `1.9.10`) 不兼容的概率较小。 +> 未详细记录各 Kotlin 版本的编译器插件兼容性。 +> 根据经验,次要版本升级(如 `1.8.0` -> `1.9.0`)更可能不兼容, +> 补丁版本(如 `1.9.21` -> `1.9.22`)不兼容概率较低。 ### Gradle -**通过 [plugins DSL](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block) 使用:** +**使用 [plugins DSL](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block):** _build.gradle.kts_ -```kotlin +```Kotlin plugins { - id("org.jetbrains.kotlin.jvm") version "$KOTLIN_VERSION" // or js? or multiplatform? - id("love.forte.plugin.suspend-transform") version "$PLUGIN_VERSION" - // other... + kotlin("jvm") version "$KOTLIN_VERSION" // 或 multiplatform + id("love.forte.plugin.suspend-transform") version "$PLUGIN_VERSION" + // 其他... } -// other... +// 其他... -// config it. -suspendTransform { - enabled = true // default: true - includeRuntime = true // default: true - includeAnnotation = true // default: true - // 注意:如果禁用 includeAnnotation, 你需要自定义 targetMarker 或将其设置为 `null` - // 更多参考: https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin/pull/73 - // targetMarker = null // 或自定义 - - /* - * 相当于同时使用 `useJvmDefault` 和 `useJsDefault`. - * 需要包含 runtime 和 annotation - */ - // useDefault() - - /* - * 使用JVM平台的默认配置 - * 相当于: - * addJvmTransformers( - * SuspendTransformConfiguration.jvmBlockingTransformer, - * SuspendTransformConfiguration.jvmAsyncTransformer, - * ) - * - * 需要包含 runtime 和 annotation - */ - useJvmDefault() - - // 或者由你自定义 - jvm { - // ... - } - // 或者由你自定义 - addJvmTransformers(...) - - /* - * 使用JS平台的默认配置 - * 相当于: - * addJvmTransformers( - * SuspendTransformConfiguration.jsPromiseTransformer, - * ) - * - * 需要包含 runtime 和 annotation - */ - useJsDefault() - - // 或者由你自定义 - js { - // ... - } - // 或者由你自定义 - addJsTransformers(...) +// 配置插件 +suspendTransformPlugin { + // 配置 SuspendTransformPluginExtension ... } ``` - - -**通过 [legacy plugin application](https://docs.gradle.org/current/userguide/plugins.html#sec:old_plugin_application) 使用:** +**使用 [传统插件应用方式](https://docs.gradle.org/current/userguide/plugins.html#sec:old_plugin_application):** _build.gradle.kts_ -```kotlin +```Kotlin buildscript { repositories { mavenCentral() @@ -231,504 +180,562 @@ buildscript { } plugins { - id("org.jetbrains.kotlin.jvm") // 或 js? 或 multiplatform? + id("org.jetbrains.kotlin.jvm") // 或 multiplatform? id("love.forte.plugin.suspend-transform") // 其他... } // 其他... -// 配置 -suspendTransform { - enabled = true // default: true - includeRuntime = true // default: true - includeAnnotation = true // default: true - // 注意:如果禁用 includeAnnotation, 你需要自定义 targetMarker 或将其设置为 `null` - // 更多参考: https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin/pull/73 - // targetMarker = null // 或自定义 - - /* - * 相当于同时使用 `useJvmDefault` 和 `useJsDefault`. - * 需要包含 runtime 和 annotation - */ - // useDefault() - - /* - * 使用JVM平台的默认配置 - * 相当于: - * addJvmTransformers( - * SuspendTransformConfiguration.jvmBlockingTransformer, - * SuspendTransformConfiguration.jvmAsyncTransformer, - * ) - * - * 需要包含 runtime 和 annotation - */ - useJvmDefault() - - // 或者由你自定义 - jvm { - // ... - } - // 或者由你自定义 - addJvmTransformers(...) - - /* - * 使用JS平台的默认配置 - * 相当于: - * addJvmTransformers( - * SuspendTransformConfiguration.jsPromiseTransformer, - * ) - * - * 需要包含 runtime 和 annotation - */ - useJsDefault() - - // 或者由你自定义 - js { - // ... - } - // 或者由你自定义 - addJsTransformers(...) +// 配置插件 +suspendTransformPlugin { + // 配置 SuspendTransformPluginExtension ... } ``` -## 注意事项 +## 配置扩展 -### Gradle JVM +### 启用插件 -Gradle JVM 必须满足 JDK11+ +启用 Kotlin 编译器插件。默认值为 `true`。 -### K2 +```Kotlin +suspendTransformPlugin { + enabled = true +} +``` -K2 编译器从 `v0.7.0` 开始支持。 +### 包含默认注解和运行时 -> [!warning] -> 实验中。 +若需使用我们提供的转换器,需添加 `annotation` 和 `runtime` 依赖。 +可通过配置自动添加: -### JsExport +```Kotlin +suspendTransformPlugin { + // 包含注解 + // 默认为 `true` + includeAnnotation = true + // 默认值可留空,使用专属默认值 + annotationDependency { + // 默认为 `compileOnly` + configurationName = "compileOnly" + // 默认与插件版本相同 + version = "" + } + + // 包含运行时 + // 默认为 `true` + includeRuntime = true + // 默认值可留空,使用专属默认值 + runtimeDependency { + // 默认为 `implementation` + configurationName = "implementation" + // 默认与插件版本相同 + version = "" + } +} +``` -如果你打算在默认配置的情况下使用 `@JsExport`, 可以尝试以下代码: +也可手动添加依赖: -_build.gradle.kts_ +```Kotlin +plugin { + kotlin("jvm") version "..." // 以 Kotlin/JVM 为例 + id("love.forte.plugin.suspend-transform") version "2.1.20-0.12.0" +} -```kotlin -plugins { - ... +dependencies { + // 注解 + compileOnly("love.forte.plugin.suspend-transform:suspend-transform-annotation:") + // 运行时 + implementation("love.forte.plugin.suspend-transform:suspend-transform-runtime:") } -suspendTransform { - addJsTransformers( - SuspendTransformConfiguration.jsPromiseTransformer.copy( - copyAnnotationExcludes = listOf( - // 生成的函数将不会包含 `@JsExport.Ignore` - ClassInfo("kotlin.js", "JsExport.Ignore") - ) - ) - ) +suspendTransformPlugin { + // 禁用自动包含 + includeAnnotation = false + includeRuntime = false } ``` +### 添加转换器 + +`Transformer` 用于描述如何转换挂起函数。需添加 `Transformer` 以使插件生效。 + ```Kotlin -@file:OptIn(ExperimentalJsExport::class) +suspendTransformPlugin { + // 配置转换器 + transformers { + add(TargetPlatform.JVM) { // this: TransformerSpec + // 配置 TransformerSpec... + } -@JsExport -class Foo { - @JsPromise - @JsExport.Ignore - suspend fun run(): Int = ... + addJvm { // this: TransformerSpec + // 配置 TransformerSpec... + } + + // 使用预置的默认转换器 + add(TargetPlatform.JVM, SuspendTransformConfigurations.jvmBlockingTransformer) + + addJvm { // this: TransformerSpec + // 基于现有转换器调整 + from(SuspendTransformConfigurations.jvmBlockingTransformer) + // 进一步配置... + } + } } ``` -## 效果 +#### 添加默认转换器 -**源代码:** +我们提供了一些常用实现,可通过配置快速使用。 -```kotlin -import love.forte.plugin.suspendtrans.annotation.JvmAsync -import love.forte.plugin.suspendtrans.annotation.JvmBlocking +> [!note] +> 默认 `Transformer` 依赖我们提供的 `annotation` 和 `runtime`,请确保已包含。 -@JvmBlocking -@JvmAsync -interface Foo { +**JVM 阻塞式** - suspend fun name(): String +```Kotlin +suspendTransformPlugin { + transformers { + // 方式一: + addJvmBlocking() - suspend fun age(def: Int = 5): Int + // 方式二: + addJvm(SuspendTransformConfigurations.jvmBlockingTransformer) + } +} +``` - @JvmBlocking(asProperty = true) - suspend fun self(): Foo +`JvmBlocking` 允许在挂起函数上标记 `@JvmBlocking`,生成 `xxxBlocking` 函数。 + +```Kotlin +class Cat { + @JvmBLocking + suspend fun meow() { + // ... + } + + // 生成: + fun meowBlocking() { + `$runInBlocking$` { meow() } + } } +``` -@JvmBlocking -@JvmAsync -class FooImpl : Foo { - suspend fun size(): Long = 666 - override suspend fun name(): String = "forte" - override suspend fun age(def: Int): Int = def - @JvmBlocking(asProperty = true) // asProperty 必须为 true - override suspend fun self(): FooImpl = this +`$runInBlocking$` 基于 `kotlinx.coroutines.runBlocking`。 + +**JVM 异步式** + +```Kotlin +suspendTransformPlugin { + transformers { + // 方式一: + addJvmAsync() + + // 方式二: + addJvm(SuspendTransformConfigurations.jvmAsyncTransformer) + } } +``` -class Bar { - @JvmBlocking - @JvmAsync - suspend fun bar(): String = "" +`JvmAsync` 允许在挂起函数上标记 `@JvmAsync`,生成 `xxxAsync` 函数。 - suspend fun noTrans(): Int = 1 +```Kotlin +class Cat { + @JvmBLocking + suspend fun meow(): String = "Meow!" + + // 生成: + fun meowAsync(): CompletableFuture { + `$runInAsync$`(block = { meow() }, scope = this as? CoroutineScope) + } } ``` -**编译结果:** +`block` 是需要执行的原始挂起函数,`scope` 是使用的协程作用域。 -> _简化自反编译结果_ +若当前作用域是 `CoroutineScope`,则优先使用自身。否则内部使用 `GlobalScope`。 -```kotlin -import love.forte.plugin.suspendtrans.annotation.JvmAsync -import love.forte.plugin.suspendtrans.annotation.JvmBlocking -import love.forte.plugin.suspendtrans.annotation.Generated -import love.forte.plugin.suspendtrans.annotation.Api4J -import kotlin.jvm.JvmSynthetic +使用 `GlobalScope` 的原因: +1. 全局性。 +2. 不可见,不会被手动关闭。 +3. 不涉及 IO,无需自定义调度器。 -@JvmBlocking -@JvmAsync -interface Foo { - @Generated - @Api4J - val selfBlocking: Foo /* compiled code */ +若有异议,欢迎提交 issue! - suspend fun age(def: Int /* = compiled code */): Int +**JS Promise** - @Generated - @Api4J - fun ageAsync(def: Int /* = compiled code */): java.util.concurrent.CompletableFuture { /* compiled code */ } +```Kotlin +suspendTransformPlugin { + transformers { + // 方式一: + addJsPromise() - @Generated - @Api4J - fun ageBlocking(def: Int /* = compiled code */): Int { /* compiled code */ } + // 方式二: + addJs(SuspendTransformConfigurations.jsPromiseTransformer) + } +} +``` - suspend fun name(): String +```Kotlin +class Cat { + @JsPromise + suspend fun meow(): String = "Meow!" + + // 生成: + fun meowAsync(): Promise { + `$runInAsync$`(block = { meow() }, scope = this as? CoroutineScope) + } +} +``` - @Generated - @Api4J - fun nameAsync(): java.util.concurrent.CompletableFuture { /* compiled code */ } +#### 使用默认转换器 - @Generated - @Api4J - fun nameBlocking(): String { /* compiled code */ } +`addJvmBlocking()` 和 `addJvmAsync()` 可以被合并为 `useJvmDefault()`。 - @JvmBlocking - suspend fun self(): Foo +```Kotlin +suspendTransformPlugin { + transformers { + // 包括 addJvmBlocking() 和 addJvmAsync() + useJvmDefault() + } +} +``` - @Generated - @Api4J - fun selfAsync(): java.util.concurrent.CompletableFuture { /* compiled code */ } +`addJsPromise()` 可以被合并为 `useJsDefault()` 。 + +```Kotlin +suspendTransformPlugin { + transformers { + // 包括 addJsPromise() + useJsDefault() + } } +``` -@JvmBlocking -@JvmAsync -class FooImpl : Foo { - @Generated - @Api4J - open val selfBlocking: FooImpl /* compiled code */ +`useJvmDefault()` 和 `useJsDefault` 可以被合并为 `useDefault()` 。 - @JvmSynthetic - open suspend fun age(def: Int): Int { /* compiled code */ } +```Kotlin +suspendTransformPlugin { + transformers { + // 包括 addJvmDefault() 和 addJsPromise() + useDefault() + } +} +``` - @Generated - @Api4J - open fun ageAsync(def: Int): java.util.concurrent.CompletableFuture { /* compiled code */ } +#### 自定义转换器 - @Generated - @Api4J - open fun ageBlocking(def: Int): Int { /* compiled code */ } +若默认转换器不满足需求,可自定义 `Transformer`,例如完全自定义阻塞逻辑。 - @JvmSynthetic - open suspend fun name(): String { /* compiled code */ } +> 完整自定义实现参考: +> https://github.com/simple-robot/simpler-robot/blob/v4-main/simbot-commons/simbot-common-suspend-runner/src/jvmMain/kotlin/love/forte/simbot/suspendrunner/BlockingRunner.kt + +```Kotlin +suspendTransformPlugin { + // 自定义时可能无需默认注解和运行时 + includeAnnotation = false + includeRuntime = false + + transformer { + // 具体配置见下文 + } +} +``` - @Generated - @Api4J - open fun nameAsync(): java.util.concurrent.CompletableFuture { /* compiled code */ } +示例:自定义注解 `@JBlock`,通过函数 `inBlock` 执行挂起函数。 - @Generated - @Api4J - open fun nameBlocking(): String { /* compiled code */ } +```Kotlin +// 自定义注解 +annotation class JBlock(...) - @JvmSynthetic - @JvmBlocking - suspend fun self(): FooImpl { /* compiled code */ } +// 自定义顶层转换函数 +fun inBlock(block: suspend () -> T): T { + TODO("你的实现") +} +``` - @Generated - @Api4J - fun selfAsync(): java.util.concurrent.CompletableFuture { /* compiled code */ } +假设注解包含以下属性: +- `baseName`: 生成函数的基础名(默认为原函数名) +- `suffix`: 生成函数名的后缀 +- `asProperty`: 将生成函数转为属性(适用于无参数的函数) - @JvmSynthetic - suspend fun size(): Long { /* compiled code */ } +注解定义: + +```Kotlin +annotation class JBlock( + val baseName: String = "", + val suffix: String = "Blocking", + val asProperty: Boolean = false +) +``` - @Generated - @Api4J - fun sizeAsync(): java.util.concurrent.CompletableFuture { /* compiled code */ } +配置示例: - @Generated - @Api4J - fun sizeBlocking(): Long { /* compiled code */ } +```Kotlin +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + addJvm { + markAnnotation { + // 注解类信息 + classInfo { + packageName = "com.example" + className = "JBlock" + } + + // 属性名映射 + baseNameProperty = "baseName" // 默认为 `baseName` + suffixProperty = "suffix" // 默认为 `suffix` + asPropertyProperty = "asProperty" // 默认为 `asProperty` + + // 默认值需手动配置(编译器无法获取注解默认值) + defaultSuffix = "Blocking" + defaultAsProperty = false + } + } + } } +``` +若属性名不同: -class Bar { - @JvmSynthetic - @JvmBlocking - @JvmAsync - suspend fun bar(): String { /* compiled code */ } +```Kotlin +annotation class JBlock( + val myBaseName: String = "", + val mySuffix: String = "Blocking", + val myAsProperty: Boolean = false +) +``` + +配置调整: - @Generated - @Api4J - fun barAsync(): java.util.concurrent.CompletableFuture { /* compiled code */ } +```Kotlin +baseNameProperty = "myBaseName" +suffixProperty = "mySuffix" +asPropertyProperty = "myAsProperty" +``` - @Generated - @Api4J - fun barBlocking(): String { /* compiled code */ } +转换函数配置: - fun noTrans(): Int { /* compiled code */ } +```Kotlin +transformFunctionInfo { + packageName = "com.example" + functionName = "inBlock" } + +// 返回类型配置 +transformReturnType = null // 与原函数返回类型相同 +transformReturnTypeGeneric = false // 无泛型 ``` -## 自定义配置 +注解复制配置示例: +```Kotlin +addOriginFunctionIncludeAnnotation { + classInfo { + packageName = "kotlin.jvm" + className = "JvmSynthetic" + } + repeatable = false +} -```kotlin -plugin { - id("love.forte.plugin.suspend-transform") version "$VERSION" +addSyntheticFunctionIncludeAnnotation { + classInfo { + packageName = "com.example" + className = "JApi" + } + includeProperty = true } +addCopyAnnotationExclude { + from(SuspendTransformConfigurations.jvmSyntheticClassInfo) +} +``` -suspendTransform { - // enabled suspend transform plugin - enabled = true - // include 'love.forte.plugin.suspend-transform:suspend-transform-runtime' to the runtime environment - includeRuntime = true - // the configuration name for including 'love.forte.plugin.suspend-transform:suspend-transform-runtime' - runtimeConfigurationName = "implementation" - - val customJvmTransformer = Transformer( - // mark annotation info, e.g. `@JvmBlocking` - markAnnotation = MarkAnnotation( - classInfo = ClassInfo("love.forte.plugin.suspendtrans.annotation", "JvmBlocking"), // class info for this annotation - baseNameProperty = "baseName", // The property used to represent the 'base name' in the annotation, e.g. `@JvmBlocking(baseName = ...)` - suffixProperty = "suffix", // The property used to represent the 'suffix' in the annotation, e.g. `@JvmBlocking(suffix = ...)` - asPropertyProperty = "asProperty", // The property used to represent the 'asProperty' in the annotation, e.g. `@JvmBlocking(asProperty = true|false)` - defaultSuffix = "Blocking", // Default value used when property 'suffix' (the value of suffixProperty) does not exist (when not specified by the user) (the compiler plugin cannot detect property defaults directly, so the default value must be specified from here) - // e.g. @JvmBlocking(suffix = "Abc"), the suffix is 'Abc', but `@JvmBlocking()`, the suffix is null in compiler plugin, so use the default suffix value. - defaultAsProperty = false, // Default value used when property 'suffix' (the value of suffixProperty) does not exist (Similar to defaultSuffix) - ), - // the transform function, e.g. - // 👇 `love.forte.plugin.suspendtrans.runtime.$runInBlocking$` - // it will be like - // ``` - // @JvmBlocking suspend fun runXxx() { ... } - // fun runXxxBlocking() = `$runInBlocking$` { runXxx() /* suspend */ } // generated function - // ``` - transformFunctionInfo = FunctionInfo( - packageName = "love.forte.plugin.suspendtrans.runtime", - className = null, // null if top-level function - functionName = "\$runInBlocking\$" - ), - transformReturnType = null, // return type, or null if return the return type of origin function, e.g. `ClassInfo("java.util.concurrent", "CompletableFuture")` - transformReturnTypeGeneric = false, // if you return like `CompletableFuture`, make it `true` - originFunctionIncludeAnnotations = listOf(IncludeAnnotation(ClassInfo("kotlin.jvm", "JvmSynthetic"))), // include into origin function - copyAnnotationsToSyntheticFunction = true, - copyAnnotationExcludes = listOf(ClassInfo("kotlin.jvm", "JvmSynthetic")), // do not copy from origin function - syntheticFunctionIncludeAnnotations = listOf(IncludeAnnotation(jvmApi4JAnnotationClassInfo)) // include into synthetic function - ) - - addJvmTransformers( - customJvmTransformer, ... - ) - - // or addJsTransformers(...) - -} -``` - -举个例子,你想要使用一个单独的注解就完成`@JvmAsync`, `@JvmBlocking`, and `@JsPromise`的工作: +完整示例: +代码: -```kotlin -// 你在JVM平台上的转化函数 -// 比如 com.example.Transforms.jvm.kt +```Kotlin +annotation class JBlock( + val myBaseName: String = "", + val mySuffix: String = "Blocking", + val myAsProperty: Boolean = false +) + +@RequiresOptIn(message = "Java 接口", level = RequiresOptIn.Level.WARNING) +@Retention(AnnotationRetention.BINARY) +annotation class JApi -@Deprecated("Just used by compiler", level = DeprecationLevel.HIDDEN) -fun runInBlocking(block: suspend () -> T): T { - // run the `block` in blocking - runBlocking { block() } +fun inBlock(block: suspend () -> T): T { + TODO("你的实现") } +``` -@Deprecated("Just used by compiler", level = DeprecationLevel.HIDDEN) -public fun runInAsync(block: suspend () -> T, scope: CoroutineScope? = null): CompletableFuture { - // run the `block` in async - val scope0 = scope ?: GlobalScope - return scope0.future { block() } - - /* - `scope` 是 `block`'s 所处的容器: - ``` - interface Container { - @JvmAsync - suspend fun run() - 👇 compiled - - fun runAsync() = runInAsync(block = { run() }, scope = this as? CoroutineScope) +配置: + +```Kotlin +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + addJvm { + markAnnotation { + classInfo { + packageName = "com.example" + className = "JBlock" + } + + baseNameProperty = "myBaseName" + suffixProperty = "mySuffix" + asPropertyProperty = "myAsProperty" + + defaultSuffix = "Blocking" + defaultAsProperty = false + } + + transformFunctionInfo { + packageName = "com.example" + functionName = "inBlock" + } + + copyAnnotationsToSyntheticFunction = true + copyAnnotationsToSyntheticProperty = true + + addOriginFunctionIncludeAnnotation { + classInfo.from(SuspendTransformConfigurations.jvmSyntheticClassInfo) + repeatable = false + } + + addSyntheticFunctionIncludeAnnotation { + classInfo { + packageName = "com.example" + className = "JApi" + } + includeProperty = true + } + + addCopyAnnotationExclude { + from(SuspendTransformConfigurations.jvmSyntheticClassInfo) + } } - ``` - */ + } } +``` + +> [!note] +> 同一注解可通过不同属性名复用于多个转换器。例如: +> ```Kotlin +> annotation class JTrans( +> val blockingBaseName: String = "", +> val blockingSuffix: String = "Blocking", +> val blockingAsProperty: Boolean = false, +> +> val asyncBaseName: String = "", +> val asyncSuffix: String = "Async", +> val asyncAsProperty: Boolean = false +> ) +> ``` + +## 注意事项 +### Gradle JVM -// 你JS平台上的转化函数 -// 比如 com.example.Transforms.js.kt -@Deprecated("Just used by compiler", level = DeprecationLevel.HIDDEN) -fun runInPromise(block: suspend () -> T, scope: CoroutineScope? = null): T { - val scope0 = scope ?: GlobalScope - return scope0.promise { block() } +**Gradle JVM** 必须为 JDK11+ + +### K2 + +自 `v0.7.0` 起支持 K2。 + +### JsExport + +若需在 JS 中使用 `@JsExport` 的默认配置: + +_build.gradle.kts_ + +```kotlin +plugins { + // ... +} + +suspendTransformPlugin { + transformers { + addJsPromise { + addCopyAnnotationExclude { + // 生成函数不包含 `@JsExport.Ignore` + from(kotlinJsExportIgnoreClassInfo) + } + } + } } ``` -创建你的注解: +```Kotlin +@file:OptIn(ExperimentalJsExport::class) -```kotlin -// Your single annotation -@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CLASS) -@Retention(AnnotationRetention.BINARY) -public annotation class SuspendTrans( - val blockingBaseName: String = "", - val blockingSuffix: String = "Blocking", - val blockingAsProperty: Boolean = false, - - val asyncBaseName: String = "", - val asyncSuffix: String = "Async", - val asyncAsProperty: Boolean = false, - - val jsPromiseBaseName: String = "", - val jsPromiseSuffix: String = "Async", - val jsPromiseAsProperty: Boolean = false, -) +@JsExport +class Foo { + @JsPromise + @JsExport.Ignore + suspend fun run(): Int = ... +} ``` -然后,配置你的构建脚本 +## 效果示例 + +**源码:** ```kotlin -// The annotation type -val suspendTransMarkAnnotationClassInfo = ClassInfo("love.forte.simbot.suspendrunner", "SuspendTrans") - -// The mark annotations -val jvmSuspendTransMarkAnnotationForBlocking = MarkAnnotation( - suspendTransMarkAnnotationClassInfo, - baseNameProperty = "blockingBaseName", - suffixProperty = "blockingSuffix", - asPropertyProperty = "blockingAsProperty", - defaultSuffix = "Blocking", -) -val jvmSuspendTransMarkAnnotationForAsync = MarkAnnotation( - suspendTransMarkAnnotationClassInfo, - baseNameProperty = "asyncBaseName", - suffixProperty = "asyncSuffix", - asPropertyProperty = "asyncAsProperty", - defaultSuffix = "Async", -) -val jsSuspendTransMarkAnnotationForPromise = MarkAnnotation( - suspendTransMarkAnnotationClassInfo, - baseNameProperty = "jsPromiseBaseName", - suffixProperty = "jsPromiseSuffix", - asPropertyProperty = "jsPromiseAsProperty", - defaultSuffix = "Async", -) +import love.forte.plugin.suspendtrans.annotation.JvmAsync +import love.forte.plugin.suspendtrans.annotation.JvmBlocking -// The transform functions -val jvmBlockingFunction = FunctionInfo("com.example", null, "runInBlocking") -val jvmAsyncFunction = FunctionInfo("com.example", null, "runInAsync") -val jsPromiseFunction = FunctionInfo("com.example", null, "runInPromise") - -// The transformers -val suspendTransTransformerForJvmBlocking: Transformer = Transformer( - markAnnotation = jvmSuspendTransMarkAnnotationForBlocking, - transformFunctionInfo = jvmBlockingFunction, - transformReturnType = null, // same as origin function - transformReturnTypeGeneric = false, - // include @JvmSynthetic into origin function - originFunctionIncludeAnnotations = listOf( - SuspendTransformConfiguration.jvmSyntheticClassInfo, - ), - copyAnnotationsToSyntheticFunction = true, - // excludes: @JvmSynthetic, @OptIn, @SuspendTrans - copyAnnotationExcludes = listOf( - SuspendTransformConfiguration.jvmSyntheticClassInfo, - SuspendTransformConfiguration.kotlinOptInClassInfo, - suspendTransMarkAnnotationClassInfo, - ), - // Include into synthetic function's annotations - syntheticFunctionIncludeAnnotations = listOf() -) +@JvmBlocking +@JvmAsync +interface Foo { -val suspendTransTransformerForJvmAsync: Transformer = Transformer( - markAnnotation = jvmSuspendTransMarkAnnotationForAsync, - transformFunctionInfo = jvmAsyncFunction, - transformReturnType = ClassInfo("java.util.concurrent", "CompletableFuture"), - transformReturnTypeGeneric = true, // Future's generic type is origin function's return type. - // include @JvmSynthetic into origin function - originFunctionIncludeAnnotations = listOf( - SuspendTransformConfiguration.jvmSyntheticClassInfo, - ), - copyAnnotationsToSyntheticFunction = true, - // excludes: @JvmSynthetic, @OptIn, @SuspendTrans - copyAnnotationExcludes = listOf( - SuspendTransformConfiguration.jvmSyntheticClassInfo, - suspendTransMarkAnnotationClassInfo, - SuspendTransformConfiguration.kotlinOptInClassInfo, - ), - // Include into synthetic function's annotations - syntheticFunctionIncludeAnnotations = listOf() -) + suspend fun name(): String -val suspendTransTransformerForJsPromise: Transformer = Transformer( - markAnnotation = jsSuspendTransMarkAnnotationForPromise, - transformFunctionInfo = jsPromiseFunction, - transformReturnType = ClassInfo("kotlin.js", "Promise"), - transformReturnTypeGeneric = true, // Promise's generic type is origin function's return type. - originFunctionIncludeAnnotations = listOf(), - copyAnnotationsToSyntheticFunction = true, - // excludes: @OptIn, @SuspendTrans - copyAnnotationExcludes = listOf( - SuspendTransformConfiguration.kotlinOptInClassInfo, - suspendTransMarkAnnotationClassInfo, - ), - syntheticFunctionIncludeAnnotations = listOf() -) + suspend fun age(def: Int = 5): Int -// 上面这些东西也可以考虑在 `buildSrc` 中定义。 + @JvmBlocking(asProperty = true) + suspend fun self(): Foo +} -suspendTransform { - // 关闭它们,并使用你自己自定义的 runtime 和 annotation - includeRuntime = false - includeAnnotation = false - // 注意:如果禁用 includeAnnotation, 你需要自定义 targetMarker 或将其设置为 `null` - // 更多参考: https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin/pull/73 - targetMarker = null // 或自定义 +@JvmBlocking +@JvmAsync +class FooImpl : Foo { + suspend fun size(): Long = 666 + override suspend fun name(): String = "forte" + override suspend fun age(def: Int): Int = def + @JvmBlocking(asProperty = true) // 必须为 'asProperty=true' + override suspend fun self(): FooImpl = this +} - addJvmTransformers( - suspendTransTransformerForJvmBlocking, - suspendTransTransformerForJvmAsync - ) - addJsTransformers( - suspendTransTransformerForJsPromise - ) +class Bar { + @JvmBlocking + @JvmAsync + suspend fun bar(): String = "" + + suspend fun noTrans(): Int = 1 } ``` +**编译结果(简化版):** + +```kotlin +// 生成代码的详细实现略,参见原文 +``` + ## 应用案例 -- [Simple Robot 框架](https://github.com/simple-robot/simpler-robot) (完全定制化) +- [Simple Robot Frameworks](https://github.com/simple-robot/simpler-robot) (完全自定义实现) + -## 开源协议 +## 许可证 -参考 [LICENSE](LICENSE) . +见 [LICENSE](LICENSE) 。 ```text Copyright (c) 2022 ForteScarlet diff --git a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt index f2a042e..84221ea 100644 --- a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt +++ b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt @@ -339,6 +339,14 @@ object SuspendTransformConfigurations { private const val JS_RUN_IN_ASYNC_FUNCTION_FUNCTION_NAME = "\$runInAsync\$" + //region Commons + @JvmStatic + val kotlinOptInClassInfo = ClassInfo( + packageName = KOTLIN, + className = "OptIn" + ) + //endregion + //region JVM Defaults @JvmStatic val jvmSyntheticClassInfo = ClassInfo( @@ -346,12 +354,6 @@ object SuspendTransformConfigurations { className = "JvmSynthetic" ) - @JvmStatic - val kotlinOptInClassInfo = ClassInfo( - packageName = KOTLIN, - className = "OptIn" - ) - @JvmStatic val jvmApi4JAnnotationClassInfo = ClassInfo( packageName = SUSPENDTRANS_ANNOTATION_PACKAGE, @@ -437,6 +439,18 @@ object SuspendTransformConfigurations { //endregion //region JS Defaults + @JvmStatic + val kotlinJsExportClassInfo = ClassInfo( + packageName = KOTLIN_JS, + className = "JsExport" + ) + + @JvmStatic + val kotlinJsExportIgnoreClassInfo = ClassInfo( + packageName = KOTLIN_JS, + className = "JsExport.Ignore" + ) + @JvmStatic val jsApi4JsAnnotationInfo = ClassInfo( packageName = SUSPENDTRANS_ANNOTATION_PACKAGE, diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt index d5d58e2..f3c774d 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt @@ -871,28 +871,29 @@ class SuspendTransformFirTransformer( return isOverride } - private val annotationPredicates = DeclarationPredicate.create { - var predicate: DeclarationPredicate? = null - for (value in suspendTransformConfiguration.transformers.values) { - for (transformer in value) { - val afq = transformer.markAnnotation.fqName - predicate = if (predicate == null) { - annotated(afq) - } else { - predicate or annotated(afq) + private val annotationPredicates: DeclarationPredicate? = + if (suspendTransformConfiguration.transformers.values.isEmpty()) { + null + } else { + DeclarationPredicate.create { + var predicate: DeclarationPredicate? = null + for (value in suspendTransformConfiguration.transformers.values) { + for (transformer in value) { + val afq = transformer.markAnnotation.fqName + predicate = predicate?.also { p -> p or annotated(afq) } ?: annotated(afq) + } } + + predicate ?: annotated() } } - predicate ?: annotated() - } - /** * NB: The predict needs to be *registered* in order to parse the [@XSerializable] type * otherwise, the annotation remains unresolved */ override fun FirDeclarationPredicateRegistrar.registerPredicates() { - register(annotationPredicates) + annotationPredicates?.also { register(it) } } private fun createCache( diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt index ff69979..edb6d3f 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt @@ -1,6 +1,7 @@ package love.forte.plugin.suspendtrans.gradle -const val USE_NEW_EXTENSION = "Use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + +const val USE_NEW_EXTENSION = "Use the new extension " + + "`love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + "(`suspendTransformPlugin { ... }`)" /** @@ -9,11 +10,12 @@ const val USE_NEW_EXTENSION = "Use `love.forte.plugin.suspendtrans.gradle.Suspen */ @Suppress("DEPRECATION") @Deprecated( - USE_NEW_EXTENSION, - ReplaceWith( + message = USE_NEW_EXTENSION, + replaceWith = ReplaceWith( "SuspendTransformPluginExtension", "love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension" - ) + ), + level = DeprecationLevel.ERROR ) open class SuspendTransformGradleExtension : love.forte.plugin.suspendtrans.SuspendTransformConfiguration() { @Deprecated("Please use the " + diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index 933e7fe..a921b49 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -2,12 +2,27 @@ package love.forte.plugin.suspendtrans.gradle import love.forte.plugin.suspendtrans.cli.SuspendTransformCliOptions import love.forte.plugin.suspendtrans.cli.encodeToHex +import love.forte.plugin.suspendtrans.configuration.* import love.forte.plugin.suspendtrans.gradle.DependencyConfigurationName.* import org.gradle.api.Project import org.gradle.api.provider.Provider import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.plugin.* +@Suppress("DEPRECATION") +private typealias DeprecatedClassInfo = love.forte.plugin.suspendtrans.ClassInfo +@Suppress("DEPRECATION") +private typealias DeprecatedFunctionInfo = love.forte.plugin.suspendtrans.FunctionInfo +@Suppress("DEPRECATION") +private typealias DeprecatedIncludeAnnotation = love.forte.plugin.suspendtrans.IncludeAnnotation +@Suppress("DEPRECATION") +private typealias DeprecatedMarkAnnotation = love.forte.plugin.suspendtrans.MarkAnnotation +@Suppress("DEPRECATION") +private typealias DeprecatedSuspendTransformConfiguration = love.forte.plugin.suspendtrans.SuspendTransformConfiguration +@Suppress("DEPRECATION") +private typealias DeprecatedTargetPlatform = love.forte.plugin.suspendtrans.TargetPlatform +@Suppress("DEPRECATION") +private typealias DeprecatedTransformer = love.forte.plugin.suspendtrans.Transformer /** * @@ -20,7 +35,7 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { } override fun apply(target: Project) { - @Suppress("DEPRECATION") + @Suppress("DEPRECATION_ERROR") target.extensions.create( EXTENSION_NAME, SuspendTransformGradleExtension::class.java @@ -60,9 +75,13 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { val target = kotlinCompilation.target val project = target.project + return project.provider { resolveSubpluginOptions(target, project) } + } + + private fun resolveSubpluginOptions(target: KotlinTarget, project: Project): List { val extension = project.extensions.getByType(SuspendTransformPluginExtension::class.java) - @Suppress("DEPRECATION") val oldExtension = + @Suppress("DEPRECATION_ERROR") val oldExtension = project.extensions.getByType(SuspendTransformGradleExtension::class.java) @Suppress("DEPRECATION") if (oldExtension.enabled || oldExtension.transformers.isNotEmpty()) { @@ -80,7 +99,7 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { "(`suspendTransformPlugin { ... }`) instead. " + "The SuspendTransformGradleExtension property " + "will currently be aggregated with `SuspendTransformPluginExtension`, " + - "but it will soon be deprecated completely." + "but it will soon be deprecated completely. " when { showError -> { @@ -95,21 +114,163 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { oldExtension.mergeTo(extension) } - return project.provider { - extension.toSubpluginOptions() - } + return extension.toSubpluginOptions(target, project) } } -@Suppress("DEPRECATION") +@Suppress("DEPRECATION", "DEPRECATION_ERROR", "TYPEALIAS_EXPANSION_DEPRECATION") private fun SuspendTransformGradleExtension.mergeTo(extension: SuspendTransformPluginExtension) { - TODO() + if (this.enabled) { + extension.enabled.convention(true) + } + if (this.includeAnnotation) { + extension.includeAnnotation.convention(true) + } + + // Annotation + val deprecatedAnnotationVersion = this.annotationDependencyVersion + // Not the default value + if (deprecatedAnnotationVersion != SuspendTransPluginConstants.ANNOTATION_VERSION) { + extension.annotationDependency { + it.version.convention(deprecatedAnnotationVersion) + } + } + val deprecatedAnnotationConfigurationName = this.annotationConfigurationName + if (deprecatedAnnotationConfigurationName != "compileOnly") { + extension.annotationDependency { + it.configurationName.convention(deprecatedAnnotationConfigurationName) + } + } + + if (this.includeRuntime) { + extension.includeRuntime.convention(true) + } + + // Runtime + val deprecatedRuntimeVersion = this.runtimeDependencyVersion + if (deprecatedRuntimeVersion != SuspendTransPluginConstants.RUNTIME_VERSION) { + extension.runtimeDependency { + it.version.convention(deprecatedRuntimeVersion) + } + } + val deprecatedRuntimeConfigurationName = this.runtimeConfigurationName + if (deprecatedRuntimeConfigurationName != "implementation") { + extension.runtimeDependency { + it.configurationName.convention(deprecatedRuntimeConfigurationName) + } + } + + // Transformers + if (this.transformers.isNotEmpty()) { + extension.transformers { transformerContainer -> + for ((deprecatedTarget, deprecatedTransformers) in this.transformers) { + val target = deprecatedTarget.toTarget() + deprecatedTransformers.forEach { deprecatedTransformer -> + when (deprecatedTransformer) { + DeprecatedSuspendTransformConfiguration.jvmBlockingTransformer -> { + transformerContainer.add(target, SuspendTransformConfigurations.jvmBlockingTransformer) + } + + DeprecatedSuspendTransformConfiguration.jvmAsyncTransformer -> { + transformerContainer.add(target, SuspendTransformConfigurations.jvmAsyncTransformer) + } + + DeprecatedSuspendTransformConfiguration.jsPromiseTransformer -> { + transformerContainer.add(target, SuspendTransformConfigurations.jsPromiseTransformer) + } + + else -> transformerContainer.add(target, deprecatedTransformer.toTransformer()) + } + } + } + } + } +} + +@Suppress("DEPRECATION", "TYPEALIAS_EXPANSION_DEPRECATION", "KotlinRedundantDiagnosticSuppress") +private fun DeprecatedTargetPlatform.toTarget(): TargetPlatform { + return when (this) { + DeprecatedTargetPlatform.COMMON -> TargetPlatform.COMMON + DeprecatedTargetPlatform.JVM -> TargetPlatform.JVM + DeprecatedTargetPlatform.JS -> TargetPlatform.JS + DeprecatedTargetPlatform.WASM -> TargetPlatform.WASM + DeprecatedTargetPlatform.NATIVE -> TargetPlatform.NATIVE + } } -private fun SuspendTransformPluginExtension.toSubpluginOptions(): List { +@OptIn(InternalSuspendTransformConstructorApi::class) +@Suppress("TYPEALIAS_EXPANSION_DEPRECATION") +private fun DeprecatedTransformer.toTransformer(): Transformer { + return Transformer( + markAnnotation = this.markAnnotation.toMarkAnnotation(), + transformFunctionInfo = this.transformFunctionInfo.toFunctionInfo(), + transformReturnType = this.transformReturnType?.toClassInfo(), + transformReturnTypeGeneric = this.transformReturnTypeGeneric, + originFunctionIncludeAnnotations = this.originFunctionIncludeAnnotations.map { it.toIncludeAnnotation() }, + syntheticFunctionIncludeAnnotations = this.syntheticFunctionIncludeAnnotations.map { it.toIncludeAnnotation() }, + copyAnnotationsToSyntheticFunction = this.copyAnnotationsToSyntheticFunction, + copyAnnotationExcludes = this.copyAnnotationExcludes.map { it.toClassInfo() }, + copyAnnotationsToSyntheticProperty = this.copyAnnotationsToSyntheticProperty + ) +} + +@OptIn(InternalSuspendTransformConstructorApi::class) +@Suppress("TYPEALIAS_EXPANSION_DEPRECATION") +private fun DeprecatedMarkAnnotation.toMarkAnnotation(): MarkAnnotation { + return MarkAnnotation( + classInfo = this.classInfo.toClassInfo(), + baseNameProperty = this.baseNameProperty, + suffixProperty = this.suffixProperty, + asPropertyProperty = this.asPropertyProperty, + defaultSuffix = this.defaultSuffix, + defaultAsProperty = this.defaultAsProperty + ) +} + +@OptIn(InternalSuspendTransformConstructorApi::class) +@Suppress("TYPEALIAS_EXPANSION_DEPRECATION") +private fun DeprecatedFunctionInfo.toFunctionInfo(): FunctionInfo { + return FunctionInfo( + packageName = this.packageName, + functionName = this.functionName + ) +} + +@OptIn(InternalSuspendTransformConstructorApi::class) +@Suppress("TYPEALIAS_EXPANSION_DEPRECATION") +private fun DeprecatedClassInfo.toClassInfo(): ClassInfo { + return ClassInfo( + packageName = this.packageName, + className = this.className, + local = this.local, + nullable = this.nullable + ) +} + +@OptIn(InternalSuspendTransformConstructorApi::class) +@Suppress("TYPEALIAS_EXPANSION_DEPRECATION") +private fun DeprecatedIncludeAnnotation.toIncludeAnnotation(): IncludeAnnotation { + return IncludeAnnotation( + classInfo = this.classInfo.toClassInfo(), + repeatable = this.repeatable, + includeProperty = this.includeProperty + ) +} + +private fun SuspendTransformPluginExtension.toSubpluginOptions(target: KotlinTarget, project: Project): List { + // If not enabled or transformer is empty. val cliConfig = SuspendTransformCliOptions.CLI_CONFIGURATION val configuration = toConfiguration() - return listOf(SubpluginOption(cliConfig.optionName, configuration.encodeToHex())) + return if (configuration.enabled && configuration.transformers.isNotEmpty()) { + if (project.logger.isInfoEnabled) { + val count = configuration.transformers.values.sumOf { it.size } + project.logger.info("The suspend transform is enabled with {} transformer(s) for {}", count, target) + } + listOf(SubpluginOption(cliConfig.optionName, configuration.encodeToHex())) + } else { + project.logger.info("The suspend transform is disabled or transformers are empty for {}.", target) + emptyList() + } } private fun Project.configureDependencies() { diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index 0b85241..9ca65b7 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -1,18 +1,37 @@ package love.forte.plugin.suspendtrans.gradle import love.forte.plugin.suspendtrans.configuration.* +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jsPromiseTransformer +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmAsyncTransformer +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingTransformer import org.gradle.api.Action import org.gradle.api.DomainObjectSet import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.* import javax.inject.Inject +/** + * @since 0.12.0 + */ +@DslMarker +annotation class SuspendTransformPluginExtensionSpecDslMarker + +/** + * @since 0.12.0 + */ +@SuspendTransformPluginExtensionSpecDslMarker +interface SuspendTransformPluginExtensionSpec + +/** + * @since 0.12.0 + */ abstract class TransformerContainer -@Inject constructor(private val objects: ObjectFactory) { +@Inject constructor(private val objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { internal val transformers: MutableMap> = mutableMapOf() - private fun getTransformers(platform: TargetPlatform): ListProperty = - transformers.computeIfAbsent(platform) { objects.listProperty(TransformerSpec::class.java) } + private fun getTransformers(platform: TargetPlatform): ListProperty { + return transformers.computeIfAbsent(platform) { objects.listProperty(TransformerSpec::class.java) } + } fun add(platform: TargetPlatform, action: Action) { val listProperty = getTransformers(platform) @@ -59,49 +78,82 @@ abstract class TransformerContainer fun addCommon(transformer: Transformer) = addCommon { it.from(transformer) } fun addCommon(transformer: Provider) = add(TargetPlatform.COMMON, transformer) fun addCommon(action: Action) = add(TargetPlatform.COMMON, action) -} -abstract class SuspendTransformPluginExtension @Inject constructor(objects: ObjectFactory) { - /** - * Enabled plugin. - * - * Default is `true`. - */ - abstract val enabled: Property + // JVM defaults + fun addJvmBlocking() { + addJvm(jvmBlockingTransformer) + } - val transformers: TransformerContainer = - objects.newInstance() + fun addJvmBlocking(action: Action) { + addJvm { + it.from(jvmBlockingTransformer) + action.execute(it) + } + } - fun transformers(action: Action) { - action.execute(transformers) + fun addJvmAsync() { + addJvm(jvmAsyncTransformer) } - fun addJvmBlockingTransformer() { - transformers.addJvm(SuspendTransformConfigurations.jvmBlockingTransformer) + fun addJvmAsync(action: Action) { + addJvm { + it.from(jvmAsyncTransformer) + action.execute(it) + } } - fun addJvmAsyncTransformer() { - transformers.addJvm(SuspendTransformConfigurations.jvmAsyncTransformer) + // JS defaults + + /** + * Add [jsPromiseTransformer] + */ + fun addJsPromise() { + addJs(jsPromiseTransformer) } - fun useJvmDefault() { - addJvmBlockingTransformer() - addJvmAsyncTransformer() + /** + * Add a js transformer based on [jsPromiseTransformer] + */ + fun addJsPromise(action: Action) { + addJs { + it.from(jsPromiseTransformer) + action.execute(it) + } } - fun addJsPromiseTransformer() { - transformers.addJs(SuspendTransformConfigurations.jsPromiseTransformer) + fun useJvmDefault() { + addJvmBlocking() + addJvmAsync() } fun useJsDefault() { - addJsPromiseTransformer() + addJsPromise() } fun useDefault() { useJvmDefault() useJsDefault() } +} + +/** + * @since 0.12.0 + */ +abstract class SuspendTransformPluginExtension +@Inject constructor(objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { + /** + * Enabled plugin. + * + * Default is `true`. + */ + abstract val enabled: Property + + val transformers: TransformerContainer = objects.newInstance() + + fun transformers(action: Action) { + action.execute(transformers) + } /** * Include the `love.forte.plugin.suspend-transform:suspend-transform-annotation`. @@ -142,17 +194,28 @@ abstract class SuspendTransformPluginExtension @Inject constructor(objects: Obje internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransformConfiguration { return SuspendTransformConfiguration( enabled = enabled.getOrElse(true), - transformers = transformers.transformers.mapValuesTo(mutableMapOf()) { (_, values) -> - values.map { valueList -> valueList.map { it.toTransformer() } }.getOrElse(emptyList()) - } + transformers = buildMap { + transformers.transformers.forEach { (k, values) -> + val list = values.map { valueList -> valueList.map { it.toTransformer() } }.getOrElse(emptyList()) + if (list.isNotEmpty()) { + put(k, list) + } + } + }, ) } -sealed interface DependencySpec { +/** + * @since 0.12.0 + */ +sealed interface DependencySpec : SuspendTransformPluginExtensionSpec { val version: Property val configurationName: Property } +/** + * @since 0.12.0 + */ interface AnnotationDependencySpec : DependencySpec { /** * Default is `compileOnly`. @@ -165,6 +228,9 @@ interface AnnotationDependencySpec : DependencySpec { override val version: Property } +/** + * @since 0.12.0 + */ interface RuntimeDependencySpec : DependencySpec { /** * Default is `implementation`. @@ -198,7 +264,11 @@ internal fun SuspendTransformPluginExtension.defaults( }) } -abstract class TransformerSpec @Inject constructor(private val objects: ObjectFactory) { +/** + * @since 0.12.0 + */ +abstract class TransformerSpec +@Inject constructor(private val objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { /** * @see Transformer.markAnnotation */ @@ -266,6 +336,10 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa val transformReturnTypeGeneric: Property = objects.property(Boolean::class.java).convention(false) + fun transformReturnTypeGeneric() { + transformReturnTypeGeneric.set(true) + } + /** * 函数生成后,需要在原函数上追加的注解信息。 * @@ -276,6 +350,10 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa private fun newIncludeAnnotationSpec(): IncludeAnnotationSpec = objects.newInstance() + fun createIncludeAnnotation(action: Action): IncludeAnnotationSpec { + return newIncludeAnnotationSpec().also(action::execute) + } + fun addOriginFunctionIncludeAnnotation(action: Action) { originFunctionIncludeAnnotations.add( newIncludeAnnotationSpec().also(action::execute) @@ -285,9 +363,7 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa abstract val syntheticFunctionIncludeAnnotations: DomainObjectSet fun addSyntheticFunctionIncludeAnnotation(action: Action) { - syntheticFunctionIncludeAnnotations.add( - newIncludeAnnotationSpec().also(action::execute) - ) + syntheticFunctionIncludeAnnotations.add(createIncludeAnnotation(action)) } /** @@ -299,13 +375,27 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa val copyAnnotationsToSyntheticFunction: Property = objects.property(Boolean::class.java).convention(false) + fun copyAnnotationsToSyntheticFunction() { + copyAnnotationsToSyntheticFunction.set(true) + } + /** * 复制原函数上注解时需要排除掉的注解。 */ abstract val copyAnnotationExcludes: DomainObjectSet + /** + * Add a [ClassInfoSpec] into [copyAnnotationExcludes] + */ fun addCopyAnnotationExclude(action: Action) { - copyAnnotationExcludes.add(objects.newInstance().also(action::execute)) + copyAnnotationExcludes.add(createCopyAnnotationExclude(action)) + } + + /** + * Create a [ClassInfoSpec] but does not add. + */ + fun createCopyAnnotationExclude(action: Action): ClassInfoSpec { + return objects.newInstance().also(action::execute) } /** @@ -316,6 +406,10 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa val copyAnnotationsToSyntheticProperty: Property = objects.property(Boolean::class.java).convention(false) + fun copyAnnotationsToSyntheticProperty() { + copyAnnotationsToSyntheticProperty.set(true) + } + /** * Configures the current specification using a [Transformer]. * @@ -356,7 +450,11 @@ abstract class TransformerSpec @Inject constructor(private val objects: ObjectFa /** * @see MarkAnnotation */ -abstract class MarkAnnotationSpec @Inject constructor(private val objects: ObjectFactory) { +/** + * @since 0.12.0 + */ +abstract class MarkAnnotationSpec +@Inject constructor(private val objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { /** * The mark annotation's class info. */ @@ -419,7 +517,10 @@ abstract class MarkAnnotationSpec @Inject constructor(private val objects: Objec /** * @see ClassInfo */ -interface ClassInfoSpec { +/** + * @since 0.12.0 + */ +interface ClassInfoSpec : SuspendTransformPluginExtensionSpec { val packageName: Property val className: Property @@ -441,7 +542,10 @@ interface ClassInfoSpec { } } -interface FunctionInfoSpec { +/** + * @since 0.12.0 + */ +interface FunctionInfoSpec : SuspendTransformPluginExtensionSpec { val packageName: Property val functionName: Property @@ -451,7 +555,11 @@ interface FunctionInfoSpec { } } -abstract class IncludeAnnotationSpec @Inject constructor(private val objects: ObjectFactory) { +/** + * @since 0.12.0 + */ +abstract class IncludeAnnotationSpec +@Inject constructor(private val objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { abstract val classInfo: Property fun classInfo(action: Action) { @@ -485,7 +593,8 @@ internal fun TransformerSpec.toTransformer(): Transformer { transformReturnType = transformReturnType.orNull?.toClassInfo(), transformReturnTypeGeneric = transformReturnTypeGeneric.getOrElse(false), originFunctionIncludeAnnotations = originFunctionIncludeAnnotations.map { it.toIncludeAnnotation() }.toList(), - syntheticFunctionIncludeAnnotations = syntheticFunctionIncludeAnnotations.map { it.toIncludeAnnotation() }.toList(), + syntheticFunctionIncludeAnnotations = syntheticFunctionIncludeAnnotations.map { it.toIncludeAnnotation() } + .toList(), copyAnnotationsToSyntheticFunction = copyAnnotationsToSyntheticFunction.getOrElse(false), copyAnnotationExcludes = copyAnnotationExcludes.map { it.toClassInfo() }.toList(), copyAnnotationsToSyntheticProperty = copyAnnotationsToSyntheticProperty.get() diff --git a/settings.gradle.kts b/settings.gradle.kts index ffeb6f5..63e8f53 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,7 +35,7 @@ include(":plugins:suspend-transform-plugin-gradle") // include(":local-helper") //Samples -include(":tests:test-jvm") +// include(":tests:test-jvm") // include(":tests:test-js") // include(":tests:test-kmp") // include(":tests:test-android") diff --git a/tests/build.gradle.kts b/tests/build.gradle.kts new file mode 100644 index 0000000..98948c1 --- /dev/null +++ b/tests/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("love.forte.plugin.suspend-transform") version "2.1.20-0.12.0" apply false +} diff --git a/tests/test-js/build.gradle.kts b/tests/test-js/build.gradle.kts index a5cbd9b..60fb60a 100644 --- a/tests/test-js/build.gradle.kts +++ b/tests/test-js/build.gradle.kts @@ -1,22 +1,9 @@ -import love.forte.plugin.suspendtrans.ClassInfo -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration -import love.forte.plugin.suspendtrans.TargetPlatform -import love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.kotlinJsExportIgnoreClassInfo import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi plugins { kotlin("multiplatform") -} - - -buildscript { - this@buildscript.repositories { - mavenLocal() - mavenCentral() - } - dependencies { - classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:2.1.0-0.11.1") - } + id("love.forte.plugin.suspend-transform") } repositories { @@ -64,16 +51,46 @@ kotlin { } } -extensions.getByType().apply { +// suspendTransformPlugin { +// includeRuntime = false +// includeAnnotation = false +// transformers { +// addJsPromise { +// addCopyAnnotationExclude { +// from(kotlinJsExportIgnoreClassInfo) +// } +// } +// } +// } + +suspendTransformPlugin { includeRuntime = false includeAnnotation = false + transformers { + addJsPromise { + addOriginFunctionIncludeAnnotation { + classInfo { + from(kotlinJsExportIgnoreClassInfo) + } + } - transformers[TargetPlatform.JS] = mutableListOf( - SuspendTransformConfiguration.jsPromiseTransformer.copy( - copyAnnotationExcludes = listOf( - ClassInfo("kotlin.js", "JsExport.Ignore") - ) - ) - ) - + addCopyAnnotationExclude { + from(kotlinJsExportIgnoreClassInfo) + } + } + } } + +// extensions.getByType().apply { +// includeRuntime = false +// includeAnnotation = false +// +// transformers[TargetPlatform.JS] = mutableListOf( +// SuspendTransformConfiguration.jsPromiseTransformer.copy( +// copyAnnotationExcludes = listOf( +// ClassInfo("kotlin.js", "JsExport.Ignore") +// ) +// ) +// ) +// +// } diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index 85e7a74..73f46cb 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -1,17 +1,7 @@ -// buildscript { -// this@buildscript.repositories { -// mavenLocal() -// mavenCentral() -// } -// dependencies { -// classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:2.1.20-0.12.0") -// } -// } - plugins { `java-library` kotlin("jvm") - id("love.forte.plugin.suspend-transform") version "2.1.20-0.12.0" + id("love.forte.plugin.suspend-transform") // id("suspend-transform.jvm-maven-publish") // id(project(":suspend-transform-plugin-gradle")) } @@ -38,11 +28,64 @@ dependencies { api(libs.kotlinx.coroutines.core) } -suspendTransform { +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + // For blocking + addJvm { + markAnnotation { + classInfo { + packageName = "com.example" + className = "JTrans" + } + baseNameProperty = "blockingBaseName" + suffixProperty = "blockingSuffix" + asPropertyProperty = "blockingAsProperty" + defaultSuffix = "Blocking" + defaultAsProperty = false + } + + transformFunctionInfo { + packageName = "com.example" + functionName = "inBlock" + } + + // other config... + } - enabled = true + // For async + addJvm { + markAnnotation { + classInfo { + packageName = "com.example" + className = "JTrans" + } + baseNameProperty = "asyncBaseName" + suffixProperty = "asyncSuffix" + asPropertyProperty = "asyncAsProperty" + defaultSuffix = "Async" + defaultAsProperty = false + } + + transformFunctionInfo { + packageName = "com.example" + functionName = "inAsync" + } + } + } } +/* +> val blockingBaseName: String = "", +> val blockingSuffix: String = "Blocking", +> val blockingAsProperty: Boolean = false, +> +> val asyncBaseName: String = "", +> val asyncSuffix: String = "Async", +> val asyncAsProperty: Boolean = false + */ + tasks.withType { useJUnitPlatform() } diff --git a/tests/test-kmp/build.gradle.kts b/tests/test-kmp/build.gradle.kts index 5ddee77..f80b29b 100644 --- a/tests/test-kmp/build.gradle.kts +++ b/tests/test-kmp/build.gradle.kts @@ -1,22 +1,9 @@ -import love.forte.plugin.suspendtrans.ClassInfo -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration.Companion.jvmAsyncTransformer -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration.Companion.jvmBlockingTransformer -import love.forte.plugin.suspendtrans.TargetPlatform -import love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.kotlinJsExportIgnoreClassInfo +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.kotlinOptInClassInfo plugins { kotlin("multiplatform") -} - - -buildscript { - this@buildscript.repositories { - mavenLocal() - mavenCentral() - } - dependencies { - classpath("love.forte.plugin.suspend-transform:suspend-transform-plugin-gradle:2.1.0-0.11.1") - } + id("love.forte.plugin.suspend-transform") } kotlin { @@ -36,6 +23,19 @@ kotlin { jvm() js { nodejs() + + useEsModules() + generateTypeScriptDefinitions() + binaries.executable() + + compilerOptions { + target = "es2015" + useEsClasses = true + freeCompilerArgs.addAll( + // https://kotlinlang.org/docs/whatsnew20.html#per-file-compilation-for-kotlin-js-projects + "-Xir-per-file", + ) + } } sourceSets { @@ -48,29 +48,55 @@ kotlin { } } -extensions.getByType().apply { +suspendTransformPlugin { includeRuntime = false includeAnnotation = false -// useJvmDefault() - transformers[TargetPlatform.JVM] = mutableListOf( - // Add `kotlin.OptIn` to copyAnnotationExcludes - jvmBlockingTransformer.copy( - copyAnnotationExcludes = buildList { - addAll(jvmBlockingTransformer.copyAnnotationExcludes) - add(ClassInfo("kotlin", "OptIn")) + transformers { + addJvmBlocking { + addCopyAnnotationExclude { + from(kotlinOptInClassInfo) } - ), + } + addJvmAsync { + addCopyAnnotationExclude { + from(kotlinOptInClassInfo) + } + } - // Add `kotlin.OptIn` to copyAnnotationExcludes - jvmAsyncTransformer.copy( - copyAnnotationExcludes = buildList { - addAll(jvmAsyncTransformer.copyAnnotationExcludes) - add(ClassInfo("kotlin", "OptIn")) + addJsPromise { + addCopyAnnotationExclude { + from(kotlinOptInClassInfo) + } + addCopyAnnotationExclude { + from(kotlinJsExportIgnoreClassInfo) } - ) - ) + } + } } +// extensions.getByType().apply { +// includeRuntime = false +// includeAnnotation = false +// // useJvmDefault() +// transformers[TargetPlatform.JVM] = mutableListOf( +// // Add `kotlin.OptIn` to copyAnnotationExcludes +// jvmBlockingTransformer.copy( +// copyAnnotationExcludes = buildList { +// addAll(jvmBlockingTransformer.copyAnnotationExcludes) +// add(ClassInfo("kotlin", "OptIn")) +// } +// ), +// +// // Add `kotlin.OptIn` to copyAnnotationExcludes +// jvmAsyncTransformer.copy( +// copyAnnotationExcludes = buildList { +// addAll(jvmAsyncTransformer.copyAnnotationExcludes) +// add(ClassInfo("kotlin", "OptIn")) +// } +// ) +// ) +// } + tasks.withType { useJUnitPlatform() } diff --git a/tests/test-kmp/src/commonMain/kotlin/example/MyClass.kt b/tests/test-kmp/src/commonMain/kotlin/example/MyClass.kt index 1c20a34..a15eeeb 100644 --- a/tests/test-kmp/src/commonMain/kotlin/example/MyClass.kt +++ b/tests/test-kmp/src/commonMain/kotlin/example/MyClass.kt @@ -1,10 +1,19 @@ package example +import love.forte.plugin.suspendtrans.annotation.JsPromise +import love.forte.plugin.suspendtrans.annotation.JvmAsync import love.forte.plugin.suspendtrans.annotation.JvmBlocking +import kotlin.js.ExperimentalJsExport +import kotlin.js.JsExport expect class MoneyValue +@OptIn(ExperimentalJsExport::class) +@JsExport class MyClass { @JvmBlocking + @JvmAsync + @JsPromise + @JsExport.Ignore suspend fun errorReproduction(amount: MoneyValue) = println(amount) } diff --git a/tests/test-kmp/src/jsMain/kotlin/example/MyClass.js.kt b/tests/test-kmp/src/jsMain/kotlin/example/MyClass.js.kt index 13f4705..9c41c23 100644 --- a/tests/test-kmp/src/jsMain/kotlin/example/MyClass.js.kt +++ b/tests/test-kmp/src/jsMain/kotlin/example/MyClass.js.kt @@ -1,3 +1,5 @@ package example -actual class MoneyValue +// actual class MoneyValue + +actual typealias MoneyValue = Double From fda2fddd21d1a623709812ac2f179aa605b2dfba Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Tue, 15 Apr 2025 18:50:50 +0800 Subject: [PATCH 07/21] Where's my `.asm.txt` and `.fir.ir.txt` files? --- README.md | 2 +- README_CN.md | 2 +- .../cli/SuspendTransformCliOption.kt | 4 +- .../suspend-transform-plugin/build.gradle.kts | 1 + .../fir/SuspendTransformFirTransformer.kt | 10 +- .../runners/AbstractCodeGenTestRunner.kt | 5 +- .../runners/AbstractTestRunner.kt | 2 +- .../codegen/implOverridenGeneric.asm.txt | 449 ------------ .../codegen/implOverridenGeneric.fir.ir.txt | 651 ------------------ .../codegen/implOverridenGeneric.fir.txt | 14 +- .../codegen/implOverridenGeneric.fir.ir.txt | 76 +- .../codegen/implOverridenGeneric.fir.txt | 14 +- .../src/main/resources/META-INF/plugin.xml | 2 +- .../gradle/SuspendTransformGradlePlugin.kt | 4 +- 14 files changed, 70 insertions(+), 1166 deletions(-) delete mode 100644 compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.asm.txt delete mode 100644 compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.ir.txt diff --git a/README.md b/README.md index 872bf27..1aed3ed 100644 --- a/README.md +++ b/README.md @@ -1068,7 +1068,7 @@ copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR love.forte.plugin.suspendtrans.A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE diff --git a/README_CN.md b/README_CN.md index e992836..411935c 100644 --- a/README_CN.md +++ b/README_CN.md @@ -752,7 +752,7 @@ copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR love.forte.plugin.suspendtrans.A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE diff --git a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt index a4713cf..2b58567 100644 --- a/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt +++ b/compiler/suspend-transform-plugin-cli/src/main/kotlin/love/forte/plugin/suspendtrans/cli/SuspendTransformCliOption.kt @@ -35,8 +35,8 @@ private data class AbstractCliOptionImpl( * Creates an instance of [SuspendTransformCliOption] to describe and define a CLI option. * * @param optionName The name of the option used to identify it in the CLI. - * @param valueDescription love.forte.plugin.suspendtrans.A description of the option's value, defaults to the option name. - * @param description love.forte.plugin.suspendtrans.A textual description of the option, defaults to an empty string. + * @param valueDescription A description of the option's value, defaults to the option name. + * @param description A textual description of the option, defaults to an empty string. * @param required Whether this option is mandatory, defaults to not required (`false`). * @param allowMultipleOccurrences Whether this option can appear multiple times in the CLI, * defaults to not allowed (`false`). diff --git a/compiler/suspend-transform-plugin/build.gradle.kts b/compiler/suspend-transform-plugin/build.gradle.kts index 04e55ec..1cf4824 100644 --- a/compiler/suspend-transform-plugin/build.gradle.kts +++ b/compiler/suspend-transform-plugin/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { api(project(":compiler:suspend-transform-plugin-deprecated-configuration")) api(project(":compiler:suspend-transform-plugin-cli")) + testImplementation("junit:junit:4.13.2") testImplementation(kotlin("stdlib")) testImplementation(kotlin("test-junit5")) diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt index f3c774d..3a456f0 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt @@ -385,7 +385,7 @@ class SuspendTransformFirTransformer( source = thisReceiverParameter.source calleeReference = buildImplicitThisReference { boundSymbol = thisReceiverParameter.symbol - println("[${newFunSymbol}] thisReceiverParameter.symbol: ${thisReceiverParameter.symbol}") + // println("[${newFunSymbol}] thisReceiverParameter.symbol: ${thisReceiverParameter.symbol}") } } } @@ -608,11 +608,11 @@ class SuspendTransformFirTransformer( // Copy the typeParameters. // Otherwise, in functions like the following, an error will occur - // suspend fun data(value: love.forte.plugin.suspendtrans.A): T = ... - // Functions for which function-scoped generalizations (``) exist. - // In the generated IR, data and dataBlocking will share an `love.forte.plugin.suspendtrans.A`, generating the error. + // suspend fun data(value: A): T = ... + // Functions for which function-scoped generalizations (``) exist. + // In the generated IR, data and dataBlocking will share an `A`, generating the error. // The error: Duplicate IR node - // [IR VALIDATION] JvmIrValidationBeforeLoweringPhase: Duplicate IR node: TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false of FUN GENERATED[...] + // [IR VALIDATION] JvmIrValidationBeforeLoweringPhase: Duplicate IR node: TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false of FUN GENERATED[...] copyParameters() // resolve returnType (with wrapped) after copyParameters diff --git a/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/runners/AbstractCodeGenTestRunner.kt b/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/runners/AbstractCodeGenTestRunner.kt index 2f441de..3f3d5b3 100644 --- a/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/runners/AbstractCodeGenTestRunner.kt +++ b/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/runners/AbstractCodeGenTestRunner.kt @@ -17,7 +17,10 @@ abstract class AbstractCodeGenTestRunner : AbstractTestRunner() { override fun TestConfigurationBuilder.configureHandlers() { configureFirHandlersStep { useHandlers( - ::FirDumpHandler, ::FirCfgDumpHandler, ::FirResolvedTypesVerifier, ::FirDiagnosticsHandler, + ::FirDumpHandler, + ::FirCfgDumpHandler, + ::FirResolvedTypesVerifier, + ::FirDiagnosticsHandler, ) } diff --git a/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/runners/AbstractTestRunner.kt b/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/runners/AbstractTestRunner.kt index ae18f7e..d907052 100644 --- a/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/runners/AbstractTestRunner.kt +++ b/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/runners/AbstractTestRunner.kt @@ -42,6 +42,7 @@ abstract class AbstractTestRunner : AbstractKotlinCompilerTest() { backendKind = BackendKinds.IrBackendForK1AndK2 // this.languageVersionSettings + // languageSettings { // languageVersion = LanguageVersion.KOTLIN_2_1 // apiVersion = ApiVersion.KOTLIN_2_1 @@ -54,7 +55,6 @@ abstract class AbstractTestRunner : AbstractKotlinCompilerTest() { builder.defaultDirectives { FIR_PARSER with FirParser.LightTree - } when (targetFrontend) { diff --git a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.asm.txt b/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.asm.txt deleted file mode 100644 index 2429b42..0000000 --- a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.asm.txt +++ /dev/null @@ -1,449 +0,0 @@ -public abstract interface Bar : java/lang/Object, Foo { - -} - -public abstract interface Foo : java/lang/Object { - -} - -public abstract interface FooInterface1 : java/lang/Object { - public abstract java.lang.Object data(kotlin.coroutines.Continuation p0) - - public abstract java.lang.Object data2(java.lang.Object p0, kotlin.coroutines.Continuation p1) - - public abstract java.lang.Object data3(int p0, kotlin.coroutines.Continuation p1) -} - -final class FooInterface1Impl$data2Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final java.lang.Object $value - - int label - - final FooInterface1Impl this$0 - - void (FooInterface1Impl $receiver, java.lang.Object $value, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface1Impl$data3Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final int $this_data3Blocking - - int label - - final FooInterface1Impl this$0 - - void (FooInterface1Impl $receiver, int $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface1Impl$dataBlocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - int label - - final FooInterface1Impl this$0 - - void (FooInterface1Impl $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -public final class FooInterface1Impl : java/lang/Object, FooInterface1 { - public void () - - public java.lang.Object data(kotlin.coroutines.Continuation $completion) - - public java.lang.Object data2(java.lang.Object value, kotlin.coroutines.Continuation $completion) - - public Bar data2Blocking(java.lang.Object value) - - public java.lang.Object data3(int $this$data3, kotlin.coroutines.Continuation $completion) - - public Bar data3Blocking(int $this$data3Blocking) - - public Bar dataBlocking() -} - -public abstract interface FooInterface2 : java/lang/Object { - public abstract java.lang.Object data(kotlin.coroutines.Continuation p0) - - public abstract java.lang.Object data2(Foo p0, kotlin.coroutines.Continuation p1) - - public abstract java.lang.Object data3(int p0, kotlin.coroutines.Continuation p1) -} - -final class FooInterface2Impl$data2Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final Foo $value - - int label - - final FooInterface2Impl this$0 - - void (FooInterface2Impl $receiver, Foo $value, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface2Impl$data3Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final int $this_data3Blocking - - int label - - final FooInterface2Impl this$0 - - void (FooInterface2Impl $receiver, int $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface2Impl$dataBlocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - int label - - final FooInterface2Impl this$0 - - void (FooInterface2Impl $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -public final class FooInterface2Impl : java/lang/Object, FooInterface2 { - public void () - - public java.lang.Object data(kotlin.coroutines.Continuation $completion) - - public java.lang.Object data2(Foo value, kotlin.coroutines.Continuation $completion) - - public Foo data2Blocking(Foo value) - - public java.lang.Object data3(int $this$data3, kotlin.coroutines.Continuation $completion) - - public Foo data3Blocking(int $this$data3Blocking) - - public Foo dataBlocking() -} - -public final class FooInterface3$DefaultImpls : java/lang/Object { - public static Foo data2Blocking(FooInterface3 $this, java.lang.Object value) - - public static Foo data3Blocking(FooInterface3 $this, int $receiver) - - public static Foo dataBlocking(FooInterface3 $this) -} - -final class FooInterface3$data2Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final java.lang.Object $value - - int label - - final FooInterface3 this$0 - - void (FooInterface3 $receiver, java.lang.Object $value, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface3$data3Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final int $this_data3Blocking - - int label - - final FooInterface3 this$0 - - void (FooInterface3 $receiver, int $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface3$dataBlocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - int label - - final FooInterface3 this$0 - - void (FooInterface3 $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -public abstract interface FooInterface3 : java/lang/Object { - public abstract java.lang.Object data(kotlin.coroutines.Continuation p0) - - public abstract java.lang.Object data2(java.lang.Object p0, kotlin.coroutines.Continuation p1) - - public abstract Foo data2Blocking(java.lang.Object p0) - - public abstract java.lang.Object data3(int p0, kotlin.coroutines.Continuation p1) - - public abstract Foo data3Blocking(int p0) - - public abstract Foo dataBlocking() -} - -final class FooInterface3Impl$data2Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final java.lang.Object $value - - int label - - final FooInterface3Impl this$0 - - void (FooInterface3Impl $receiver, java.lang.Object $value, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface3Impl$data3Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final int $this_data3Blocking - - int label - - final FooInterface3Impl this$0 - - void (FooInterface3Impl $receiver, int $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface3Impl$dataBlocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - int label - - final FooInterface3Impl this$0 - - void (FooInterface3Impl $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -public final class FooInterface3Impl : java/lang/Object, FooInterface3 { - public void () - - public java.lang.Object data(kotlin.coroutines.Continuation $completion) - - public java.lang.Object data2(java.lang.Object value, kotlin.coroutines.Continuation $completion) - - public Bar data2Blocking(java.lang.Object value) - - public Foo data2Blocking(java.lang.Object value) - - public java.lang.Object data3(int $this$data3, kotlin.coroutines.Continuation $completion) - - public Bar data3Blocking(int $this$data3Blocking) - - public Foo data3Blocking(int $this$data3Blocking) - - public Bar dataBlocking() - - public Foo dataBlocking() -} - -public final class FooInterface4$DefaultImpls : java/lang/Object { - public static Foo data2Blocking(FooInterface4 $this, Foo value) - - public static Foo data3Blocking(FooInterface4 $this, int $receiver) - - public static Foo dataBlocking(FooInterface4 $this) -} - -final class FooInterface4$data2Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final Foo $value - - int label - - final FooInterface4 this$0 - - void (FooInterface4 $receiver, Foo $value, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface4$data3Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final int $this_data3Blocking - - int label - - final FooInterface4 this$0 - - void (FooInterface4 $receiver, int $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface4$dataBlocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - int label - - final FooInterface4 this$0 - - void (FooInterface4 $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -public abstract interface FooInterface4 : java/lang/Object { - public abstract java.lang.Object data(kotlin.coroutines.Continuation p0) - - public abstract java.lang.Object data2(Foo p0, kotlin.coroutines.Continuation p1) - - public abstract Foo data2Blocking(Foo p0) - - public abstract java.lang.Object data3(int p0, kotlin.coroutines.Continuation p1) - - public abstract Foo data3Blocking(int p0) - - public abstract Foo dataBlocking() -} - -final class FooInterface4Impl$data2Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final Foo $value - - int label - - final FooInterface4Impl this$0 - - void (FooInterface4Impl $receiver, Foo $value, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface4Impl$data3Blocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - final int $this_data3Blocking - - int label - - final FooInterface4Impl this$0 - - void (FooInterface4Impl $receiver, int $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -final class FooInterface4Impl$dataBlocking$1 : kotlin/coroutines/jvm/internal/SuspendLambda, kotlin/jvm/functions/Function1 { - int label - - final FooInterface4Impl this$0 - - void (FooInterface4Impl $receiver, kotlin.coroutines.Continuation $completion) - - public final kotlin.coroutines.Continuation create(kotlin.coroutines.Continuation $completion) - - public final java.lang.Object invoke(kotlin.coroutines.Continuation p1) - - public java.lang.Object invoke(java.lang.Object p1) - - public final java.lang.Object invokeSuspend(java.lang.Object $result) -} - -public final class FooInterface4Impl : java/lang/Object, FooInterface4 { - public void () - - public java.lang.Object data(kotlin.coroutines.Continuation $completion) - - public java.lang.Object data2(Foo value, kotlin.coroutines.Continuation $completion) - - public Foo data2Blocking(Foo value) - - public java.lang.Object data3(int $this$data3, kotlin.coroutines.Continuation $completion) - - public Foo data3Blocking(int $this$data3Blocking) - - public Foo dataBlocking() -} diff --git a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.ir.txt b/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.ir.txt deleted file mode 100644 index bd320c5..0000000 --- a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.ir.txt +++ /dev/null @@ -1,651 +0,0 @@ -FILE fqName: fileName:/Main.kt - CLASS CLASS name:FooInterface1Impl modality:FINAL visibility:public superTypes:[.FooInterface1.FooInterface1Impl>] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FooInterface1Impl.FooInterface1Impl> - TYPE_PARAMETER name:T index:0 variance: superTypes:[.Bar] reified:false - CONSTRUCTOR visibility:public <> () returnType:.FooInterface1Impl.FooInterface1Impl> [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:FooInterface1Impl modality:FINAL visibility:public superTypes:[.FooInterface1.FooInterface1Impl>]' - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .FooInterface1 - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in .FooInterface1 - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in .FooInterface1 - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking) returnType:T of .FooInterface1Impl - annotations: - Api4J - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false - $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking): T of .FooInterface1Impl declared in .FooInterface1Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface1Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface1Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface1Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface1Impl declared in .FooInterface1Impl.data2Blocking' - CALL 'public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null - : - $this: GET_VAR ': .FooInterface1Impl.FooInterface1Impl> declared in .FooInterface1Impl.data2Blocking' type=.FooInterface1Impl.FooInterface1Impl> origin=null - value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking declared in .FooInterface1Impl.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface1Impl - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3Blocking (): T of .FooInterface1Impl declared in .FooInterface1Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface1Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface1Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface1Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface1Impl declared in .FooInterface1Impl.data3Blocking' - CALL 'public open fun data3 (): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null - $this: GET_VAR ': .FooInterface1Impl.FooInterface1Impl> declared in .FooInterface1Impl.data3Blocking' type=.FooInterface1Impl.FooInterface1Impl> origin=null - $receiver: GET_VAR ': kotlin.Int declared in .FooInterface1Impl.data3Blocking' type=kotlin.Int origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:dataBlocking visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>) returnType:T of .FooInterface1Impl - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun dataBlocking (): T of .FooInterface1Impl declared in .FooInterface1Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface1Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface1Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface1Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface1Impl declared in .FooInterface1Impl.dataBlocking' - CALL 'public open fun data (): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null - $this: GET_VAR ': .FooInterface1Impl.FooInterface1Impl> declared in .FooInterface1Impl.dataBlocking' type=.FooInterface1Impl.FooInterface1Impl> origin=null - FUN name:data visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>) returnType:T of .FooInterface1Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data (): T of .FooInterface1 declared in .FooInterface1 - $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface1Impl declared in .FooInterface1Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2) returnType:T of .FooInterface1Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1.data2): T of .FooInterface1 declared in .FooInterface1 - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false - $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2 - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface1Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data3 (): T of .FooInterface1 declared in .FooInterface1 - $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3 (): T of .FooInterface1Impl declared in .FooInterface1Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - CLASS CLASS name:FooInterface2Impl modality:FINAL visibility:public superTypes:[.FooInterface2.FooInterface2Impl>] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FooInterface2Impl.FooInterface2Impl> - TYPE_PARAMETER name:T index:0 variance: superTypes:[.Foo] reified:false - CONSTRUCTOR visibility:public <> () returnType:.FooInterface2Impl.FooInterface2Impl> [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:FooInterface2Impl modality:FINAL visibility:public superTypes:[.FooInterface2.FooInterface2Impl>]' - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .FooInterface2 - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in .FooInterface2 - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in .FooInterface2 - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN <> ($this:.FooInterface2Impl.FooInterface2Impl>, value:T of .FooInterface2Impl) returnType:T of .FooInterface2Impl - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface2Impl.FooInterface2Impl> - VALUE_PARAMETER name:value index:0 type:T of .FooInterface2Impl - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: T of .FooInterface2Impl): T of .FooInterface2Impl declared in .FooInterface2Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface2Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface2Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface2Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface2Impl declared in .FooInterface2Impl.data2Blocking' - CALL 'public open fun data2 (value: T of .FooInterface2Impl): T of .FooInterface2Impl declared in .FooInterface2Impl' type=T of .FooInterface2Impl origin=null - $this: GET_VAR ': .FooInterface2Impl.FooInterface2Impl> declared in .FooInterface2Impl.data2Blocking' type=.FooInterface2Impl.FooInterface2Impl> origin=null - value: GET_VAR 'value: T of .FooInterface2Impl declared in .FooInterface2Impl.data2Blocking' type=T of .FooInterface2Impl origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface2Impl.FooInterface2Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface2Impl - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface2Impl.FooInterface2Impl> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3Blocking (): T of .FooInterface2Impl declared in .FooInterface2Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface2Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface2Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface2Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface2Impl declared in .FooInterface2Impl.data3Blocking' - CALL 'public open fun data3 (): T of .FooInterface2Impl declared in .FooInterface2Impl' type=T of .FooInterface2Impl origin=null - $this: GET_VAR ': .FooInterface2Impl.FooInterface2Impl> declared in .FooInterface2Impl.data3Blocking' type=.FooInterface2Impl.FooInterface2Impl> origin=null - $receiver: GET_VAR ': kotlin.Int declared in .FooInterface2Impl.data3Blocking' type=kotlin.Int origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:dataBlocking visibility:public modality:OPEN <> ($this:.FooInterface2Impl.FooInterface2Impl>) returnType:T of .FooInterface2Impl - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface2Impl.FooInterface2Impl> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun dataBlocking (): T of .FooInterface2Impl declared in .FooInterface2Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface2Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface2Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface2Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface2Impl declared in .FooInterface2Impl.dataBlocking' - CALL 'public open fun data (): T of .FooInterface2Impl declared in .FooInterface2Impl' type=T of .FooInterface2Impl origin=null - $this: GET_VAR ': .FooInterface2Impl.FooInterface2Impl> declared in .FooInterface2Impl.dataBlocking' type=.FooInterface2Impl.FooInterface2Impl> origin=null - FUN name:data visibility:public modality:OPEN <> ($this:.FooInterface2Impl.FooInterface2Impl>) returnType:T of .FooInterface2Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data (): T of .FooInterface2 declared in .FooInterface2 - $this: VALUE_PARAMETER name: type:.FooInterface2Impl.FooInterface2Impl> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface2Impl declared in .FooInterface2Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN <> ($this:.FooInterface2Impl.FooInterface2Impl>, value:T of .FooInterface2Impl) returnType:T of .FooInterface2Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data2 (value: T of .FooInterface2): T of .FooInterface2 declared in .FooInterface2 - $this: VALUE_PARAMETER name: type:.FooInterface2Impl.FooInterface2Impl> - VALUE_PARAMETER name:value index:0 type:T of .FooInterface2Impl - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: T of .FooInterface2Impl): T of .FooInterface2Impl declared in .FooInterface2Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface2Impl.FooInterface2Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface2Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data3 (): T of .FooInterface2 declared in .FooInterface2 - $this: VALUE_PARAMETER name: type:.FooInterface2Impl.FooInterface2Impl> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3 (): T of .FooInterface2Impl declared in .FooInterface2Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - CLASS CLASS name:FooInterface3Impl modality:FINAL visibility:public superTypes:[.FooInterface3.FooInterface3Impl>] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FooInterface3Impl.FooInterface3Impl> - TYPE_PARAMETER name:T index:0 variance: superTypes:[.Bar] reified:false - CONSTRUCTOR visibility:public <> () returnType:.FooInterface3Impl.FooInterface3Impl> [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:FooInterface3Impl modality:FINAL visibility:public superTypes:[.FooInterface3.FooInterface3Impl>]' - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .FooInterface3 - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in .FooInterface3 - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in .FooInterface3 - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking) returnType:T of .FooInterface3Impl - annotations: - Api4J - overridden: - public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3 - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false - $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking): T of .FooInterface3Impl declared in .FooInterface3Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface3Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3Impl declared in .FooInterface3Impl.data2Blocking' - CALL 'public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null - : - $this: GET_VAR ': .FooInterface3Impl.FooInterface3Impl> declared in .FooInterface3Impl.data2Blocking' type=.FooInterface3Impl.FooInterface3Impl> origin=null - value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking declared in .FooInterface3Impl.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface3Impl - annotations: - Api4J - overridden: - public open fun data3Blocking (): T of .FooInterface3 declared in .FooInterface3 - $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3Blocking (): T of .FooInterface3Impl declared in .FooInterface3Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface3Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3Impl declared in .FooInterface3Impl.data3Blocking' - CALL 'public open fun data3 (): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null - $this: GET_VAR ': .FooInterface3Impl.FooInterface3Impl> declared in .FooInterface3Impl.data3Blocking' type=.FooInterface3Impl.FooInterface3Impl> origin=null - $receiver: GET_VAR ': kotlin.Int declared in .FooInterface3Impl.data3Blocking' type=kotlin.Int origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:dataBlocking visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>) returnType:T of .FooInterface3Impl - annotations: - Api4J - overridden: - public open fun dataBlocking (): T of .FooInterface3 declared in .FooInterface3 - $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun dataBlocking (): T of .FooInterface3Impl declared in .FooInterface3Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface3Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3Impl declared in .FooInterface3Impl.dataBlocking' - CALL 'public open fun data (): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null - $this: GET_VAR ': .FooInterface3Impl.FooInterface3Impl> declared in .FooInterface3Impl.dataBlocking' type=.FooInterface3Impl.FooInterface3Impl> origin=null - FUN name:data visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>) returnType:T of .FooInterface3Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data (): T of .FooInterface3 declared in .FooInterface3 - $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface3Impl declared in .FooInterface3Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2) returnType:T of .FooInterface3Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3 - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false - $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2 - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface3Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data3 (): T of .FooInterface3 declared in .FooInterface3 - $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3 (): T of .FooInterface3Impl declared in .FooInterface3Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - CLASS CLASS name:FooInterface4Impl modality:FINAL visibility:public superTypes:[.FooInterface4.FooInterface4Impl>] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FooInterface4Impl.FooInterface4Impl> - TYPE_PARAMETER name:T index:0 variance: superTypes:[.Foo] reified:false - CONSTRUCTOR visibility:public <> () returnType:.FooInterface4Impl.FooInterface4Impl> [primary] - BLOCK_BODY - DELEGATING_CONSTRUCTOR_CALL 'public constructor () declared in kotlin.Any' - INSTANCE_INITIALIZER_CALL classDescriptor='CLASS CLASS name:FooInterface4Impl modality:FINAL visibility:public superTypes:[.FooInterface4.FooInterface4Impl>]' - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN <> ($this:.FooInterface4Impl.FooInterface4Impl>, value:T of .FooInterface4Impl) returnType:T of .FooInterface4Impl - annotations: - Api4J - overridden: - public open fun data2Blocking (value: T of .FooInterface4): T of .FooInterface4 declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:.FooInterface4Impl.FooInterface4Impl> - VALUE_PARAMETER name:value index:0 type:T of .FooInterface4Impl - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: T of .FooInterface4Impl): T of .FooInterface4Impl declared in .FooInterface4Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface4Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface4Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface4Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface4Impl declared in .FooInterface4Impl.data2Blocking' - CALL 'public open fun data2 (value: T of .FooInterface4Impl): T of .FooInterface4Impl declared in .FooInterface4Impl' type=T of .FooInterface4Impl origin=null - $this: GET_VAR ': .FooInterface4Impl.FooInterface4Impl> declared in .FooInterface4Impl.data2Blocking' type=.FooInterface4Impl.FooInterface4Impl> origin=null - value: GET_VAR 'value: T of .FooInterface4Impl declared in .FooInterface4Impl.data2Blocking' type=T of .FooInterface4Impl origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface4Impl.FooInterface4Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface4Impl - annotations: - Api4J - overridden: - public open fun data3Blocking (): T of .FooInterface4 declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:.FooInterface4Impl.FooInterface4Impl> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3Blocking (): T of .FooInterface4Impl declared in .FooInterface4Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface4Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface4Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface4Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface4Impl declared in .FooInterface4Impl.data3Blocking' - CALL 'public open fun data3 (): T of .FooInterface4Impl declared in .FooInterface4Impl' type=T of .FooInterface4Impl origin=null - $this: GET_VAR ': .FooInterface4Impl.FooInterface4Impl> declared in .FooInterface4Impl.data3Blocking' type=.FooInterface4Impl.FooInterface4Impl> origin=null - $receiver: GET_VAR ': kotlin.Int declared in .FooInterface4Impl.data3Blocking' type=kotlin.Int origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:dataBlocking visibility:public modality:OPEN <> ($this:.FooInterface4Impl.FooInterface4Impl>) returnType:T of .FooInterface4Impl - annotations: - Api4J - overridden: - public open fun dataBlocking (): T of .FooInterface4 declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:.FooInterface4Impl.FooInterface4Impl> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun dataBlocking (): T of .FooInterface4Impl declared in .FooInterface4Impl' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface4Impl origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface4Impl> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface4Impl [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface4Impl declared in .FooInterface4Impl.dataBlocking' - CALL 'public open fun data (): T of .FooInterface4Impl declared in .FooInterface4Impl' type=T of .FooInterface4Impl origin=null - $this: GET_VAR ': .FooInterface4Impl.FooInterface4Impl> declared in .FooInterface4Impl.dataBlocking' type=.FooInterface4Impl.FooInterface4Impl> origin=null - FUN name:data visibility:public modality:OPEN <> ($this:.FooInterface4Impl.FooInterface4Impl>) returnType:T of .FooInterface4Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data (): T of .FooInterface4 declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:.FooInterface4Impl.FooInterface4Impl> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface4Impl declared in .FooInterface4Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN <> ($this:.FooInterface4Impl.FooInterface4Impl>, value:T of .FooInterface4Impl) returnType:T of .FooInterface4Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data2 (value: T of .FooInterface4): T of .FooInterface4 declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:.FooInterface4Impl.FooInterface4Impl> - VALUE_PARAMETER name:value index:0 type:T of .FooInterface4Impl - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: T of .FooInterface4Impl): T of .FooInterface4Impl declared in .FooInterface4Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface4Impl.FooInterface4Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface4Impl [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - overridden: - public abstract fun data3 (): T of .FooInterface4 declared in .FooInterface4 - $this: VALUE_PARAMETER name: type:.FooInterface4Impl.FooInterface4Impl> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3 (): T of .FooInterface4Impl declared in .FooInterface4Impl' - CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - CLASS INTERFACE name:Bar modality:ABSTRACT visibility:public superTypes:[.Foo] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Bar - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in .Foo - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in .Foo - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in .Foo - $this: VALUE_PARAMETER name: type:kotlin.Any - CLASS INTERFACE name:Foo modality:ABSTRACT visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.Foo - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - CLASS INTERFACE name:FooInterface1 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FooInterface1.FooInterface1> - TYPE_PARAMETER name:T index:0 variance: superTypes:[.Foo] reified:false - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN name:data visibility:public modality:ABSTRACT <> ($this:.FooInterface1.FooInterface1>) returnType:T of .FooInterface1 [suspend] - $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface1.FooInterface1>, value:love.forte.plugin.suspendtrans.A of .FooInterface1.data2) returnType:T of .FooInterface1 [suspend] - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false - $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1.data2 - FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface1.FooInterface1>, $receiver:kotlin.Int) returnType:T of .FooInterface1 [suspend] - $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - CLASS INTERFACE name:FooInterface2 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FooInterface2.FooInterface2> - TYPE_PARAMETER name:T index:0 variance: superTypes:[.Foo] reified:false - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN name:data visibility:public modality:ABSTRACT <> ($this:.FooInterface2.FooInterface2>) returnType:T of .FooInterface2 [suspend] - $this: VALUE_PARAMETER name: type:.FooInterface2.FooInterface2> - FUN name:data2 visibility:public modality:ABSTRACT <> ($this:.FooInterface2.FooInterface2>, value:T of .FooInterface2) returnType:T of .FooInterface2 [suspend] - $this: VALUE_PARAMETER name: type:.FooInterface2.FooInterface2> - VALUE_PARAMETER name:value index:0 type:T of .FooInterface2 - FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface2.FooInterface2>, $receiver:kotlin.Int) returnType:T of .FooInterface2 [suspend] - $this: VALUE_PARAMETER name: type:.FooInterface2.FooInterface2> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - CLASS INTERFACE name:FooInterface3 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FooInterface3.FooInterface3> - TYPE_PARAMETER name:T index:0 variance: superTypes:[.Foo] reified:false - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3.FooInterface3>, value:love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking) returnType:T of .FooInterface3 - annotations: - Api4J - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false - $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface3 origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3 [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3 declared in .FooInterface3.data2Blocking' - CALL 'public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null - : - $this: GET_VAR ': .FooInterface3.FooInterface3> declared in .FooInterface3.data2Blocking' type=.FooInterface3.FooInterface3> origin=null - value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking declared in .FooInterface3.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface3.FooInterface3>, $receiver:kotlin.Int) returnType:T of .FooInterface3 - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3Blocking (): T of .FooInterface3 declared in .FooInterface3' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface3 origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3 [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3 declared in .FooInterface3.data3Blocking' - CALL 'public abstract fun data3 (): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null - $this: GET_VAR ': .FooInterface3.FooInterface3> declared in .FooInterface3.data3Blocking' type=.FooInterface3.FooInterface3> origin=null - $receiver: GET_VAR ': kotlin.Int declared in .FooInterface3.data3Blocking' type=kotlin.Int origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:dataBlocking visibility:public modality:OPEN <> ($this:.FooInterface3.FooInterface3>) returnType:T of .FooInterface3 - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun dataBlocking (): T of .FooInterface3 declared in .FooInterface3' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface3 origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3 [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3 declared in .FooInterface3.dataBlocking' - CALL 'public abstract fun data (): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null - $this: GET_VAR ': .FooInterface3.FooInterface3> declared in .FooInterface3.dataBlocking' type=.FooInterface3.FooInterface3> origin=null - FUN name:data visibility:public modality:ABSTRACT <> ($this:.FooInterface3.FooInterface3>) returnType:T of .FooInterface3 [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface3.FooInterface3>, value:love.forte.plugin.suspendtrans.A of .FooInterface3.data2) returnType:T of .FooInterface3 [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false - $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3.data2 - FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface3.FooInterface3>, $receiver:kotlin.Int) returnType:T of .FooInterface3 [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - CLASS INTERFACE name:FooInterface4 modality:ABSTRACT visibility:public superTypes:[kotlin.Any] - $this: VALUE_PARAMETER INSTANCE_RECEIVER name: type:.FooInterface4.FooInterface4> - TYPE_PARAMETER name:T index:0 variance: superTypes:[.Foo] reified:false - FUN FAKE_OVERRIDE name:equals visibility:public modality:OPEN <> ($this:kotlin.Any, other:kotlin.Any?) returnType:kotlin.Boolean [fake_override,operator] - overridden: - public open fun equals (other: kotlin.Any?): kotlin.Boolean declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - VALUE_PARAMETER name:other index:0 type:kotlin.Any? - FUN FAKE_OVERRIDE name:hashCode visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.Int [fake_override] - overridden: - public open fun hashCode (): kotlin.Int declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN FAKE_OVERRIDE name:toString visibility:public modality:OPEN <> ($this:kotlin.Any) returnType:kotlin.String [fake_override] - overridden: - public open fun toString (): kotlin.String declared in kotlin.Any - $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data2Blocking visibility:public modality:OPEN <> ($this:.FooInterface4.FooInterface4>, value:T of .FooInterface4) returnType:T of .FooInterface4 - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface4.FooInterface4> - VALUE_PARAMETER name:value index:0 type:T of .FooInterface4 - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: T of .FooInterface4): T of .FooInterface4 declared in .FooInterface4' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface4 origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface4> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface4 [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface4 declared in .FooInterface4.data2Blocking' - CALL 'public abstract fun data2 (value: T of .FooInterface4): T of .FooInterface4 declared in .FooInterface4' type=T of .FooInterface4 origin=null - $this: GET_VAR ': .FooInterface4.FooInterface4> declared in .FooInterface4.data2Blocking' type=.FooInterface4.FooInterface4> origin=null - value: GET_VAR 'value: T of .FooInterface4 declared in .FooInterface4.data2Blocking' type=T of .FooInterface4 origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface4.FooInterface4>, $receiver:kotlin.Int) returnType:T of .FooInterface4 - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface4.FooInterface4> - $receiver: VALUE_PARAMETER name: type:kotlin.Int - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data3Blocking (): T of .FooInterface4 declared in .FooInterface4' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface4 origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface4> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface4 [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface4 declared in .FooInterface4.data3Blocking' - CALL 'public abstract fun data3 (): T of .FooInterface4 declared in .FooInterface4' type=T of .FooInterface4 origin=null - $this: GET_VAR ': .FooInterface4.FooInterface4> declared in .FooInterface4.data3Blocking' type=.FooInterface4.FooInterface4> origin=null - $receiver: GET_VAR ': kotlin.Int declared in .FooInterface4.data3Blocking' type=kotlin.Int origin=null - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformK2V3Key] name:dataBlocking visibility:public modality:OPEN <> ($this:.FooInterface4.FooInterface4>) returnType:T of .FooInterface4 - annotations: - Api4J - $this: VALUE_PARAMETER name: type:.FooInterface4.FooInterface4> - BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun dataBlocking (): T of .FooInterface4 declared in .FooInterface4' - CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of .FooInterface4 origin=null - : - block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface4> origin=LAMBDA - FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface4 [suspend] - BLOCK_BODY - RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface4 declared in .FooInterface4.dataBlocking' - CALL 'public abstract fun data (): T of .FooInterface4 declared in .FooInterface4' type=T of .FooInterface4 origin=null - $this: GET_VAR ': .FooInterface4.FooInterface4> declared in .FooInterface4.dataBlocking' type=.FooInterface4.FooInterface4> origin=null - FUN name:data visibility:public modality:ABSTRACT <> ($this:.FooInterface4.FooInterface4>) returnType:T of .FooInterface4 [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - $this: VALUE_PARAMETER name: type:.FooInterface4.FooInterface4> - FUN name:data2 visibility:public modality:ABSTRACT <> ($this:.FooInterface4.FooInterface4>, value:T of .FooInterface4) returnType:T of .FooInterface4 [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - $this: VALUE_PARAMETER name: type:.FooInterface4.FooInterface4> - VALUE_PARAMETER name:value index:0 type:T of .FooInterface4 - FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface4.FooInterface4>, $receiver:kotlin.Int) returnType:T of .FooInterface4 [suspend] - annotations: - JvmBlocking(baseName = , suffix = , asProperty = ) - JvmSynthetic - $this: VALUE_PARAMETER name: type:.FooInterface4.FooInterface4> - $receiver: VALUE_PARAMETER name: type:kotlin.Int diff --git a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.txt b/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.txt index 5bce210..e01f208 100644 --- a/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.txt +++ b/compiler/suspend-transform-plugin/src/testData/codegen/implOverridenGeneric.fir.txt @@ -6,7 +6,7 @@ FILE: Main.kt public abstract interface FooInterface1 : R|kotlin/Any| { public abstract suspend fun data(): R|T| - public abstract suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| + public abstract suspend fun data2(value: R|A|): R|T| public abstract suspend fun R|kotlin/Int|.data3(): R|T| @@ -20,7 +20,7 @@ FILE: Main.kt ^data R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public open override suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public open override suspend fun data2(value: R|A|): R|T| { ^data2 R|kotlin/TODO|() } @@ -28,7 +28,7 @@ FILE: Main.kt ^data3 R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| { ^data2Blocking R|love/forte/plugin/suspendtrans/runtime/$runInBlocking$|(suspend fun (): R|T| { ^ this@R|/FooInterface1Impl|.R|/FooInterface1Impl.data2|(R|/value|) } @@ -100,11 +100,11 @@ FILE: Main.kt public abstract interface FooInterface3 : R|kotlin/Any| { @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public abstract suspend fun data(): R|T| - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public abstract suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public abstract suspend fun data2(value: R|A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public abstract suspend fun R|kotlin/Int|.data3(): R|T| - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| { ^data2Blocking R|love/forte/plugin/suspendtrans/runtime/$runInBlocking$|(suspend fun (): R|T| { ^ this@R|/FooInterface3|.R|/FooInterface3.data2|(R|/value|) } @@ -135,7 +135,7 @@ FILE: Main.kt ^data R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public open override suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|kotlin/jvm/JvmSynthetic|() public open override suspend fun data2(value: R|A|): R|T| { ^data2 R|kotlin/TODO|() } @@ -143,7 +143,7 @@ FILE: Main.kt ^data3 R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| { ^data2Blocking R|love/forte/plugin/suspendtrans/runtime/$runInBlocking$|(suspend fun (): R|T| { ^ this@R|/FooInterface3Impl|.R|/FooInterface3Impl.data2|(R|/value|) } diff --git a/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.ir.txt b/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.ir.txt index 1c4e3b3..7b2e294 100644 --- a/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.ir.txt +++ b/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.ir.txt @@ -19,24 +19,24 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in .FooInterface1 $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking) returnType:T of .FooInterface1Impl + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:A of .FooInterface1Impl.data2Blocking) returnType:T of .FooInterface1Impl annotations: Api4J - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking + VALUE_PARAMETER name:value index:0 type:A of .FooInterface1Impl.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking): T of .FooInterface1Impl declared in .FooInterface1Impl' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface1Impl.data2Blocking): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface1Impl> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface1Impl [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface1Impl declared in .FooInterface1Impl.data2Blocking' - CALL 'public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null - : + CALL 'public open fun data2 (value: A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' type=T of .FooInterface1Impl origin=null + : $this: GET_VAR ': .FooInterface1Impl.FooInterface1Impl> declared in .FooInterface1Impl.data2Blocking' type=.FooInterface1Impl.FooInterface1Impl> origin=null - value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking declared in .FooInterface1Impl.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2Blocking origin=null + value: GET_VAR 'value: A of .FooInterface1Impl.data2Blocking declared in .FooInterface1Impl.data2Blocking' type=A of .FooInterface1Impl.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface1Impl annotations: Api4J @@ -78,18 +78,18 @@ FILE fqName: fileName:/Main.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2) returnType:T of .FooInterface1Impl [suspend] + FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface1Impl.FooInterface1Impl>, value:A of .FooInterface1Impl.data2) returnType:T of .FooInterface1Impl [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) TargetMarker(value = "ZGF0YTJGb29JbnRlcmZhY2UxSW1wbDxUPm51bGxB") JvmSynthetic overridden: - public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1.data2): T of .FooInterface1 declared in .FooInterface1 - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false + public abstract fun data2 (value: A of .FooInterface1.data2): T of .FooInterface1 declared in .FooInterface1 + TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1Impl.FooInterface1Impl> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2 + VALUE_PARAMETER name:value index:0 type:A of .FooInterface1Impl.data2 BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' + RETURN type=kotlin.Nothing from='public open fun data2 (value: A of .FooInterface1Impl.data2): T of .FooInterface1Impl declared in .FooInterface1Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface1Impl.FooInterface1Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface1Impl [suspend] annotations: @@ -224,26 +224,26 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in .FooInterface3 $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking) returnType:T of .FooInterface3Impl + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:A of .FooInterface3Impl.data2Blocking) returnType:T of .FooInterface3Impl annotations: Api4J overridden: - public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3 - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false + public open fun data2Blocking (value: A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3 + TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking + VALUE_PARAMETER name:value index:0 type:A of .FooInterface3Impl.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking): T of .FooInterface3Impl declared in .FooInterface3Impl' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface3Impl.data2Blocking): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3Impl> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3Impl [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3Impl declared in .FooInterface3Impl.data2Blocking' - CALL 'public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null - : + CALL 'public open fun data2 (value: A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' type=T of .FooInterface3Impl origin=null + : $this: GET_VAR ': .FooInterface3Impl.FooInterface3Impl> declared in .FooInterface3Impl.data2Blocking' type=.FooInterface3Impl.FooInterface3Impl> origin=null - value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking declared in .FooInterface3Impl.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2Blocking origin=null + value: GET_VAR 'value: A of .FooInterface3Impl.data2Blocking declared in .FooInterface3Impl.data2Blocking' type=A of .FooInterface3Impl.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface3Impl annotations: Api4J @@ -289,18 +289,18 @@ FILE fqName: fileName:/Main.kt BLOCK_BODY RETURN type=kotlin.Nothing from='public open fun data (): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null - FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2) returnType:T of .FooInterface3Impl [suspend] + FUN name:data2 visibility:public modality:OPEN ($this:.FooInterface3Impl.FooInterface3Impl>, value:A of .FooInterface3Impl.data2) returnType:T of .FooInterface3Impl [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) TargetMarker(value = "ZGF0YTJGb29JbnRlcmZhY2UzSW1wbDxUPm51bGxB") JvmSynthetic overridden: - public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3 - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false + public abstract fun data2 (value: A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3 + TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3Impl.FooInterface3Impl> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2 + VALUE_PARAMETER name:value index:0 type:A of .FooInterface3Impl.data2 BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' + RETURN type=kotlin.Nothing from='public open fun data2 (value: A of .FooInterface3Impl.data2): T of .FooInterface3Impl declared in .FooInterface3Impl' CALL 'public final fun TODO (): kotlin.Nothing declared in kotlin' type=kotlin.Nothing origin=null FUN name:data3 visibility:public modality:OPEN <> ($this:.FooInterface3Impl.FooInterface3Impl>, $receiver:kotlin.Int) returnType:T of .FooInterface3Impl [suspend] annotations: @@ -469,10 +469,10 @@ FILE fqName: fileName:/Main.kt $this: VALUE_PARAMETER name: type:kotlin.Any FUN name:data visibility:public modality:ABSTRACT <> ($this:.FooInterface1.FooInterface1>) returnType:T of .FooInterface1 [suspend] $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface1.FooInterface1>, value:love.forte.plugin.suspendtrans.A of .FooInterface1.data2) returnType:T of .FooInterface1 [suspend] - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false + FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface1.FooInterface1>, value:A of .FooInterface1.data2) returnType:T of .FooInterface1 [suspend] + TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface1.data2 + VALUE_PARAMETER name:value index:0 type:A of .FooInterface1.data2 FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface1.FooInterface1>, $receiver:kotlin.Int) returnType:T of .FooInterface1 [suspend] $this: VALUE_PARAMETER name: type:.FooInterface1.FooInterface1> $receiver: VALUE_PARAMETER name: type:kotlin.Int @@ -516,24 +516,24 @@ FILE fqName: fileName:/Main.kt overridden: public open fun toString (): kotlin.String declared in kotlin.Any $this: VALUE_PARAMETER name: type:kotlin.Any - FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3.FooInterface3>, value:love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking) returnType:T of .FooInterface3 + FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data2Blocking visibility:public modality:OPEN ($this:.FooInterface3.FooInterface3>, value:A of .FooInterface3.data2Blocking) returnType:T of .FooInterface3 annotations: Api4J - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking + VALUE_PARAMETER name:value index:0 type:A of .FooInterface3.data2Blocking BLOCK_BODY - RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3' + RETURN type=kotlin.Nothing from='public open fun data2Blocking (value: A of .FooInterface3.data2Blocking): T of .FooInterface3 declared in .FooInterface3' CALL 'public final fun $runInBlocking$ (block: kotlin.coroutines.SuspendFunction0): T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ declared in love.forte.plugin.suspendtrans.runtime' type=T of love.forte.plugin.suspendtrans.runtime.$runInBlocking$ origin=null : block: FUN_EXPR type=kotlin.coroutines.SuspendFunction0.FooInterface3> origin=LAMBDA FUN LOCAL_FUNCTION_FOR_LAMBDA name: visibility:local modality:FINAL <> () returnType:T of .FooInterface3 [suspend] BLOCK_BODY RETURN type=kotlin.Nothing from='local final fun (): T of .FooInterface3 declared in .FooInterface3.data2Blocking' - CALL 'public abstract fun data2 (value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null - : + CALL 'public abstract fun data2 (value: A of .FooInterface3.data2): T of .FooInterface3 declared in .FooInterface3' type=T of .FooInterface3 origin=null + : $this: GET_VAR ': .FooInterface3.FooInterface3> declared in .FooInterface3.data2Blocking' type=.FooInterface3.FooInterface3> origin=null - value: GET_VAR 'value: love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking declared in .FooInterface3.data2Blocking' type=love.forte.plugin.suspendtrans.A of .FooInterface3.data2Blocking origin=null + value: GET_VAR 'value: A of .FooInterface3.data2Blocking declared in .FooInterface3.data2Blocking' type=A of .FooInterface3.data2Blocking origin=null FUN GENERATED[love.forte.plugin.suspendtrans.fir.SuspendTransformPluginKey] name:data3Blocking visibility:public modality:OPEN <> ($this:.FooInterface3.FooInterface3>, $receiver:kotlin.Int) returnType:T of .FooInterface3 annotations: Api4J @@ -570,14 +570,14 @@ FILE fqName: fileName:/Main.kt TargetMarker(value = "ZGF0YUZvb0ludGVyZmFjZTM8VD5udWxs") JvmSynthetic $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface3.FooInterface3>, value:love.forte.plugin.suspendtrans.A of .FooInterface3.data2) returnType:T of .FooInterface3 [suspend] + FUN name:data2 visibility:public modality:ABSTRACT ($this:.FooInterface3.FooInterface3>, value:A of .FooInterface3.data2) returnType:T of .FooInterface3 [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) TargetMarker(value = "ZGF0YTJGb29JbnRlcmZhY2UzPFQ+bnVsbEE=") JvmSynthetic - TYPE_PARAMETER name:love.forte.plugin.suspendtrans.A index:0 variance: superTypes:[kotlin.Any?] reified:false + TYPE_PARAMETER name:A index:0 variance: superTypes:[kotlin.Any?] reified:false $this: VALUE_PARAMETER name: type:.FooInterface3.FooInterface3> - VALUE_PARAMETER name:value index:0 type:love.forte.plugin.suspendtrans.A of .FooInterface3.data2 + VALUE_PARAMETER name:value index:0 type:A of .FooInterface3.data2 FUN name:data3 visibility:public modality:ABSTRACT <> ($this:.FooInterface3.FooInterface3>, $receiver:kotlin.Int) returnType:T of .FooInterface3 [suspend] annotations: JvmBlocking(baseName = , suffix = , asProperty = ) diff --git a/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.txt b/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.txt index ef6d65d..50347f6 100644 --- a/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.txt +++ b/compiler/suspend-transform-plugin/src/testData_2/codegen/implOverridenGeneric.fir.txt @@ -6,7 +6,7 @@ FILE: Main.kt public abstract interface FooInterface1 : R|kotlin/Any| { public abstract suspend fun data(): R|T| - public abstract suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| + public abstract suspend fun data2(value: R|A|): R|T| public abstract suspend fun R|kotlin/Int|.data3(): R|T| @@ -20,7 +20,7 @@ FILE: Main.kt ^data R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UxSW1wbDxUPm51bGxB)) public open override suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UxSW1wbDxUPm51bGxB)) public open override suspend fun data2(value: R|A|): R|T| { ^data2 R|kotlin/TODO|() } @@ -28,7 +28,7 @@ FILE: Main.kt ^data3 R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun dataBlocking(): R|T| @@ -70,11 +70,11 @@ FILE: Main.kt public abstract interface FooInterface3 : R|kotlin/Any| { @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YUZvb0ludGVyZmFjZTM8VD5udWxs)) public abstract suspend fun data(): R|T| - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UzPFQ+bnVsbEE=)) public abstract suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UzPFQ+bnVsbEE=)) public abstract suspend fun data2(value: R|A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTNGb29JbnRlcmZhY2UzPFQ+a290bGluL0ludA==)) public abstract suspend fun R|kotlin/Int|.data3(): R|T| - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun dataBlocking(): R|T| @@ -90,7 +90,7 @@ FILE: Main.kt ^data R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UzSW1wbDxUPm51bGxB)) public open override suspend fun data2(value: R|love.forte.plugin.suspendtrans.A|): R|T| { + @R|love/forte/plugin/suspendtrans/annotation/JvmBlocking|() @R|love/forte/plugin/suspendtrans/annotation/TargetMarker|(value = String(ZGF0YTJGb29JbnRlcmZhY2UzSW1wbDxUPm51bGxB)) public open override suspend fun data2(value: R|A|): R|T| { ^data2 R|kotlin/TODO|() } @@ -98,7 +98,7 @@ FILE: Main.kt ^data3 R|kotlin/TODO|() } - @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|love.forte.plugin.suspendtrans.A|): R|T| + @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open fun data2Blocking(value: R|A|): R|T| @R|love/forte/plugin/suspendtrans/annotation/Api4J|() public open override fun dataBlocking(): R|T| diff --git a/plugins/ide/suspend-transform-plugin-idea/src/main/resources/META-INF/plugin.xml b/plugins/ide/suspend-transform-plugin-idea/src/main/resources/META-INF/plugin.xml index 6ad4215..da17a17 100644 --- a/plugins/ide/suspend-transform-plugin-idea/src/main/resources/META-INF/plugin.xml +++ b/plugins/ide/suspend-transform-plugin-idea/src/main/resources/META-INF/plugin.xml @@ -9,7 +9,7 @@ - + ForteScarlet diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index a921b49..616d130 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -275,9 +275,9 @@ private fun SuspendTransformPluginExtension.toSubpluginOptions(target: KotlinTar private fun Project.configureDependencies() { fun Project.include(platform: Platform, conf: SuspendTransformPluginExtension) { - if (conf.enabled.get()) { + if (!conf.enabled.get()) { logger.info( - "The `SuspendTransformGradleExtension.enable` in project {} for platform {} is `false`, skip config.", + "The `SuspendTransformPluginExtension.enable` in project {} for platform {} is `false`, skip config.", this, platform ) From 7dfdf748eab51d265b11cc8c6ecf7d831a5ab32a Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 16 Apr 2025 10:23:54 +0800 Subject: [PATCH 08/21] Deprecated level to WARNING --- .../suspendtrans/gradle/SuspendTransformGradleExtension.kt | 3 +-- .../suspendtrans/gradle/SuspendTransformGradlePlugin.kt | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt index edb6d3f..c676856 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt @@ -14,8 +14,7 @@ const val USE_NEW_EXTENSION = "Use the new extension " + replaceWith = ReplaceWith( "SuspendTransformPluginExtension", "love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension" - ), - level = DeprecationLevel.ERROR + ) ) open class SuspendTransformGradleExtension : love.forte.plugin.suspendtrans.SuspendTransformConfiguration() { @Deprecated("Please use the " + diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index 616d130..ac5b9b8 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -35,7 +35,7 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { } override fun apply(target: Project) { - @Suppress("DEPRECATION_ERROR") + @Suppress("DEPRECATION") target.extensions.create( EXTENSION_NAME, SuspendTransformGradleExtension::class.java @@ -81,7 +81,7 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { private fun resolveSubpluginOptions(target: KotlinTarget, project: Project): List { val extension = project.extensions.getByType(SuspendTransformPluginExtension::class.java) - @Suppress("DEPRECATION_ERROR") val oldExtension = + @Suppress("DEPRECATION") val oldExtension = project.extensions.getByType(SuspendTransformGradleExtension::class.java) @Suppress("DEPRECATION") if (oldExtension.enabled || oldExtension.transformers.isNotEmpty()) { From adf2998f2e0d7c19182669c0b213dc85dc38a945 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 16 Apr 2025 10:28:30 +0800 Subject: [PATCH 09/21] Update README --- README.md | 6 +++--- README_CN.md | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 1aed3ed..03d3f3b 100644 --- a/README.md +++ b/README.md @@ -322,7 +322,7 @@ which generates a `xxxBlocking` function. ```Kotlin class Cat { - @JvmBLocking + @JvmBlocking suspend fun meow() { // ... } @@ -356,7 +356,7 @@ which generates a `xxxAsync` function. ```Kotlin class Cat { - @JvmBLocking + @JvmBlocking suspend fun meow(): String = "Meow!" // Generated: @@ -494,7 +494,7 @@ First, let's agree that the following properties should be included in the annot - `asProperty`: Make the generated function a property. Can be used in cases where the original function has no arguments. ```Kotlin - @JBlock + @JBlock(asProperty = true) suspend fun value(): Int // Generated: diff --git a/README_CN.md b/README_CN.md index 411935c..8e65f1b 100644 --- a/README_CN.md +++ b/README_CN.md @@ -129,14 +129,14 @@ class Foo { 若版本小于等于 `0.9.0`,可参考以下对照表: -| Kotlin 版本 | 插件版本 | -|---------------|------------------------| -| `2.0.0` | `0.8.0-beta1` ~ `0.9.0` | -| `1.9.22` | `0.7.0-beta1` | -| `1.9.21` | `0.6.0` | -| `1.9.10` | `0.5.1` | -| `1.9.0` | `0.5.0` | -| `1.8.21` | `0.3.1` ~ `0.4.0` | +| Kotlin 版本 | 插件版本 | +|-----------|-------------------------| +| `2.0.0` | `0.8.0-beta1` ~ `0.9.0` | +| `1.9.22` | `0.7.0-beta1` | +| `1.9.21` | `0.6.0` | +| `1.9.10` | `0.5.1` | +| `1.9.0` | `0.5.0` | +| `1.8.21` | `0.3.1` ~ `0.4.0` | > [!note] > 未详细记录各 Kotlin 版本的编译器插件兼容性。 @@ -311,7 +311,7 @@ suspendTransformPlugin { ```Kotlin class Cat { - @JvmBLocking + @JvmBlocking suspend fun meow() { // ... } @@ -343,7 +343,7 @@ suspendTransformPlugin { ```Kotlin class Cat { - @JvmBLocking + @JvmBlocking suspend fun meow(): String = "Meow!" // 生成: From 3519add8faec1bac293525ebbc4a96abab64b974 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 16 Apr 2025 17:27:07 +0800 Subject: [PATCH 10/21] =?UTF-8?q?=E8=B0=83=E6=95=B4=20TransformersContaine?= =?UTF-8?q?r=20=E5=86=85=E9=83=A8=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gradle/SuspendTransformPluginExtension.kt | 78 +++++++++++++++---- settings.gradle.kts | 6 +- tests/test-jvm/build.gradle.kts | 2 + 3 files changed, 68 insertions(+), 18 deletions(-) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index 9ca65b7..cd2e8a0 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -6,6 +6,8 @@ import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguratio import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingTransformer import org.gradle.api.Action import org.gradle.api.DomainObjectSet +import org.gradle.api.Named +import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.* import javax.inject.Inject @@ -22,29 +24,69 @@ annotation class SuspendTransformPluginExtensionSpecDslMarker @SuspendTransformPluginExtensionSpecDslMarker interface SuspendTransformPluginExtensionSpec +interface NamedTransformerSpecListContainer : Named { + val platform: Provider + val transformers: ListProperty +} + +internal interface NamedTransformerSpecListContainerInternal : NamedTransformerSpecListContainer { + override val platform: Property +} + /** * @since 0.12.0 */ -abstract class TransformerContainer -@Inject constructor(private val objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { - internal val transformers: MutableMap> = mutableMapOf() +abstract class TransformersContainer +@Inject constructor( + private val objects: ObjectFactory +) : SuspendTransformPluginExtensionSpec { + private val _containers: NamedDomainObjectContainer = + objects.domainObjectContainer(NamedTransformerSpecListContainerInternal::class.java) { name -> + val targetPlatform = try { + TargetPlatform.valueOf(name) + } catch (e: IllegalArgumentException) { + throw IllegalArgumentException( + "The name '$name' is not a valid TargetPlatform name. " + + "Valid names: ${TargetPlatform.entries.joinToString { it.name }}", + e + ) + } + + objects.newInstance( + NamedTransformerSpecListContainerInternal::class.java, + name + ).apply { + platform.set(targetPlatform) + } + } - private fun getTransformers(platform: TargetPlatform): ListProperty { - return transformers.computeIfAbsent(platform) { objects.listProperty(TransformerSpec::class.java) } + internal val containers: NamedDomainObjectContainer + get() = _containers + + private fun getTransformersInternal(platform: TargetPlatform): ListProperty { + val container = _containers.findByName(platform.name) + return container?.transformers ?: _containers.create(platform.name).transformers + } + + /** + * Create a [TransformerSpec] but not add. + */ + private fun createTransformer(action: Action): TransformerSpec { + return objects.newInstance().also(action::execute) } fun add(platform: TargetPlatform, action: Action) { - val listProperty = getTransformers(platform) - listProperty.add(objects.newInstance(TransformerSpec::class.java).also(action::execute)) + val listProperty = getTransformersInternal(platform) + listProperty.add(createTransformer(action)) } fun add(platform: TargetPlatform, transformer: TransformerSpec) { - val listProperty = getTransformers(platform) + val listProperty = getTransformersInternal(platform) listProperty.add(transformer) } fun add(platform: TargetPlatform, transformer: Provider) { - val listProperty = getTransformers(platform) + val listProperty = getTransformersInternal(platform) listProperty.add(transformer) } @@ -149,9 +191,9 @@ abstract class SuspendTransformPluginExtension */ abstract val enabled: Property - val transformers: TransformerContainer = objects.newInstance() + val transformers: TransformersContainer = objects.newInstance() - fun transformers(action: Action) { + fun transformers(action: Action) { action.execute(transformers) } @@ -195,10 +237,16 @@ internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransform return SuspendTransformConfiguration( enabled = enabled.getOrElse(true), transformers = buildMap { - transformers.transformers.forEach { (k, values) -> - val list = values.map { valueList -> valueList.map { it.toTransformer() } }.getOrElse(emptyList()) - if (list.isNotEmpty()) { - put(k, list) + val transformers = transformers.containers + for (targetPlatform in TargetPlatform.entries) { + transformers.findByName(targetPlatform.name)?.also { container -> + val list = container.transformers.map { valueList -> + valueList.map { it.toTransformer() } + }.getOrElse(emptyList()) + + if (list.isNotEmpty()) { + put(targetPlatform, list) + } } } }, diff --git a/settings.gradle.kts b/settings.gradle.kts index 63e8f53..a789a7e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,7 +35,7 @@ include(":plugins:suspend-transform-plugin-gradle") // include(":local-helper") //Samples -// include(":tests:test-jvm") -// include(":tests:test-js") -// include(":tests:test-kmp") +include(":tests:test-jvm") +include(":tests:test-js") +include(":tests:test-kmp") // include(":tests:test-android") diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index 73f46cb..7b27338 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -32,6 +32,8 @@ suspendTransformPlugin { includeAnnotation = false includeRuntime = false transformers { + + // For blocking addJvm { markAnnotation { From d52b9f5103a4c636da7f5b3d96e9a50e734d7c9f Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 16 Apr 2025 17:31:30 +0800 Subject: [PATCH 11/21] =?UTF-8?q?=E8=B0=83=E6=95=B4=20TransformersContaine?= =?UTF-8?q?r=20=E5=86=85=E9=83=A8=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gradle/SuspendTransformPluginExtension.kt | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index cd2e8a0..d1d8b08 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -33,6 +33,10 @@ internal interface NamedTransformerSpecListContainerInternal : NamedTransformerS override val platform: Property } +@RequiresOptIn("This API is an experimental public TransformersContainer's api. " + + "It may be changed in the future without notice.") +annotation class ExperimentalTransformersContainerApi + /** * @since 0.12.0 */ @@ -60,7 +64,8 @@ abstract class TransformersContainer } } - internal val containers: NamedDomainObjectContainer + @ExperimentalTransformersContainerApi + val containers: NamedDomainObjectContainer get() = _containers private fun getTransformersInternal(platform: TargetPlatform): ListProperty { @@ -232,7 +237,7 @@ abstract class SuspendTransformPluginExtension } } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConstructorApi::class, ExperimentalTransformersContainerApi::class) internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransformConfiguration { return SuspendTransformConfiguration( enabled = enabled.getOrElse(true), From 354066e87eb06bd80f342eb9d597070fe70091b2 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 16 Apr 2025 17:42:42 +0800 Subject: [PATCH 12/21] =?UTF-8?q?=E8=B0=83=E6=95=B4=20TransformersContaine?= =?UTF-8?q?r=20=E5=86=85=E9=83=A8=E5=AE=9E=E7=8E=B0=EF=BC=8C=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=E9=83=A8=E5=88=86=E9=87=8D=E8=BD=BD=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gradle/SuspendTransformPluginExtension.kt | 114 ++++++++++++++++-- 1 file changed, 107 insertions(+), 7 deletions(-) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index d1d8b08..f119634 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -76,15 +76,27 @@ abstract class TransformersContainer /** * Create a [TransformerSpec] but not add. */ - private fun createTransformer(action: Action): TransformerSpec { + fun createTransformer(action: Action): TransformerSpec { return objects.newInstance().also(action::execute) } + /** + * Create a [TransformerSpec] but not add. + */ + fun createTransformer(action: (TransformerSpec) -> Unit): TransformerSpec { + return objects.newInstance().also(action) + } + fun add(platform: TargetPlatform, action: Action) { val listProperty = getTransformersInternal(platform) listProperty.add(createTransformer(action)) } + fun add(platform: TargetPlatform, action: (TransformerSpec) -> Unit) { + val listProperty = getTransformersInternal(platform) + listProperty.add(createTransformer(action)) + } + fun add(platform: TargetPlatform, transformer: TransformerSpec) { val listProperty = getTransformersInternal(platform) listProperty.add(transformer) @@ -105,26 +117,30 @@ abstract class TransformersContainer fun addJvm(transformer: Transformer) = addJvm { it.from(transformer) } fun addJvm(transformer: Provider) = add(TargetPlatform.JVM, transformer) fun addJvm(action: Action) = add(TargetPlatform.JVM, action) + fun addJvm(action: (TransformerSpec) -> Unit) = add(TargetPlatform.JVM, action) fun addJs(transformer: TransformerSpec) = add(TargetPlatform.JS, transformer) fun addJs(transformer: Transformer) = addJs { it.from(transformer) } fun addJs(transformer: Provider) = add(TargetPlatform.JS, transformer) fun addJs(action: Action) = add(TargetPlatform.JS, action) + fun addJs(action: (TransformerSpec) -> Unit) = add(TargetPlatform.JS, action) fun addNative(transformer: TransformerSpec) = add(TargetPlatform.NATIVE, transformer) fun addNative(transformer: Transformer) = addNative { it.from(transformer) } fun addNative(transformer: Provider) = add(TargetPlatform.NATIVE, transformer) fun addNative(action: Action) = add(TargetPlatform.NATIVE, action) + fun addNative(action: (TransformerSpec) -> Unit) = add(TargetPlatform.NATIVE, action) fun addWasm(transformer: TransformerSpec) = add(TargetPlatform.WASM, transformer) fun addWasm(transformer: Transformer) = addWasm { it.from(transformer) } fun addWasm(transformer: Provider) = add(TargetPlatform.WASM, transformer) fun addWasm(action: Action) = add(TargetPlatform.WASM, action) + fun addWasm(action: (TransformerSpec) -> Unit) = add(TargetPlatform.WASM, action) fun addCommon(transformer: TransformerSpec) = add(TargetPlatform.COMMON, transformer) fun addCommon(transformer: Transformer) = addCommon { it.from(transformer) } fun addCommon(transformer: Provider) = add(TargetPlatform.COMMON, transformer) - fun addCommon(action: Action) = add(TargetPlatform.COMMON, action) + fun addCommon(action: (TransformerSpec) -> Unit) = add(TargetPlatform.COMMON, action) // JVM defaults @@ -139,6 +155,14 @@ abstract class TransformersContainer } } + fun addJvmBlocking(action: (TransformerSpec) -> Unit) { + addJvmBlocking(Action(action)) + addJvm { + it.from(jvmBlockingTransformer) + action(it) + } + } + fun addJvmAsync() { addJvm(jvmAsyncTransformer) } @@ -150,6 +174,13 @@ abstract class TransformersContainer } } + fun addJvmAsync(action: (TransformerSpec) -> Unit) { + addJvm { + it.from(jvmAsyncTransformer) + action(it) + } + } + // JS defaults /** @@ -162,10 +193,10 @@ abstract class TransformersContainer /** * Add a js transformer based on [jsPromiseTransformer] */ - fun addJsPromise(action: Action) { + fun addJsPromise(action: (TransformerSpec) -> Unit) { addJs { it.from(jsPromiseTransformer) - action.execute(it) + action(it) } } @@ -202,6 +233,10 @@ abstract class SuspendTransformPluginExtension action.execute(transformers) } + fun transformers(action: (TransformersContainer) -> Unit) { + action(transformers) + } + /** * Include the `love.forte.plugin.suspend-transform:suspend-transform-annotation`. * Default is `true`. @@ -223,6 +258,10 @@ abstract class SuspendTransformPluginExtension annotationDependency.set(annotationDependency.get().also(action::execute)) } + fun annotationDependency(action: (AnnotationDependencySpec) -> Unit) { + annotationDependency.set(annotationDependency.get().also(action)) + } + /** * Default is `implementation` with [SuspendTransPluginConstants.RUNTIME_VERSION] */ @@ -232,6 +271,10 @@ abstract class SuspendTransformPluginExtension runtimeDependency.set(runtimeDependency.get().also(action::execute)) } + fun runtimeDependency(action: (RuntimeDependencySpec) -> Unit) { + runtimeDependency.set(runtimeDependency.get().also(action)) + } + fun runtimeAsApi() { runtimeDependency.get().configurationName.set("api") } @@ -332,6 +375,11 @@ abstract class TransformerSpec markAnnotation.set(old.also(action::execute)) } + fun markAnnotation(action: (MarkAnnotationSpec) -> Unit) { + val old = markAnnotation.getOrElse(objects.newInstance()) + markAnnotation.set(old.also(action)) + } + /** * 用于转化的函数信息。 * @@ -364,6 +412,14 @@ abstract class TransformerSpec ) } + fun transformFunctionInfo(action: (FunctionInfoSpec) -> Unit) { + transformFunctionInfo.set( + transformFunctionInfo.getOrElse( + objects.newInstance() + ).also(action) + ) + } + /** * 转化后的返回值类型, 为null时代表与原函数一致。 * @@ -379,6 +435,14 @@ abstract class TransformerSpec ) } + fun transformReturnType(action: (ClassInfoSpec) -> Unit) { + transformReturnType.set( + transformReturnType.getOrElse( + objects.newInstance() + ).also(action) + ) + } + /** * 转化后的返回值类型中,是否存在需要与原本返回值类型一致的泛型。 * 这里指的是返回值类型中嵌套的范型,例如 `CompletableFuture` 中的 `T`。 @@ -403,19 +467,33 @@ abstract class TransformerSpec private fun newIncludeAnnotationSpec(): IncludeAnnotationSpec = objects.newInstance() - fun createIncludeAnnotation(action: Action): IncludeAnnotationSpec { + fun createIncludeAnnotation(action: Action): IncludeAnnotationSpec { return newIncludeAnnotationSpec().also(action::execute) } - fun addOriginFunctionIncludeAnnotation(action: Action) { + fun createIncludeAnnotation(action: (IncludeAnnotationSpec) -> Unit): IncludeAnnotationSpec { + return newIncludeAnnotationSpec().also(action) + } + + fun addOriginFunctionIncludeAnnotation(action: Action) { originFunctionIncludeAnnotations.add( newIncludeAnnotationSpec().also(action::execute) ) } + fun addOriginFunctionIncludeAnnotation(action: (IncludeAnnotationSpec) -> Unit) { + originFunctionIncludeAnnotations.add( + newIncludeAnnotationSpec().also(action) + ) + } + abstract val syntheticFunctionIncludeAnnotations: DomainObjectSet - fun addSyntheticFunctionIncludeAnnotation(action: Action) { + fun addSyntheticFunctionIncludeAnnotation(action: Action) { + syntheticFunctionIncludeAnnotations.add(createIncludeAnnotation(action)) + } + + fun addSyntheticFunctionIncludeAnnotation(action: (IncludeAnnotationSpec) -> Unit) { syntheticFunctionIncludeAnnotations.add(createIncludeAnnotation(action)) } @@ -444,6 +522,13 @@ abstract class TransformerSpec copyAnnotationExcludes.add(createCopyAnnotationExclude(action)) } + /** + * Add a [ClassInfoSpec] into [copyAnnotationExcludes] + */ + fun addCopyAnnotationExclude(action: (ClassInfoSpec) -> Unit) { + copyAnnotationExcludes.add(createCopyAnnotationExclude(action)) + } + /** * Create a [ClassInfoSpec] but does not add. */ @@ -451,6 +536,13 @@ abstract class TransformerSpec return objects.newInstance().also(action::execute) } + /** + * Create a [ClassInfoSpec] but does not add. + */ + fun createCopyAnnotationExclude(action: (ClassInfoSpec) -> Unit): ClassInfoSpec { + return objects.newInstance().also(action) + } + /** * 如果是生成属性的话,是否复制源函数上的注解到新的属性上 * @@ -517,6 +609,10 @@ abstract class MarkAnnotationSpec classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } + fun classInfo(action: (ClassInfoSpec) -> Unit) { + classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action)) + } + /** * 用于标记生成函数需要使用的基础函数名的注解属性名。 * @@ -619,6 +715,10 @@ abstract class IncludeAnnotationSpec classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } + fun classInfo(action: (ClassInfoSpec) -> Unit) { + classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action)) + } + /** * Default value is `false` */ From 83cfcb3a295c31b5ee82fb8051cdf9806e1c2370 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Wed, 16 Apr 2025 17:44:47 +0800 Subject: [PATCH 13/21] remove test modules --- settings.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index a789a7e..63e8f53 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,7 +35,7 @@ include(":plugins:suspend-transform-plugin-gradle") // include(":local-helper") //Samples -include(":tests:test-jvm") -include(":tests:test-js") -include(":tests:test-kmp") +// include(":tests:test-jvm") +// include(":tests:test-js") +// include(":tests:test-kmp") // include(":tests:test-android") From b6c2ebdda40866b138dbf9cb0765d8b0a8239eaa Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 18 Apr 2025 12:10:16 +0800 Subject: [PATCH 14/21] =?UTF-8?q?=E7=96=91=E4=BC=BC=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=86=E6=9F=90=E4=BA=9B=E6=83=85=E5=86=B5=E4=B8=8B=E4=B8=8D?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=90=88=E6=88=90=E5=87=BD=E6=95=B0=E6=88=96?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fir/SuspendTransformFirTransformer.kt | 90 +++++---- .../gradle/SuspendTransformGradlePlugin.kt | 46 +++-- .../gradle/SuspendTransformPluginExtension.kt | 176 +++++++++--------- tests/test-jvm/build.gradle.kts | 89 ++++----- .../src/test/kotlin/SuspendTransformTests.kt | 10 + tests/test-kmp/build.gradle.kts | 77 ++++---- .../src/commonMain/kotlin/example/MyClass.kt | 9 + .../commonMain/kotlin/example/MyInterface.kt | 17 ++ .../src/jvmTest/kotlin/MyClassReflectTests.kt | 26 +++ 9 files changed, 308 insertions(+), 232 deletions(-) create mode 100644 tests/test-kmp/src/commonMain/kotlin/example/MyInterface.kt create mode 100644 tests/test-kmp/src/jvmTest/kotlin/MyClassReflectTests.kt diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt index 3a456f0..609b3c1 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt @@ -2,6 +2,7 @@ package love.forte.plugin.suspendtrans.fir import love.forte.plugin.suspendtrans.configuration.MarkAnnotation import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration +import love.forte.plugin.suspendtrans.configuration.TargetPlatform import love.forte.plugin.suspendtrans.configuration.Transformer import love.forte.plugin.suspendtrans.fqn import love.forte.plugin.suspendtrans.utils.* @@ -101,16 +102,24 @@ class SuspendTransformFirTransformer( Name.identifier("CoroutineScope") ) - coroutineScopeSymbol = session.symbolProvider.getClassLikeSymbolByClassId(classId) - ?: session.dependenciesSymbolProvider.getClassLikeSymbolByClassId(classId) - ?: error("Cannot resolve `kotlinx.coroutines.CoroutineScope` symbol.") + if (!(::coroutineScopeSymbol.isInitialized)) { + coroutineScopeSymbol = session.symbolProvider.getClassLikeSymbolByClassId(classId) + ?: session.dependenciesSymbolProvider.getClassLikeSymbolByClassId(classId) + ?: error("Cannot resolve `kotlinx.coroutines.CoroutineScope` symbol.") + } + } - private fun initTransformerFunctionSymbolMap() { + private fun initTransformerFunctionSymbolMap( + classSymbol: FirClassSymbol<*>, + memberScope: FirClassDeclaredMemberScope? + ): Map { // 尝试找到所有配置的 bridge function, 例如 `runBlocking` 等 val symbolProvider = session.symbolProvider val dependenciesSymbolProvider = session.dependenciesSymbolProvider + val map = mutableMapOf() + suspendTransformConfiguration.transformers .forEach { (_, transformerList) -> for (transformer in transformerList) { @@ -136,6 +145,7 @@ class SuspendTransformFirTransformer( if (transformerFunctionSymbols.isNotEmpty()) { if (transformerFunctionSymbols.size == 1) { transformerFunctionSymbolMap[transformer] = transformerFunctionSymbols.first() + map[transformer] = transformerFunctionSymbols.first() } else { error("Found multiple transformer function symbols for transformer: $transformer") } @@ -145,15 +155,18 @@ class SuspendTransformFirTransformer( } } } + + return map } // private val cache: FirCache, FirClassDeclaredMemberScope?>, Map>?, Nothing?> = private val cache: FirCache>?, Nothing?> = - session.firCachesFactory.createCache { (symbol, scope), c -> + session.firCachesFactory.createCache { cacheKey, c -> + val (symbol, scope) = cacheKey initScopeSymbol() - initTransformerFunctionSymbolMap() + val transformerFunctionMap = initTransformerFunctionSymbolMap(symbol, scope) - createCache(symbol, scope) + createCache(symbol, scope, transformerFunctionMap) } @@ -337,9 +350,12 @@ class SuspendTransformFirTransformer( val lambdaTarget = FirFunctionTarget(null, isLambda = true) val lambda = buildAnonymousFunction { this.resolvePhase = FirResolvePhase.BODY_RESOLVE + // this.resolvePhase = FirResolvePhase.RAW_FIR this.isLambda = true this.moduleData = originFunSymbol.moduleData - this.origin = FirDeclarationOrigin.Synthetic.FakeFunction + // this.origin = FirDeclarationOrigin.Source + // this.origin = FirDeclarationOrigin.Synthetic.FakeFunction + this.origin = FirDeclarationOrigin.Plugin(SuspendTransformK2V3Key) this.returnTypeRef = originFunSymbol.resolvedReturnTypeRef this.hasExplicitParameterList = false this.status = FirResolvedDeclarationStatusImpl.DEFAULT_STATUS_FOR_SUSPEND_FUNCTION_EXPRESSION @@ -385,7 +401,6 @@ class SuspendTransformFirTransformer( source = thisReceiverParameter.source calleeReference = buildImplicitThisReference { boundSymbol = thisReceiverParameter.symbol - // println("[${newFunSymbol}] thisReceiverParameter.symbol: ${thisReceiverParameter.symbol}") } } } @@ -591,6 +606,7 @@ class SuspendTransformFirTransformer( val newFunTarget = FirFunctionTarget(null, isLambda = false) val newFun = buildSimpleFunctionCopy(originFunc) { + origin = FirDeclarationOrigin.Plugin(SuspendTransformK2V3Key) name = callableId.callableName symbol = newFunSymbol status = originFunc.status.copy( @@ -871,46 +887,53 @@ class SuspendTransformFirTransformer( return isOverride } - private val annotationPredicates: DeclarationPredicate? = - if (suspendTransformConfiguration.transformers.values.isEmpty()) { - null - } else { - DeclarationPredicate.create { - var predicate: DeclarationPredicate? = null - for (value in suspendTransformConfiguration.transformers.values) { - for (transformer in value) { - val afq = transformer.markAnnotation.fqName - predicate = predicate?.also { p -> p or annotated(afq) } ?: annotated(afq) - } - } - - predicate ?: annotated() + private val annotationPredicates = DeclarationPredicate.create { + val annotationFqNames = suspendTransformConfiguration.transformers.values + .flatMapTo(mutableSetOf()) { transformerList -> + transformerList.map { it.markAnnotation.fqName } } - } + + hasAnnotated(annotationFqNames) + // var predicate: DeclarationPredicate? = null + // for (value in suspendTransformConfiguration.transformers.values) { + // for (transformer in value) { + // val afq = transformer.markAnnotation.fqName + // predicate = if (predicate == null) { + // annotated(afq) + // } else { + // predicate or annotated(afq) + // } + // } + // } + // + // predicate ?: annotated() + } + /** * NB: The predict needs to be *registered* in order to parse the [@XSerializable] type * otherwise, the annotation remains unresolved */ override fun FirDeclarationPredicateRegistrar.registerPredicates() { - annotationPredicates?.also { register(it) } + register(annotationPredicates) } private fun createCache( classSymbol: FirClassSymbol<*>, - declaredScope: FirClassDeclaredMemberScope? + declaredScope: FirClassDeclaredMemberScope?, + transformerFunctionSymbolMap: Map ): Map>? { if (declaredScope == null) return null - fun check(targetPlatform: love.forte.plugin.suspendtrans.configuration.TargetPlatform): Boolean { + fun check(targetPlatform: TargetPlatform): Boolean { val platform = classSymbol.moduleData.platform return when { - platform.isJvm() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.JVM -> true - platform.isJs() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.JS -> true - platform.isWasm() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.WASM -> true - platform.isNative() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.NATIVE -> true - platform.isCommon() && targetPlatform == love.forte.plugin.suspendtrans.configuration.TargetPlatform.COMMON -> true + platform.isJvm() && targetPlatform == TargetPlatform.JVM -> true + platform.isJs() && targetPlatform == TargetPlatform.JS -> true + platform.isWasm() && targetPlatform == TargetPlatform.WASM -> true + platform.isNative() && targetPlatform == TargetPlatform.NATIVE -> true + platform.isCommon() && targetPlatform == TargetPlatform.COMMON -> true else -> false } } @@ -945,7 +968,6 @@ class SuspendTransformFirTransformer( // 读不到注解的参数? // 必须使用 anno.getXxxArgument(Name(argument name)), // 使用 argumentMapping.mapping 获取不到结果 -// println("RAW AnnoData: ${anno.argumentMapping.mapping}") val annoData = anno.toTransformAnnotationData(markAnnotation, functionName) val syntheticFunNameString = annoData.functionName @@ -1274,11 +1296,9 @@ class SuspendTransformFirTransformer( when (this) { is ConeDynamicType -> { - //println("Dynamic type: $this") } is ConeFlexibleType -> { - //println("Flexible type: $this") } is ConeClassLikeType -> { diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index ac5b9b8..7b448b0 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -57,6 +57,8 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { val isApplicable = project.plugins.hasPlugin(SuspendTransformGradlePlugin::class.java) && project.configOrNull?.enabled?.get() != false + project.logger.info("Is suspend transform plugin applicable for {}: {}", kotlinCompilation, isApplicable) + return isApplicable } @@ -75,22 +77,21 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { val target = kotlinCompilation.target val project = target.project - return project.provider { resolveSubpluginOptions(target, project) } + project.logger.info("Apply suspend transform plugin to compilation {}, target: {}", kotlinCompilation, target) + + val extension = resolveExtension(project) + return project.provider { extension.toSubpluginOptions(target, project) } } - private fun resolveSubpluginOptions(target: KotlinTarget, project: Project): List { + private fun resolveExtension(project: Project): SuspendTransformPluginExtension { val extension = project.extensions.getByType(SuspendTransformPluginExtension::class.java) @Suppress("DEPRECATION") val oldExtension = project.extensions.getByType(SuspendTransformGradleExtension::class.java) @Suppress("DEPRECATION") - if (oldExtension.enabled || oldExtension.transformers.isNotEmpty()) { - val showError = - project.providers.gradleProperty("love.forte.plugin.suspend-transform.deprecatedExtensionError") - .map { it.toBoolean() }.getOrElse(true) - - val showWarn = - project.providers.gradleProperty("love.forte.plugin.suspend-transform.deprecatedExtensionWarn") + if (oldExtension.enabled && oldExtension.transformers.isNotEmpty()) { + val dontShowWarn = + project.providers.gradleProperty("love.forte.plugin.suspend-transform.suppressDeprecatedExtensionWarn") .map { it.toBoolean() }.getOrElse(false) val msg = "The `love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension` " + @@ -101,20 +102,14 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { "will currently be aggregated with `SuspendTransformPluginExtension`, " + "but it will soon be deprecated completely. " - when { - showError -> { - project.logger.error(msg) - } - - showWarn -> { - project.logger.warn(msg) - } + if (!dontShowWarn) { + project.logger.warn(msg) } oldExtension.mergeTo(extension) } - return extension.toSubpluginOptions(target, project) + return extension } } @@ -132,13 +127,13 @@ private fun SuspendTransformGradleExtension.mergeTo(extension: SuspendTransformP // Not the default value if (deprecatedAnnotationVersion != SuspendTransPluginConstants.ANNOTATION_VERSION) { extension.annotationDependency { - it.version.convention(deprecatedAnnotationVersion) + version.convention(deprecatedAnnotationVersion) } } val deprecatedAnnotationConfigurationName = this.annotationConfigurationName if (deprecatedAnnotationConfigurationName != "compileOnly") { extension.annotationDependency { - it.configurationName.convention(deprecatedAnnotationConfigurationName) + configurationName.convention(deprecatedAnnotationConfigurationName) } } @@ -150,13 +145,13 @@ private fun SuspendTransformGradleExtension.mergeTo(extension: SuspendTransformP val deprecatedRuntimeVersion = this.runtimeDependencyVersion if (deprecatedRuntimeVersion != SuspendTransPluginConstants.RUNTIME_VERSION) { extension.runtimeDependency { - it.version.convention(deprecatedRuntimeVersion) + version.convention(deprecatedRuntimeVersion) } } val deprecatedRuntimeConfigurationName = this.runtimeConfigurationName if (deprecatedRuntimeConfigurationName != "implementation") { extension.runtimeDependency { - it.configurationName.convention(deprecatedRuntimeConfigurationName) + configurationName.convention(deprecatedRuntimeConfigurationName) } } @@ -370,6 +365,9 @@ fun Project.configureMultiplatformDependency(conf: SuspendTransformPluginExtensi return } + val sourceSetsByCompilation = sourceSetsByCompilation() + project.logger.info("Suspend transform sourceSetsByCompilation: $sourceSetsByCompilation") + // 时间久远,已经忘记为什么要做这个判断了,也忘记这段是在哪儿参考来的了💀 if (rootProject.getBooleanProperty("kotlin.mpp.enableGranularSourceSetsMetadata")) { val multiplatformExtensions = project.extensions.getByType(KotlinMultiplatformExtension::class.java) @@ -403,7 +401,7 @@ fun Project.configureMultiplatformDependency(conf: SuspendTransformPluginExtensi // For each source set that is only used in Native compilations, add an implementation dependency so that it // gets published and is properly consumed as a transitive dependency: - sourceSetsByCompilation().forEach { (sourceSet, compilations) -> + sourceSetsByCompilation.forEach { (sourceSet, compilations) -> val isSharedSourceSet = compilations.all { it.platformType == KotlinPlatformType.common || it.platformType == KotlinPlatformType.native || it.platformType == KotlinPlatformType.js || it.platformType == KotlinPlatformType.wasm @@ -434,7 +432,7 @@ fun Project.configureMultiplatformDependency(conf: SuspendTransformPluginExtensi } } } else { - sourceSetsByCompilation().forEach { (sourceSet, compilations) -> + sourceSetsByCompilation.forEach { (sourceSet, compilations) -> val platformTypes = compilations.map { it.platformType }.toSet() logger.info( "Configure sourceSet [{}]. compilations: {}, platformTypes: {}", diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index f119634..6e2a102 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -7,9 +7,11 @@ import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguratio import org.gradle.api.Action import org.gradle.api.DomainObjectSet import org.gradle.api.Named -import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.model.ObjectFactory -import org.gradle.api.provider.* +import org.gradle.api.provider.ListProperty +import org.gradle.api.provider.Property +import org.gradle.api.provider.Provider +import org.gradle.api.provider.ProviderFactory import javax.inject.Inject /** @@ -33,8 +35,10 @@ internal interface NamedTransformerSpecListContainerInternal : NamedTransformerS override val platform: Property } -@RequiresOptIn("This API is an experimental public TransformersContainer's api. " + - "It may be changed in the future without notice.") +@RequiresOptIn( + "This API is an experimental public TransformersContainer's api. " + + "It may be changed in the future without notice." +) annotation class ExperimentalTransformersContainerApi /** @@ -44,33 +48,35 @@ abstract class TransformersContainer @Inject constructor( private val objects: ObjectFactory ) : SuspendTransformPluginExtensionSpec { - private val _containers: NamedDomainObjectContainer = - objects.domainObjectContainer(NamedTransformerSpecListContainerInternal::class.java) { name -> - val targetPlatform = try { - TargetPlatform.valueOf(name) - } catch (e: IllegalArgumentException) { - throw IllegalArgumentException( - "The name '$name' is not a valid TargetPlatform name. " + - "Valid names: ${TargetPlatform.entries.joinToString { it.name }}", - e - ) - } - - objects.newInstance( - NamedTransformerSpecListContainerInternal::class.java, - name - ).apply { - platform.set(targetPlatform) - } - } - - @ExperimentalTransformersContainerApi - val containers: NamedDomainObjectContainer - get() = _containers + internal val _containers: MutableMap> = + mutableMapOf() + + // private val _containers: NamedDomainObjectContainer = + // objects.domainObjectContainer(NamedTransformerSpecListContainerInternal::class.java) { name -> + // val targetPlatform = try { + // TargetPlatform.valueOf(name) + // } catch (e: IllegalArgumentException) { + // throw IllegalArgumentException( + // "The name '$name' is not a valid TargetPlatform name. " + + // "Valid names: ${TargetPlatform.entries.joinToString { it.name }}", + // e + // ) + // } + // + // objects.newInstance( + // NamedTransformerSpecListContainerInternal::class.java, + // name + // ).apply { + // platform.set(targetPlatform) + // } + // } + + // @ExperimentalTransformersContainerApi + // val containers: NamedDomainObjectContainer + // get() = _containers private fun getTransformersInternal(platform: TargetPlatform): ListProperty { - val container = _containers.findByName(platform.name) - return container?.transformers ?: _containers.create(platform.name).transformers + return _containers.computeIfAbsent(platform) { objects.listProperty(TransformerSpec::class.java) } } /** @@ -83,7 +89,7 @@ abstract class TransformersContainer /** * Create a [TransformerSpec] but not add. */ - fun createTransformer(action: (TransformerSpec) -> Unit): TransformerSpec { + fun createTransformer(action: TransformerSpec.() -> Unit): TransformerSpec { return objects.newInstance().also(action) } @@ -92,7 +98,7 @@ abstract class TransformersContainer listProperty.add(createTransformer(action)) } - fun add(platform: TargetPlatform, action: (TransformerSpec) -> Unit) { + fun add(platform: TargetPlatform, action: TransformerSpec.() -> Unit) { val listProperty = getTransformersInternal(platform) listProperty.add(createTransformer(action)) } @@ -109,38 +115,38 @@ abstract class TransformersContainer fun add(platform: TargetPlatform, transformer: Transformer) { add(platform) { - it.from(transformer) + from(transformer) } } fun addJvm(transformer: TransformerSpec) = add(TargetPlatform.JVM, transformer) - fun addJvm(transformer: Transformer) = addJvm { it.from(transformer) } + fun addJvm(transformer: Transformer) = addJvm { from(transformer) } fun addJvm(transformer: Provider) = add(TargetPlatform.JVM, transformer) fun addJvm(action: Action) = add(TargetPlatform.JVM, action) - fun addJvm(action: (TransformerSpec) -> Unit) = add(TargetPlatform.JVM, action) + fun addJvm(action: TransformerSpec.() -> Unit) = add(TargetPlatform.JVM, action) fun addJs(transformer: TransformerSpec) = add(TargetPlatform.JS, transformer) - fun addJs(transformer: Transformer) = addJs { it.from(transformer) } + fun addJs(transformer: Transformer) = addJs { from(transformer) } fun addJs(transformer: Provider) = add(TargetPlatform.JS, transformer) fun addJs(action: Action) = add(TargetPlatform.JS, action) - fun addJs(action: (TransformerSpec) -> Unit) = add(TargetPlatform.JS, action) + fun addJs(action: TransformerSpec.() -> Unit) = add(TargetPlatform.JS, action) fun addNative(transformer: TransformerSpec) = add(TargetPlatform.NATIVE, transformer) - fun addNative(transformer: Transformer) = addNative { it.from(transformer) } + fun addNative(transformer: Transformer) = addNative { from(transformer) } fun addNative(transformer: Provider) = add(TargetPlatform.NATIVE, transformer) fun addNative(action: Action) = add(TargetPlatform.NATIVE, action) - fun addNative(action: (TransformerSpec) -> Unit) = add(TargetPlatform.NATIVE, action) + fun addNative(action: TransformerSpec.() -> Unit) = add(TargetPlatform.NATIVE, action) fun addWasm(transformer: TransformerSpec) = add(TargetPlatform.WASM, transformer) - fun addWasm(transformer: Transformer) = addWasm { it.from(transformer) } + fun addWasm(transformer: Transformer) = addWasm { from(transformer) } fun addWasm(transformer: Provider) = add(TargetPlatform.WASM, transformer) fun addWasm(action: Action) = add(TargetPlatform.WASM, action) - fun addWasm(action: (TransformerSpec) -> Unit) = add(TargetPlatform.WASM, action) + fun addWasm(action: TransformerSpec.() -> Unit) = add(TargetPlatform.WASM, action) fun addCommon(transformer: TransformerSpec) = add(TargetPlatform.COMMON, transformer) - fun addCommon(transformer: Transformer) = addCommon { it.from(transformer) } + fun addCommon(transformer: Transformer) = addCommon { from(transformer) } fun addCommon(transformer: Provider) = add(TargetPlatform.COMMON, transformer) - fun addCommon(action: (TransformerSpec) -> Unit) = add(TargetPlatform.COMMON, action) + fun addCommon(action: TransformerSpec.() -> Unit) = add(TargetPlatform.COMMON, action) // JVM defaults @@ -150,16 +156,15 @@ abstract class TransformersContainer fun addJvmBlocking(action: Action) { addJvm { - it.from(jvmBlockingTransformer) - action.execute(it) + from(jvmBlockingTransformer) + action.execute(this) } } - fun addJvmBlocking(action: (TransformerSpec) -> Unit) { - addJvmBlocking(Action(action)) + fun addJvmBlocking(action: TransformerSpec.() -> Unit) { addJvm { - it.from(jvmBlockingTransformer) - action(it) + from(jvmBlockingTransformer) + action() } } @@ -169,15 +174,15 @@ abstract class TransformersContainer fun addJvmAsync(action: Action) { addJvm { - it.from(jvmAsyncTransformer) - action.execute(it) + from(jvmAsyncTransformer) + action.execute(this) } } - fun addJvmAsync(action: (TransformerSpec) -> Unit) { + fun addJvmAsync(action: TransformerSpec.() -> Unit) { addJvm { - it.from(jvmAsyncTransformer) - action(it) + from(jvmAsyncTransformer) + action() } } @@ -193,10 +198,10 @@ abstract class TransformersContainer /** * Add a js transformer based on [jsPromiseTransformer] */ - fun addJsPromise(action: (TransformerSpec) -> Unit) { + fun addJsPromise(action: TransformerSpec.() -> Unit) { addJs { - it.from(jsPromiseTransformer) - action(it) + from(jsPromiseTransformer) + action() } } @@ -233,7 +238,7 @@ abstract class SuspendTransformPluginExtension action.execute(transformers) } - fun transformers(action: (TransformersContainer) -> Unit) { + fun transformers(action: TransformersContainer.() -> Unit) { action(transformers) } @@ -258,7 +263,7 @@ abstract class SuspendTransformPluginExtension annotationDependency.set(annotationDependency.get().also(action::execute)) } - fun annotationDependency(action: (AnnotationDependencySpec) -> Unit) { + fun annotationDependency(action: AnnotationDependencySpec.() -> Unit) { annotationDependency.set(annotationDependency.get().also(action)) } @@ -271,7 +276,7 @@ abstract class SuspendTransformPluginExtension runtimeDependency.set(runtimeDependency.get().also(action::execute)) } - fun runtimeDependency(action: (RuntimeDependencySpec) -> Unit) { + fun runtimeDependency(action: RuntimeDependencySpec.() -> Unit) { runtimeDependency.set(runtimeDependency.get().also(action)) } @@ -285,16 +290,13 @@ internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransform return SuspendTransformConfiguration( enabled = enabled.getOrElse(true), transformers = buildMap { - val transformers = transformers.containers - for (targetPlatform in TargetPlatform.entries) { - transformers.findByName(targetPlatform.name)?.also { container -> - val list = container.transformers.map { valueList -> - valueList.map { it.toTransformer() } - }.getOrElse(emptyList()) - - if (list.isNotEmpty()) { - put(targetPlatform, list) - } + transformers._containers.forEach { targetPlatform, transformerListProperty -> + val list = transformerListProperty + .map { valueList -> valueList.map { it.toTransformer() } } + .getOrElse(emptyList()) + + if (list.isNotEmpty()) { + put(targetPlatform, list) } } }, @@ -375,7 +377,7 @@ abstract class TransformerSpec markAnnotation.set(old.also(action::execute)) } - fun markAnnotation(action: (MarkAnnotationSpec) -> Unit) { + fun markAnnotation(action: MarkAnnotationSpec.() -> Unit) { val old = markAnnotation.getOrElse(objects.newInstance()) markAnnotation.set(old.also(action)) } @@ -412,7 +414,7 @@ abstract class TransformerSpec ) } - fun transformFunctionInfo(action: (FunctionInfoSpec) -> Unit) { + fun transformFunctionInfo(action: FunctionInfoSpec.() -> Unit) { transformFunctionInfo.set( transformFunctionInfo.getOrElse( objects.newInstance() @@ -435,7 +437,7 @@ abstract class TransformerSpec ) } - fun transformReturnType(action: (ClassInfoSpec) -> Unit) { + fun transformReturnType(action: ClassInfoSpec.() -> Unit) { transformReturnType.set( transformReturnType.getOrElse( objects.newInstance() @@ -471,7 +473,7 @@ abstract class TransformerSpec return newIncludeAnnotationSpec().also(action::execute) } - fun createIncludeAnnotation(action: (IncludeAnnotationSpec) -> Unit): IncludeAnnotationSpec { + fun createIncludeAnnotation(action: IncludeAnnotationSpec.() -> Unit): IncludeAnnotationSpec { return newIncludeAnnotationSpec().also(action) } @@ -481,7 +483,7 @@ abstract class TransformerSpec ) } - fun addOriginFunctionIncludeAnnotation(action: (IncludeAnnotationSpec) -> Unit) { + fun addOriginFunctionIncludeAnnotation(action: IncludeAnnotationSpec.() -> Unit) { originFunctionIncludeAnnotations.add( newIncludeAnnotationSpec().also(action) ) @@ -493,7 +495,7 @@ abstract class TransformerSpec syntheticFunctionIncludeAnnotations.add(createIncludeAnnotation(action)) } - fun addSyntheticFunctionIncludeAnnotation(action: (IncludeAnnotationSpec) -> Unit) { + fun addSyntheticFunctionIncludeAnnotation(action: IncludeAnnotationSpec.() -> Unit) { syntheticFunctionIncludeAnnotations.add(createIncludeAnnotation(action)) } @@ -525,7 +527,7 @@ abstract class TransformerSpec /** * Add a [ClassInfoSpec] into [copyAnnotationExcludes] */ - fun addCopyAnnotationExclude(action: (ClassInfoSpec) -> Unit) { + fun addCopyAnnotationExclude(action: ClassInfoSpec.() -> Unit) { copyAnnotationExcludes.add(createCopyAnnotationExclude(action)) } @@ -539,7 +541,7 @@ abstract class TransformerSpec /** * Create a [ClassInfoSpec] but does not add. */ - fun createCopyAnnotationExclude(action: (ClassInfoSpec) -> Unit): ClassInfoSpec { + fun createCopyAnnotationExclude(action: ClassInfoSpec.() -> Unit): ClassInfoSpec { return objects.newInstance().also(action) } @@ -562,21 +564,21 @@ abstract class TransformerSpec * e.g. [SuspendTransformConfigurations.jvmBlockingTransformer]. */ fun from(transformer: Transformer) { - markAnnotation { it.from(transformer.markAnnotation) } - transformFunctionInfo { it.from(transformer.transformFunctionInfo) } + markAnnotation { from(transformer.markAnnotation) } + transformFunctionInfo { from(transformer.transformFunctionInfo) } transformer.transformReturnType?.also { transformReturnType -> - transformReturnType { it.from(transformReturnType) } + transformReturnType { from(transformReturnType) } } transformReturnTypeGeneric.set(transformer.transformReturnTypeGeneric) for (originFunctionIncludeAnnotation in transformer.originFunctionIncludeAnnotations) { addOriginFunctionIncludeAnnotation { - it.from(originFunctionIncludeAnnotation) + from(originFunctionIncludeAnnotation) } } for (syntheticFunctionIncludeAnnotation in transformer.syntheticFunctionIncludeAnnotations) { addSyntheticFunctionIncludeAnnotation { - it.from(syntheticFunctionIncludeAnnotation) + from(syntheticFunctionIncludeAnnotation) } } @@ -584,7 +586,7 @@ abstract class TransformerSpec for (copyAnnotationExclude in transformer.copyAnnotationExcludes) { addCopyAnnotationExclude { - it.from(copyAnnotationExclude) + from(copyAnnotationExclude) } } @@ -609,7 +611,7 @@ abstract class MarkAnnotationSpec classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } - fun classInfo(action: (ClassInfoSpec) -> Unit) { + fun classInfo(action: ClassInfoSpec.() -> Unit) { classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action)) } @@ -653,7 +655,7 @@ abstract class MarkAnnotationSpec fun from(markAnnotation: MarkAnnotation) { classInfo { - it.from(markAnnotation.classInfo) + from(markAnnotation.classInfo) } baseNameProperty.set(markAnnotation.baseNameProperty) suffixProperty.set(markAnnotation.suffixProperty) @@ -715,7 +717,7 @@ abstract class IncludeAnnotationSpec classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } - fun classInfo(action: (ClassInfoSpec) -> Unit) { + fun classInfo(action: ClassInfoSpec.() -> Unit) { classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action)) } @@ -731,7 +733,7 @@ abstract class IncludeAnnotationSpec fun from(includeAnnotation: IncludeAnnotation) { classInfo { - it.from(includeAnnotation.classInfo) + from(includeAnnotation.classInfo) } repeatable.set(includeAnnotation.repeatable) includeProperty.set(includeAnnotation.includeProperty) diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index 7b27338..c41409f 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -1,3 +1,6 @@ +import jdk.tools.jlink.resources.plugins +import org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 + plugins { `java-library` kotlin("jvm") @@ -7,9 +10,11 @@ plugins { } kotlin { + jvmToolchain(11) compilerOptions { + jvmTarget = JVM_11 + javaParameters = true freeCompilerArgs.add("-Xjvm-default=all") - } } @@ -32,49 +37,49 @@ suspendTransformPlugin { includeAnnotation = false includeRuntime = false transformers { - + useDefault() // For blocking - addJvm { - markAnnotation { - classInfo { - packageName = "com.example" - className = "JTrans" - } - baseNameProperty = "blockingBaseName" - suffixProperty = "blockingSuffix" - asPropertyProperty = "blockingAsProperty" - defaultSuffix = "Blocking" - defaultAsProperty = false - } - - transformFunctionInfo { - packageName = "com.example" - functionName = "inBlock" - } - - // other config... - } - - // For async - addJvm { - markAnnotation { - classInfo { - packageName = "com.example" - className = "JTrans" - } - baseNameProperty = "asyncBaseName" - suffixProperty = "asyncSuffix" - asPropertyProperty = "asyncAsProperty" - defaultSuffix = "Async" - defaultAsProperty = false - } - - transformFunctionInfo { - packageName = "com.example" - functionName = "inAsync" - } - } + // addJvm { + // markAnnotation { + // classInfo { + // packageName = "com.example" + // className = "JTrans" + // } + // baseNameProperty = "blockingBaseName" + // suffixProperty = "blockingSuffix" + // asPropertyProperty = "blockingAsProperty" + // defaultSuffix = "Blocking" + // defaultAsProperty = false + // } + // + // transformFunctionInfo { + // packageName = "com.example" + // functionName = "inBlock" + // } + // + // // other config... + // } + // + // // For async + // addJvm { + // markAnnotation { + // classInfo { + // packageName = "com.example" + // className = "JTrans" + // } + // baseNameProperty = "asyncBaseName" + // suffixProperty = "asyncSuffix" + // asPropertyProperty = "asyncAsProperty" + // defaultSuffix = "Async" + // defaultAsProperty = false + // } + // + // transformFunctionInfo { + // packageName = "com.example" + // functionName = "inAsync" + // } + // } } } diff --git a/tests/test-jvm/src/test/kotlin/SuspendTransformTests.kt b/tests/test-jvm/src/test/kotlin/SuspendTransformTests.kt index 6df947e..e7f3a05 100644 --- a/tests/test-jvm/src/test/kotlin/SuspendTransformTests.kt +++ b/tests/test-jvm/src/test/kotlin/SuspendTransformTests.kt @@ -25,7 +25,9 @@ import love.forte.plugin.suspendtrans.annotation.JvmBlocking import java.lang.reflect.Modifier import java.util.concurrent.CompletableFuture import kotlin.reflect.KTypeParameter +import kotlin.reflect.full.functions import kotlin.reflect.full.memberProperties +import kotlin.reflect.jvm.javaMethod import kotlin.test.* @@ -69,6 +71,14 @@ class STPTrans1Impl : STPTrans1 { */ class SuspendTransformTests { + @Test + fun javaMethodResolve() { + val run1Blocking = STTrans1::class.functions.find { it.name == "run1Blocking" } + assertNotNull(run1Blocking) + println(run1Blocking) + println(run1Blocking.javaMethod) + } + @Test fun `interface suspend trans function test`() { with(STTrans1::class.java) { diff --git a/tests/test-kmp/build.gradle.kts b/tests/test-kmp/build.gradle.kts index f80b29b..3416d0b 100644 --- a/tests/test-kmp/build.gradle.kts +++ b/tests/test-kmp/build.gradle.kts @@ -1,5 +1,5 @@ -import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.kotlinJsExportIgnoreClassInfo -import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.kotlinOptInClassInfo +import jdk.tools.jlink.resources.plugins + plugins { kotlin("multiplatform") @@ -20,6 +20,8 @@ repositories { apply(plugin = "love.forte.plugin.suspend-transform") kotlin { + + jvmToolchain(11) jvm() js { nodejs() @@ -45,58 +47,45 @@ kotlin { implementation(project(":runtime:suspend-transform-runtime")) implementation(libs.kotlinx.coroutines.core) } + + commonTest.dependencies { + implementation(kotlin("test")) + implementation(libs.kotlinx.coroutines.test) + } } } +tasks.withType { + options.encoding = "UTF-8" + sourceCompatibility = "11" + targetCompatibility = "11" + + // see https://kotlinlang.org/docs/gradle-configure-project.html#configure-with-java-modules-jpms-enabled + // if (moduleName != null) { + // options.compilerArgumentProviders.add( + // CommandLineArgumentProvider { + // // Provide compiled Kotlin classes to javac – needed for Java/Kotlin mixed sources to work + // // listOf("--patch-module", "$moduleName=${sourceSets["main"].output.asPath}") + // val sourceSet = sourceSets.findByName("main") ?: sourceSets.findByName("jvmMain") + // if (sourceSet != null) { + // listOf("--patch-module", "$moduleName=${sourceSet.output.asPath}") + // } else { + // emptyList() + // } + // // listOf("--patch-module", "$moduleName=${sourceSets["main"].output.asPath}") + // } + // ) + // } +} + suspendTransformPlugin { includeRuntime = false includeAnnotation = false transformers { - addJvmBlocking { - addCopyAnnotationExclude { - from(kotlinOptInClassInfo) - } - } - addJvmAsync { - addCopyAnnotationExclude { - from(kotlinOptInClassInfo) - } - } - - addJsPromise { - addCopyAnnotationExclude { - from(kotlinOptInClassInfo) - } - addCopyAnnotationExclude { - from(kotlinJsExportIgnoreClassInfo) - } - } + useDefault() } } -// extensions.getByType().apply { -// includeRuntime = false -// includeAnnotation = false -// // useJvmDefault() -// transformers[TargetPlatform.JVM] = mutableListOf( -// // Add `kotlin.OptIn` to copyAnnotationExcludes -// jvmBlockingTransformer.copy( -// copyAnnotationExcludes = buildList { -// addAll(jvmBlockingTransformer.copyAnnotationExcludes) -// add(ClassInfo("kotlin", "OptIn")) -// } -// ), -// -// // Add `kotlin.OptIn` to copyAnnotationExcludes -// jvmAsyncTransformer.copy( -// copyAnnotationExcludes = buildList { -// addAll(jvmAsyncTransformer.copyAnnotationExcludes) -// add(ClassInfo("kotlin", "OptIn")) -// } -// ) -// ) -// } - tasks.withType { useJUnitPlatform() } diff --git a/tests/test-kmp/src/commonMain/kotlin/example/MyClass.kt b/tests/test-kmp/src/commonMain/kotlin/example/MyClass.kt index a15eeeb..28f03a9 100644 --- a/tests/test-kmp/src/commonMain/kotlin/example/MyClass.kt +++ b/tests/test-kmp/src/commonMain/kotlin/example/MyClass.kt @@ -1,5 +1,6 @@ package example +import kotlinx.coroutines.delay import love.forte.plugin.suspendtrans.annotation.JsPromise import love.forte.plugin.suspendtrans.annotation.JvmAsync import love.forte.plugin.suspendtrans.annotation.JvmBlocking @@ -16,4 +17,12 @@ class MyClass { @JsPromise @JsExport.Ignore suspend fun errorReproduction(amount: MoneyValue) = println(amount) + + @JvmBlocking + @JvmAsync + @JsExport.Ignore + suspend fun accept(): Int { + delay(1) + return 1 + } } diff --git a/tests/test-kmp/src/commonMain/kotlin/example/MyInterface.kt b/tests/test-kmp/src/commonMain/kotlin/example/MyInterface.kt new file mode 100644 index 0000000..6fed8be --- /dev/null +++ b/tests/test-kmp/src/commonMain/kotlin/example/MyInterface.kt @@ -0,0 +1,17 @@ +package example + +import love.forte.plugin.suspendtrans.annotation.JvmAsync +import love.forte.plugin.suspendtrans.annotation.JvmBlocking + +/** + * + * @author ForteScarlet + */ +interface MyInterface { + @JvmBlocking + @JvmAsync + suspend fun delete() + @JvmBlocking + @JvmAsync + suspend fun delete(vararg value: String) +} \ No newline at end of file diff --git a/tests/test-kmp/src/jvmTest/kotlin/MyClassReflectTests.kt b/tests/test-kmp/src/jvmTest/kotlin/MyClassReflectTests.kt new file mode 100644 index 0000000..7fe8de7 --- /dev/null +++ b/tests/test-kmp/src/jvmTest/kotlin/MyClassReflectTests.kt @@ -0,0 +1,26 @@ +import example.MyClass +import example.MyInterface +import kotlin.reflect.full.functions +import kotlin.reflect.jvm.javaMethod +import kotlin.test.Test +import kotlin.test.assertNotNull + +/** + * + * @author ForteScarlet + */ +class MyClassReflectTests { + + @Test + fun testMyClassReflect() { + val acceptBlocking = MyClass::class.functions.find { it.name == "acceptBlocking" } + assertNotNull(acceptBlocking) + println(acceptBlocking) + println(acceptBlocking.javaMethod) + + val deleteBlocking = MyInterface::class.functions.find { it.name == "deleteBlocking" } + assertNotNull(deleteBlocking) + println(deleteBlocking) + println(deleteBlocking.javaMethod) + } +} \ No newline at end of file From c8edc3ef37678b2c83fc1fdae689d985b359bb81 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Fri, 18 Apr 2025 14:52:06 +0800 Subject: [PATCH 15/21] WARN log prefix --- README.md | 4 +- .../gradle/SuspendTransformGradleExtension.kt | 2 +- .../gradle/SuspendTransformGradlePlugin.kt | 26 ++++---- tests/test-jvm/build.gradle.kts | 59 ++++--------------- tests/test-kmp/build.gradle.kts | 22 +++++-- .../commonMain/kotlin/example/MyInterface.kt | 9 +++ 6 files changed, 58 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 03d3f3b..c699505 100644 --- a/README.md +++ b/README.md @@ -864,6 +864,8 @@ try this: _build.gradle.kts_ ```kotlin +import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations + plugins { // ... } @@ -872,7 +874,7 @@ suspendTransformPlugin { transformers { addJsPromise { addCopyAnnotationExclude { - // The generated function does not include `@JsExport.Ignore`. + // The generated function does not include (copy) `@JsExport.Ignore`. from(kotlinJsExportIgnoreClassInfo) } } diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt index c676856..3cd9832 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradleExtension.kt @@ -20,7 +20,7 @@ open class SuspendTransformGradleExtension : love.forte.plugin.suspendtrans.Susp @Deprecated("Please use the " + "`love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration` " + "(`suspendTransformPlugin { ... }`) instead.") - override var enabled: Boolean = false + override var enabled: Boolean = true /** * 是否增加 `love.forte.plugin.suspend-transform:suspend-transform-annotation` 的运行时。 diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index 7b448b0..cc6d4ca 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -57,7 +57,7 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { val isApplicable = project.plugins.hasPlugin(SuspendTransformGradlePlugin::class.java) && project.configOrNull?.enabled?.get() != false - project.logger.info("Is suspend transform plugin applicable for {}: {}", kotlinCompilation, isApplicable) + project.logger.debug("Is suspend transform plugin applicable for {}: {}", kotlinCompilation, isApplicable) return isApplicable } @@ -77,7 +77,7 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { val target = kotlinCompilation.target val project = target.project - project.logger.info("Apply suspend transform plugin to compilation {}, target: {}", kotlinCompilation, target) + project.logger.debug("Apply suspend transform plugin to compilation {}, target: {}", kotlinCompilation, target) val extension = resolveExtension(project) return project.provider { extension.toSubpluginOptions(target, project) } @@ -92,15 +92,18 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { if (oldExtension.enabled && oldExtension.transformers.isNotEmpty()) { val dontShowWarn = project.providers.gradleProperty("love.forte.plugin.suspend-transform.suppressDeprecatedExtensionWarn") - .map { it.toBoolean() }.getOrElse(false) + .orNull.toBoolean() - val msg = "The `love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension` " + - "(`suspendTransform { ... }`) is deprecated, " + + + val msg = "WARN: The `love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension` " + + "(`suspendTransform { ... }`) is deprecated, \n" + "please use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + - "(`suspendTransformPlugin { ... }`) instead. " + + "(`suspendTransformPlugin { ... }`) instead. \n" + "The SuspendTransformGradleExtension property " + "will currently be aggregated with `SuspendTransformPluginExtension`, " + - "but it will soon be deprecated completely. " + "but it will soon be deprecated completely. \n" + + "Add 'love.forte.plugin.suspend-transform.suppressDeprecatedExtensionWarn=true' " + + "to gradle.properties to suppress this warning." if (!dontShowWarn) { project.logger.warn(msg) @@ -252,18 +255,21 @@ private fun DeprecatedIncludeAnnotation.toIncludeAnnotation(): IncludeAnnotation ) } -private fun SuspendTransformPluginExtension.toSubpluginOptions(target: KotlinTarget, project: Project): List { +private fun SuspendTransformPluginExtension.toSubpluginOptions( + target: KotlinTarget, + project: Project +): List { // If not enabled or transformer is empty. val cliConfig = SuspendTransformCliOptions.CLI_CONFIGURATION val configuration = toConfiguration() return if (configuration.enabled && configuration.transformers.isNotEmpty()) { if (project.logger.isInfoEnabled) { val count = configuration.transformers.values.sumOf { it.size } - project.logger.info("The suspend transform is enabled with {} transformer(s) for {}", count, target) + project.logger.debug("The suspend transform is enabled with {} transformer(s) for {}", count, target) } listOf(SubpluginOption(cliConfig.optionName, configuration.encodeToHex())) } else { - project.logger.info("The suspend transform is disabled or transformers are empty for {}.", target) + project.logger.debug("The suspend transform is disabled or transformers are empty for {}.", target) emptyList() } } diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index c41409f..30d336b 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -1,4 +1,3 @@ -import jdk.tools.jlink.resources.plugins import org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 plugins { @@ -33,56 +32,22 @@ dependencies { api(libs.kotlinx.coroutines.core) } -suspendTransformPlugin { +@Suppress("DEPRECATION") +suspendTransform { + enabled = true includeAnnotation = false includeRuntime = false - transformers { - useDefault() - - // For blocking - // addJvm { - // markAnnotation { - // classInfo { - // packageName = "com.example" - // className = "JTrans" - // } - // baseNameProperty = "blockingBaseName" - // suffixProperty = "blockingSuffix" - // asPropertyProperty = "blockingAsProperty" - // defaultSuffix = "Blocking" - // defaultAsProperty = false - // } - // - // transformFunctionInfo { - // packageName = "com.example" - // functionName = "inBlock" - // } - // - // // other config... - // } - // - // // For async - // addJvm { - // markAnnotation { - // classInfo { - // packageName = "com.example" - // className = "JTrans" - // } - // baseNameProperty = "asyncBaseName" - // suffixProperty = "asyncSuffix" - // asPropertyProperty = "asyncAsProperty" - // defaultSuffix = "Async" - // defaultAsProperty = false - // } - // - // transformFunctionInfo { - // packageName = "com.example" - // functionName = "inAsync" - // } - // } - } + useDefault() } +// suspendTransformPlugin { +// includeAnnotation = false +// includeRuntime = false +// transformers { +// useDefault() +// } +// } + /* > val blockingBaseName: String = "", > val blockingSuffix: String = "Blocking", diff --git a/tests/test-kmp/build.gradle.kts b/tests/test-kmp/build.gradle.kts index 3416d0b..d6f6097 100644 --- a/tests/test-kmp/build.gradle.kts +++ b/tests/test-kmp/build.gradle.kts @@ -1,5 +1,5 @@ -import jdk.tools.jlink.resources.plugins - +import love.forte.plugin.suspendtrans.ClassInfo +import love.forte.plugin.suspendtrans.SuspendTransformConfiguration plugins { kotlin("multiplatform") @@ -81,11 +81,23 @@ tasks.withType { suspendTransformPlugin { includeRuntime = false includeAnnotation = false - transformers { - useDefault() - } } +@Suppress("DEPRECATION") +suspendTransform { + includeRuntime = false + includeAnnotation = false + useJvmDefault() + addJsTransformers( + SuspendTransformConfiguration.jsPromiseTransformer.copy( + copyAnnotationExcludes = listOf( + ClassInfo("kotlin.js", "JsExport.Ignore") + ) + ) + ) +} + + tasks.withType { useJUnitPlatform() } diff --git a/tests/test-kmp/src/commonMain/kotlin/example/MyInterface.kt b/tests/test-kmp/src/commonMain/kotlin/example/MyInterface.kt index 6fed8be..2d9f5ae 100644 --- a/tests/test-kmp/src/commonMain/kotlin/example/MyInterface.kt +++ b/tests/test-kmp/src/commonMain/kotlin/example/MyInterface.kt @@ -1,17 +1,26 @@ package example +import love.forte.plugin.suspendtrans.annotation.JsPromise import love.forte.plugin.suspendtrans.annotation.JvmAsync import love.forte.plugin.suspendtrans.annotation.JvmBlocking +import kotlin.js.ExperimentalJsExport +import kotlin.js.JsExport /** * * @author ForteScarlet */ +@OptIn(ExperimentalJsExport::class) +@JsExport interface MyInterface { @JvmBlocking @JvmAsync + @JsPromise + @JsExport.Ignore suspend fun delete() @JvmBlocking @JvmAsync + @JsPromise(baseName = "delete2") + @JsExport.Ignore suspend fun delete(vararg value: String) } \ No newline at end of file From e43c10eed445e356c369039a646b1ca0bedebd8a Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Sat, 19 Apr 2025 15:11:39 +0800 Subject: [PATCH 16/21] Make the Gradle plugin buildSrc friendly --- buildSrc/src/main/kotlin/GradleSupportHelper.kt | 10 ++++++++++ compiler/suspend-transform-plugin-cli/build.gradle.kts | 5 ++--- .../build.gradle.kts | 5 ++--- .../build.gradle.kts | 5 ++--- .../suspendtrans/fir/SuspendTransformFirTransformer.kt | 6 +++++- .../suspend-transform-plugin-gradle/build.gradle.kts | 4 ++-- 6 files changed, 23 insertions(+), 12 deletions(-) create mode 100644 buildSrc/src/main/kotlin/GradleSupportHelper.kt diff --git a/buildSrc/src/main/kotlin/GradleSupportHelper.kt b/buildSrc/src/main/kotlin/GradleSupportHelper.kt new file mode 100644 index 0000000..b7f3f71 --- /dev/null +++ b/buildSrc/src/main/kotlin/GradleSupportHelper.kt @@ -0,0 +1,10 @@ +/** + * 为了让 gradle 插件可以在 buildSrc 之类的地方使用。 + */ +fun org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension.configGradleBuildSrcFriendly() { + coreLibrariesVersion = "1.9.0" + compilerOptions { + apiVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9) + languageVersion.set(org.jetbrains.kotlin.gradle.dsl.KotlinVersion.KOTLIN_1_9) + } +} diff --git a/compiler/suspend-transform-plugin-cli/build.gradle.kts b/compiler/suspend-transform-plugin-cli/build.gradle.kts index 24dc011..1937890 100644 --- a/compiler/suspend-transform-plugin-cli/build.gradle.kts +++ b/compiler/suspend-transform-plugin-cli/build.gradle.kts @@ -21,11 +21,10 @@ dependencies { } kotlin { + configGradleBuildSrcFriendly() compilerOptions { jvmTarget.set(JvmTarget.JVM_1_8) - freeCompilerArgs.addAll( - "-Xjvm-default=all", - ) + freeCompilerArgs.addAll("-Xjvm-default=all") } } diff --git a/compiler/suspend-transform-plugin-configuration/build.gradle.kts b/compiler/suspend-transform-plugin-configuration/build.gradle.kts index 3595f12..0db94ea 100644 --- a/compiler/suspend-transform-plugin-configuration/build.gradle.kts +++ b/compiler/suspend-transform-plugin-configuration/build.gradle.kts @@ -15,11 +15,10 @@ dependencies { } kotlin { + configGradleBuildSrcFriendly() compilerOptions { jvmTarget.set(JvmTarget.JVM_1_8) - freeCompilerArgs.addAll( - "-Xjvm-default=all", - ) + freeCompilerArgs.addAll("-Xjvm-default=all",) } } diff --git a/compiler/suspend-transform-plugin-deprecated-configuration/build.gradle.kts b/compiler/suspend-transform-plugin-deprecated-configuration/build.gradle.kts index 49a6a0b..56b2a51 100644 --- a/compiler/suspend-transform-plugin-deprecated-configuration/build.gradle.kts +++ b/compiler/suspend-transform-plugin-deprecated-configuration/build.gradle.kts @@ -14,11 +14,10 @@ dependencies { } kotlin { + configGradleBuildSrcFriendly() compilerOptions { jvmTarget.set(JvmTarget.JVM_1_8) - freeCompilerArgs.addAll( - "-Xjvm-default=all", - ) + freeCompilerArgs.addAll("-Xjvm-default=all") } } diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt index 609b3c1..a6b499c 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/fir/SuspendTransformFirTransformer.kt @@ -6,7 +6,9 @@ import love.forte.plugin.suspendtrans.configuration.TargetPlatform import love.forte.plugin.suspendtrans.configuration.Transformer import love.forte.plugin.suspendtrans.fqn import love.forte.plugin.suspendtrans.utils.* +import org.jetbrains.kotlin.KtFakeSourceElementKind import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.fakeElement import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext import org.jetbrains.kotlin.fir.analysis.checkers.context.MutableCheckerContext @@ -55,6 +57,7 @@ import org.jetbrains.kotlin.platform.isJs import org.jetbrains.kotlin.platform.isWasm import org.jetbrains.kotlin.platform.jvm.isJvm import org.jetbrains.kotlin.platform.konan.isNative +import org.jetbrains.kotlin.realElement import org.jetbrains.kotlin.utils.keysToMap import java.util.concurrent.ConcurrentHashMap @@ -607,6 +610,7 @@ class SuspendTransformFirTransformer( val newFunTarget = FirFunctionTarget(null, isLambda = false) val newFun = buildSimpleFunctionCopy(originFunc) { origin = FirDeclarationOrigin.Plugin(SuspendTransformK2V3Key) + source = originFunc.source?.fakeElement(KtFakeSourceElementKind.PluginGenerated) name = callableId.callableName symbol = newFunSymbol status = originFunc.status.copy( @@ -726,7 +730,7 @@ class SuspendTransformFirTransformer( val p1 = buildProperty { symbol = pSymbol name = callableId.callableName - source = original.source + source = original.source?.fakeElement(KtFakeSourceElementKind.PluginGenerated) resolvePhase = original.resolvePhase moduleData = original.moduleData origin = pKey.origin diff --git a/plugins/suspend-transform-plugin-gradle/build.gradle.kts b/plugins/suspend-transform-plugin-gradle/build.gradle.kts index 763cfb8..dbad3c8 100644 --- a/plugins/suspend-transform-plugin-gradle/build.gradle.kts +++ b/plugins/suspend-transform-plugin-gradle/build.gradle.kts @@ -3,6 +3,7 @@ import love.forte.gradle.common.publication.configure.configPublishMaven import love.forte.gradle.common.publication.configure.publishingExtension import love.forte.gradle.common.publication.configure.setupPom import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import utils.isMainPublishable @@ -33,10 +34,10 @@ dependencies { api(project(":compiler:suspend-transform-plugin-cli")) api(project(":compiler:suspend-transform-plugin-configuration")) api(project(":compiler:suspend-transform-plugin-deprecated-configuration")) - } kotlin { + configGradleBuildSrcFriendly() compilerOptions { freeCompilerArgs.addAll("-Xjvm-default=all") } @@ -72,7 +73,6 @@ buildConfig { //if (!isAutomatedGradlePluginPublishing()) { if (isMainPublishable()) { - @Suppress("UnstableApiUsage") gradlePlugin { website = "https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin" vcsUrl = "https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin.git" From 8d3cdeeb102e5f10366a36fd910063294af8b693 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Sat, 19 Apr 2025 15:38:03 +0800 Subject: [PATCH 17/21] Improve the Gradle plugin's API and configuration's API. --- .../cli/ConfigurationSerializeTests.kt | 7 ++- .../SuspendTransformConfiguration.kt | 43 ++++++++++--------- .../SuspendTransformCommandLineProcessor.kt | 4 +- .../SuspendTransformComponentRegistrar.kt | 6 +-- ...spendTransformerEnvironmentConfigurator.kt | 5 +-- .../gradle/SuspendTransformGradlePlugin.kt | 38 +++++++++++++--- .../gradle/SuspendTransformPluginExtension.kt | 15 ++++--- 7 files changed, 72 insertions(+), 46 deletions(-) diff --git a/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt b/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt index 18aa6e9..3821bab 100644 --- a/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt +++ b/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt @@ -1,6 +1,6 @@ package love.forte.plugin.suspendtrans.cli -import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConstructorApi +import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConfigurationApi import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jsPromiseTransformer import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmAsyncTransformer @@ -14,13 +14,12 @@ import kotlin.test.assertEquals * @author ForteScarlet */ class ConfigurationSerializeTests { - @OptIn(InternalSuspendTransformConstructorApi::class) + @OptIn(InternalSuspendTransformConfigurationApi::class) @Test fun testDecode() { - assertEquals("0801", SuspendTransformConfiguration(true, emptyMap()).encodeToHex()) + assertEquals("0801", SuspendTransformConfiguration(emptyMap()).encodeToHex()) val config = SuspendTransformConfiguration( - enabled = true, transformers = mapOf( TargetPlatform.JVM to listOf(jvmBlockingTransformer, jvmAsyncTransformer), TargetPlatform.JS to listOf(jsPromiseTransformer), diff --git a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt index 84221ea..c73401c 100644 --- a/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt +++ b/compiler/suspend-transform-plugin-configuration/src/main/kotlin/love/forte/plugin/suspendtrans/configuration/SuspendTransformConfiguration.kt @@ -7,13 +7,14 @@ import kotlinx.serialization.Serializable // 虽然序列化行为是内部的,但是还是应该尽可能避免出现字段的顺序错乱或删改。 @RequiresOptIn( - "This is an internal suspend transform config api. " + + "This is an internal suspend transform configuration's api. " + "It may be changed in the future without notice.", RequiresOptIn.Level.ERROR ) -annotation class InternalSuspendTransformConstructorApi +@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR) +annotation class InternalSuspendTransformConfigurationApi @Serializable -class FunctionInfo @InternalSuspendTransformConstructorApi constructor( +class FunctionInfo @InternalSuspendTransformConfigurationApi constructor( val packageName: String, val functionName: String ) { @@ -39,7 +40,7 @@ class FunctionInfo @InternalSuspendTransformConstructorApi constructor( } @Serializable -class ClassInfo @InternalSuspendTransformConstructorApi constructor( +class ClassInfo @InternalSuspendTransformConfigurationApi constructor( val packageName: String, val className: String, val local: Boolean = false, @@ -79,7 +80,7 @@ enum class TargetPlatform { * 用于标记的注解信息. */ @Serializable -class MarkAnnotation @InternalSuspendTransformConstructorApi constructor( +class MarkAnnotation @InternalSuspendTransformConfigurationApi constructor( /** * 注解类信息 */ @@ -135,7 +136,7 @@ class MarkAnnotation @InternalSuspendTransformConstructorApi constructor( } @Serializable -class IncludeAnnotation @InternalSuspendTransformConstructorApi constructor( +class IncludeAnnotation @InternalSuspendTransformConfigurationApi constructor( val classInfo: ClassInfo, val repeatable: Boolean = false, /** @@ -169,7 +170,7 @@ class IncludeAnnotation @InternalSuspendTransformConstructorApi constructor( } @Serializable -class Transformer @InternalSuspendTransformConstructorApi constructor( +class Transformer @InternalSuspendTransformConfigurationApi constructor( /** * 函数上的某种标记。 */ @@ -280,38 +281,40 @@ class Transformer @InternalSuspendTransformConstructorApi constructor( * 可序列化的配置信息。 */ @Serializable -class SuspendTransformConfiguration @InternalSuspendTransformConstructorApi constructor( - val enabled: Boolean, +class SuspendTransformConfiguration @InternalSuspendTransformConfigurationApi constructor( + /** + * The transformers. + * + * Note: This `Map` cannot be empty. + * The `List` values cannot be empty. + */ val transformers: Map> ) { + + override fun toString(): String { + return "SuspendTransformConfiguration(transformers=$transformers)" + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (other !is SuspendTransformConfiguration) return false - if (enabled != other.enabled) return false if (transformers != other.transformers) return false return true } override fun hashCode(): Int { - var result = enabled.hashCode() - result = 31 * result + transformers.hashCode() - return result - } - - override fun toString(): String { - return "SuspendTransformConfiguration(enabled=$enabled, transformers=$transformers)" + return transformers.hashCode() } } /** * Merge both */ -@InternalSuspendTransformConstructorApi +@InternalSuspendTransformConfigurationApi operator fun SuspendTransformConfiguration.plus(other: SuspendTransformConfiguration): SuspendTransformConfiguration { return SuspendTransformConfiguration( - enabled = enabled && other.enabled, transformers = transformers.toMutableMap().apply { other.transformers.forEach { (platform, transformers) -> compute(platform) { _, old -> @@ -325,7 +328,7 @@ operator fun SuspendTransformConfiguration.plus(other: SuspendTransformConfigura /** * Some constants for configuration. */ -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) object SuspendTransformConfigurations { private const val KOTLIN = "kotlin" private const val KOTLIN_JVM = "kotlin.jvm" diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformCommandLineProcessor.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformCommandLineProcessor.kt index f5625bd..a1d9212 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformCommandLineProcessor.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformCommandLineProcessor.kt @@ -4,7 +4,7 @@ import BuildConfig import love.forte.plugin.suspendtrans.cli.SuspendTransformCliOptions import love.forte.plugin.suspendtrans.cli.decodeSuspendTransformConfigurationFromHex import love.forte.plugin.suspendtrans.cli.toAbstractCliOption -import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConstructorApi +import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConfigurationApi import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration import love.forte.plugin.suspendtrans.configuration.plus import org.jetbrains.kotlin.compiler.plugin.AbstractCliOption @@ -25,7 +25,7 @@ class SuspendTransformCommandLineProcessor : CommandLineProcessor { override val pluginOptions: Collection = listOf(SuspendTransformCliOptions.CLI_CONFIGURATION.toAbstractCliOption()) - @OptIn(InternalSuspendTransformConstructorApi::class) + @OptIn(InternalSuspendTransformConfigurationApi::class) override fun processOption( option: AbstractCliOption, value: String, diff --git a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt index 862fd86..54c6d57 100644 --- a/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt +++ b/compiler/suspend-transform-plugin/src/main/kotlin/love/forte/plugin/suspendtrans/SuspendTransformComponentRegistrar.kt @@ -1,6 +1,6 @@ package love.forte.plugin.suspendtrans -import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConstructorApi +import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConfigurationApi import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration import love.forte.plugin.suspendtrans.fir.SuspendTransformFirExtensionRegistrar import love.forte.plugin.suspendtrans.ir.SuspendTransformIrGenerationExtension @@ -60,11 +60,11 @@ class SuspendTransformComponentRegistrar : CompilerPluginRegistrar() { // // } // } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) private fun CompilerConfiguration.resolveToSuspendTransformConfiguration(): SuspendTransformConfiguration { return get( SuspendTransformCommandLineProcessor.CONFIGURATION_KEY, - SuspendTransformConfiguration(true, mutableMapOf()) + SuspendTransformConfiguration(mutableMapOf()) ) // return SuspendTransformConfiguration().apply { // enabled = compilerConfiguration.get(SuspendTransformCommandLineProcessor.ENABLED, true) diff --git a/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt b/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt index 2273dfe..c2bdc0a 100644 --- a/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt +++ b/compiler/suspend-transform-plugin/src/test/love/forte/plugin/suspendtrans/services/SuspendTransformerEnvironmentConfigurator.kt @@ -1,7 +1,7 @@ package love.forte.plugin.suspendtrans.services import love.forte.plugin.suspendtrans.SuspendTransformComponentRegistrar -import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConstructorApi +import love.forte.plugin.suspendtrans.configuration.InternalSuspendTransformConfigurationApi import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jsPromiseTransformer import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmAsyncTransformer import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingTransformer @@ -23,13 +23,12 @@ import java.io.File */ class SuspendTransformerEnvironmentConfigurator(testServices: TestServices) : EnvironmentConfigurator(testServices) { - @OptIn(ExperimentalCompilerApi::class, InternalSuspendTransformConstructorApi::class) + @OptIn(ExperimentalCompilerApi::class, InternalSuspendTransformConfigurationApi::class) override fun CompilerPluginRegistrar.ExtensionStorage.registerCompilerExtensions( module: TestModule, configuration: CompilerConfiguration ) { val testConfiguration = love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguration( - enabled = true, transformers = mapOf( TargetPlatform.JS to listOf(jsPromiseTransformer), TargetPlatform.JVM to listOf(jvmBlockingTransformer, jvmAsyncTransformer) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index cc6d4ca..96b854a 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -80,7 +80,7 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { project.logger.debug("Apply suspend transform plugin to compilation {}, target: {}", kotlinCompilation, target) val extension = resolveExtension(project) - return project.provider { extension.toSubpluginOptions(target, project) } + return extension.toSubpluginOptionsProvider(target, project) } private fun resolveExtension(project: Project): SuspendTransformPluginExtension { @@ -196,7 +196,7 @@ private fun DeprecatedTargetPlatform.toTarget(): TargetPlatform { } } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") private fun DeprecatedTransformer.toTransformer(): Transformer { return Transformer( @@ -212,7 +212,7 @@ private fun DeprecatedTransformer.toTransformer(): Transformer { ) } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") private fun DeprecatedMarkAnnotation.toMarkAnnotation(): MarkAnnotation { return MarkAnnotation( @@ -225,7 +225,7 @@ private fun DeprecatedMarkAnnotation.toMarkAnnotation(): MarkAnnotation { ) } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") private fun DeprecatedFunctionInfo.toFunctionInfo(): FunctionInfo { return FunctionInfo( @@ -234,7 +234,7 @@ private fun DeprecatedFunctionInfo.toFunctionInfo(): FunctionInfo { ) } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") private fun DeprecatedClassInfo.toClassInfo(): ClassInfo { return ClassInfo( @@ -245,7 +245,7 @@ private fun DeprecatedClassInfo.toClassInfo(): ClassInfo { ) } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) @Suppress("TYPEALIAS_EXPANSION_DEPRECATION") private fun DeprecatedIncludeAnnotation.toIncludeAnnotation(): IncludeAnnotation { return IncludeAnnotation( @@ -262,7 +262,7 @@ private fun SuspendTransformPluginExtension.toSubpluginOptions( // If not enabled or transformer is empty. val cliConfig = SuspendTransformCliOptions.CLI_CONFIGURATION val configuration = toConfiguration() - return if (configuration.enabled && configuration.transformers.isNotEmpty()) { + return if (configuration.transformers.isNotEmpty()) { if (project.logger.isInfoEnabled) { val count = configuration.transformers.values.sumOf { it.size } project.logger.debug("The suspend transform is enabled with {} transformer(s) for {}", count, target) @@ -274,6 +274,30 @@ private fun SuspendTransformPluginExtension.toSubpluginOptions( } } +private fun SuspendTransformPluginExtension.toSubpluginOptionsProvider( + target: KotlinTarget, + project: Project +): Provider> { + return enabled + .map { isEnabled -> + if (!isEnabled) { + project.logger.debug("The suspend transform is disabled for {}.", target) + return@map emptyList() + } + + val configuration = toConfiguration() + val transformers = configuration.transformers + if (transformers.isEmpty()) { + project.logger.debug("The suspend transform is enabled but transformers are empty for {}.", target) + return@map emptyList() + } + + val cliConfig = SuspendTransformCliOptions.CLI_CONFIGURATION + listOf(SubpluginOption(cliConfig.optionName, configuration.encodeToHex())) + } + +} + private fun Project.configureDependencies() { fun Project.include(platform: Platform, conf: SuspendTransformPluginExtension) { if (!conf.enabled.get()) { diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index 6e2a102..559fa9c 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -285,10 +285,11 @@ abstract class SuspendTransformPluginExtension } } -@OptIn(InternalSuspendTransformConstructorApi::class, ExperimentalTransformersContainerApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class, ExperimentalTransformersContainerApi::class) internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransformConfiguration { return SuspendTransformConfiguration( - enabled = enabled.getOrElse(true), + // 此处 Map 可能为 空,但是 List 不会有空的。 + // 后续在使用的时候只需要判断一下 transformers 本身是不是空即可。 transformers = buildMap { transformers._containers.forEach { targetPlatform, transformerListProperty -> val list = transformerListProperty @@ -740,7 +741,7 @@ abstract class IncludeAnnotationSpec } } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) internal fun TransformerSpec.toTransformer(): Transformer { return Transformer( markAnnotation = markAnnotation.get().toMarkAnnotation(), @@ -756,7 +757,7 @@ internal fun TransformerSpec.toTransformer(): Transformer { ) } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) internal fun MarkAnnotationSpec.toMarkAnnotation(): MarkAnnotation { return MarkAnnotation( classInfo = classInfo.get().toClassInfo(), @@ -768,7 +769,7 @@ internal fun MarkAnnotationSpec.toMarkAnnotation(): MarkAnnotation { ) } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) internal fun ClassInfoSpec.toClassInfo(): ClassInfo { return ClassInfo( packageName = packageName.get(), @@ -778,7 +779,7 @@ internal fun ClassInfoSpec.toClassInfo(): ClassInfo { ) } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) internal fun FunctionInfoSpec.toFunctionInfo(): FunctionInfo { return FunctionInfo( packageName = packageName.get(), @@ -786,7 +787,7 @@ internal fun FunctionInfoSpec.toFunctionInfo(): FunctionInfo { ) } -@OptIn(InternalSuspendTransformConstructorApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) internal fun IncludeAnnotationSpec.toIncludeAnnotation(): IncludeAnnotation { return IncludeAnnotation( classInfo = classInfo.get().toClassInfo(), From 207a3aa14615378fdf42468b06382b57a29775a9 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Sat, 19 Apr 2025 16:48:19 +0800 Subject: [PATCH 18/21] Improve the Gradle plugin's API and configuration's API. --- .../gradle/SuspendTransformGradlePlugin.kt | 43 +++++------------ .../gradle/SuspendTransformPluginExtension.kt | 47 ++++++++++++++++--- settings.gradle.kts | 6 +-- tests/test-jvm/build.gradle.kts | 24 +++++----- tests/test-kmp/build.gradle.kts | 7 +-- 5 files changed, 70 insertions(+), 57 deletions(-) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt index 96b854a..d0efe29 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformGradlePlugin.kt @@ -94,7 +94,6 @@ open class SuspendTransformGradlePlugin : KotlinCompilerPluginSupportPlugin { project.providers.gradleProperty("love.forte.plugin.suspend-transform.suppressDeprecatedExtensionWarn") .orNull.toBoolean() - val msg = "WARN: The `love.forte.plugin.suspendtrans.gradle.SuspendTransformGradleExtension` " + "(`suspendTransform { ... }`) is deprecated, \n" + "please use `love.forte.plugin.suspendtrans.gradle.SuspendTransformPluginExtension` " + @@ -255,45 +254,29 @@ private fun DeprecatedIncludeAnnotation.toIncludeAnnotation(): IncludeAnnotation ) } -private fun SuspendTransformPluginExtension.toSubpluginOptions( - target: KotlinTarget, - project: Project -): List { - // If not enabled or transformer is empty. - val cliConfig = SuspendTransformCliOptions.CLI_CONFIGURATION - val configuration = toConfiguration() - return if (configuration.transformers.isNotEmpty()) { - if (project.logger.isInfoEnabled) { - val count = configuration.transformers.values.sumOf { it.size } - project.logger.debug("The suspend transform is enabled with {} transformer(s) for {}", count, target) - } - listOf(SubpluginOption(cliConfig.optionName, configuration.encodeToHex())) - } else { - project.logger.debug("The suspend transform is disabled or transformers are empty for {}.", target) - emptyList() - } -} - private fun SuspendTransformPluginExtension.toSubpluginOptionsProvider( target: KotlinTarget, project: Project ): Provider> { return enabled - .map { isEnabled -> + .flatMap { isEnabled -> if (!isEnabled) { project.logger.debug("The suspend transform is disabled for {}.", target) - return@map emptyList() + return@flatMap project.provider { emptyList() } } - val configuration = toConfiguration() - val transformers = configuration.transformers - if (transformers.isEmpty()) { - project.logger.debug("The suspend transform is enabled but transformers are empty for {}.", target) - return@map emptyList() - } + val configurationProvider = toConfigurationProvider(project.objects) - val cliConfig = SuspendTransformCliOptions.CLI_CONFIGURATION - listOf(SubpluginOption(cliConfig.optionName, configuration.encodeToHex())) + configurationProvider.map { configuration -> + val transformers = configuration.transformers + if (transformers.isEmpty()) { + project.logger.debug("The suspend transform is enabled but transformers are empty for {}.", target) + return@map emptyList() + } + + val cliConfig = SuspendTransformCliOptions.CLI_CONFIGURATION + listOf(SubpluginOption(cliConfig.optionName, configuration.encodeToHex())) + } } } diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index 559fa9c..3d2345f 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -35,12 +35,6 @@ internal interface NamedTransformerSpecListContainerInternal : NamedTransformerS override val platform: Property } -@RequiresOptIn( - "This API is an experimental public TransformersContainer's api. " + - "It may be changed in the future without notice." -) -annotation class ExperimentalTransformersContainerApi - /** * @since 0.12.0 */ @@ -285,7 +279,7 @@ abstract class SuspendTransformPluginExtension } } -@OptIn(InternalSuspendTransformConfigurationApi::class, ExperimentalTransformersContainerApi::class) +@OptIn(InternalSuspendTransformConfigurationApi::class) internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransformConfiguration { return SuspendTransformConfiguration( // 此处 Map 可能为 空,但是 List 不会有空的。 @@ -304,6 +298,45 @@ internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransform ) } +internal data class TransformerEntry( + val targetPlatform: TargetPlatform, + val transformers: List +) + +@OptIn(InternalSuspendTransformConfigurationApi::class) +internal fun SuspendTransformPluginExtension.toConfigurationProvider(objects: ObjectFactory): Provider { + val combines = objects.listProperty(TransformerEntry::class.java) + for ((targetPlatform, transformerListProperty) in transformers._containers) { + combines.addAll( + transformerListProperty.map { list -> + if (list.isEmpty()) { + // Type mismatch: inferred type is TransformerEntry? but TransformerEntry was expected + // if return null with `combines.add` + emptyList() + } else { + listOf( + TransformerEntry(targetPlatform, list.map { it.toTransformer() }) + ) + } + } + ) + } + + return combines.map { entries -> + val transformersMap: Map> = entries.associateBy( + keySelector = { it.targetPlatform }, + valueTransform = { it.transformers } + ) + + // 此处 `Map` 可能为 空,但是 `List` 不会有空的。 + // 后续在使用的时候只需要判断一下 transformers 本身是不是空即可。 + SuspendTransformConfiguration( + transformers = transformersMap + ) + } + +} + /** * @since 0.12.0 */ diff --git a/settings.gradle.kts b/settings.gradle.kts index 63e8f53..a789a7e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -35,7 +35,7 @@ include(":plugins:suspend-transform-plugin-gradle") // include(":local-helper") //Samples -// include(":tests:test-jvm") -// include(":tests:test-js") -// include(":tests:test-kmp") +include(":tests:test-jvm") +include(":tests:test-js") +include(":tests:test-kmp") // include(":tests:test-android") diff --git a/tests/test-jvm/build.gradle.kts b/tests/test-jvm/build.gradle.kts index 30d336b..743e100 100644 --- a/tests/test-jvm/build.gradle.kts +++ b/tests/test-jvm/build.gradle.kts @@ -32,22 +32,22 @@ dependencies { api(libs.kotlinx.coroutines.core) } -@Suppress("DEPRECATION") -suspendTransform { - enabled = true - includeAnnotation = false - includeRuntime = false - useDefault() -} - -// suspendTransformPlugin { +// @Suppress("DEPRECATION") +// suspendTransform { +// enabled = true // includeAnnotation = false // includeRuntime = false -// transformers { -// useDefault() -// } +// useDefault() // } +suspendTransformPlugin { + includeAnnotation = false + includeRuntime = false + transformers { + useDefault() + } +} + /* > val blockingBaseName: String = "", > val blockingSuffix: String = "Blocking", diff --git a/tests/test-kmp/build.gradle.kts b/tests/test-kmp/build.gradle.kts index d6f6097..b04e501 100644 --- a/tests/test-kmp/build.gradle.kts +++ b/tests/test-kmp/build.gradle.kts @@ -1,6 +1,3 @@ -import love.forte.plugin.suspendtrans.ClassInfo -import love.forte.plugin.suspendtrans.SuspendTransformConfiguration - plugins { kotlin("multiplatform") id("love.forte.plugin.suspend-transform") @@ -89,9 +86,9 @@ suspendTransform { includeAnnotation = false useJvmDefault() addJsTransformers( - SuspendTransformConfiguration.jsPromiseTransformer.copy( + love.forte.plugin.suspendtrans.SuspendTransformConfiguration.jsPromiseTransformer.copy( copyAnnotationExcludes = listOf( - ClassInfo("kotlin.js", "JsExport.Ignore") + love.forte.plugin.suspendtrans.ClassInfo("kotlin.js", "JsExport.Ignore") ) ) ) From ce6db38aec3899f0b833db6b5e28a91c42a84122 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Sat, 19 Apr 2025 17:20:31 +0800 Subject: [PATCH 19/21] Hidden the test modules and improve something --- .../gradle/SuspendTransformPluginExtension.kt | 100 +++++++----------- settings.gradle.kts | 8 +- 2 files changed, 45 insertions(+), 63 deletions(-) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index 3d2345f..b6698b8 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -1,3 +1,4 @@ + package love.forte.plugin.suspendtrans.gradle import love.forte.plugin.suspendtrans.configuration.* @@ -6,7 +7,6 @@ import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfiguratio import love.forte.plugin.suspendtrans.configuration.SuspendTransformConfigurations.jvmBlockingTransformer import org.gradle.api.Action import org.gradle.api.DomainObjectSet -import org.gradle.api.Named import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property @@ -26,51 +26,43 @@ annotation class SuspendTransformPluginExtensionSpecDslMarker @SuspendTransformPluginExtensionSpecDslMarker interface SuspendTransformPluginExtensionSpec -interface NamedTransformerSpecListContainer : Named { - val platform: Provider - val transformers: ListProperty +@SuspendTransformPluginExtensionSpecDslMarker +interface SuspendTransformPluginExtensionClassInfoSpec : SuspendTransformPluginExtensionSpec { + fun classInfo(action: Action) + fun classInfo(action: ClassInfoSpec.() -> Unit) } -internal interface NamedTransformerSpecListContainerInternal : NamedTransformerSpecListContainer { - override val platform: Property -} +// TODO +// interface SuspendTransformPluginExtensionSpecFactory { +// fun createClassInfo(): ClassInfoSpec +// fun createMarkAnnotation(): MarkAnnotationSpec +// fun createFunctionInfo(): FunctionInfoSpec +// fun createIncludeAnnotation(): IncludeAnnotationSpec +// fun createCopyAnnotationExclude(): CopyAnnotationExcludeSpec +// fun createRuntimeDependency(): RuntimeDependencySpec +// fun createAnnotationDependency(): AnnotationDependencySpec +// fun createTransformFunctionInfo(): TransformFunctionInfoSpec +// fun createTransformReturnType(): TransformReturnTypeSpec +// fun createTransformer(): TransformerSpec +// } +// +// interface SuspendTransformPluginExtensionSpecFactoryAware { +// val factory: SuspendTransformPluginExtensionSpecFactory +// } /** * @since 0.12.0 */ +@Suppress("unused") abstract class TransformersContainer @Inject constructor( private val objects: ObjectFactory ) : SuspendTransformPluginExtensionSpec { - internal val _containers: MutableMap> = + internal val containers: MutableMap> = mutableMapOf() - // private val _containers: NamedDomainObjectContainer = - // objects.domainObjectContainer(NamedTransformerSpecListContainerInternal::class.java) { name -> - // val targetPlatform = try { - // TargetPlatform.valueOf(name) - // } catch (e: IllegalArgumentException) { - // throw IllegalArgumentException( - // "The name '$name' is not a valid TargetPlatform name. " + - // "Valid names: ${TargetPlatform.entries.joinToString { it.name }}", - // e - // ) - // } - // - // objects.newInstance( - // NamedTransformerSpecListContainerInternal::class.java, - // name - // ).apply { - // platform.set(targetPlatform) - // } - // } - - // @ExperimentalTransformersContainerApi - // val containers: NamedDomainObjectContainer - // get() = _containers - private fun getTransformersInternal(platform: TargetPlatform): ListProperty { - return _containers.computeIfAbsent(platform) { objects.listProperty(TransformerSpec::class.java) } + return containers.computeIfAbsent(platform) { objects.listProperty(TransformerSpec::class.java) } } /** @@ -217,6 +209,7 @@ abstract class TransformersContainer /** * @since 0.12.0 */ +@Suppress("unused") abstract class SuspendTransformPluginExtension @Inject constructor(objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { /** @@ -279,25 +272,6 @@ abstract class SuspendTransformPluginExtension } } -@OptIn(InternalSuspendTransformConfigurationApi::class) -internal fun SuspendTransformPluginExtension.toConfiguration(): SuspendTransformConfiguration { - return SuspendTransformConfiguration( - // 此处 Map 可能为 空,但是 List 不会有空的。 - // 后续在使用的时候只需要判断一下 transformers 本身是不是空即可。 - transformers = buildMap { - transformers._containers.forEach { targetPlatform, transformerListProperty -> - val list = transformerListProperty - .map { valueList -> valueList.map { it.toTransformer() } } - .getOrElse(emptyList()) - - if (list.isNotEmpty()) { - put(targetPlatform, list) - } - } - }, - ) -} - internal data class TransformerEntry( val targetPlatform: TargetPlatform, val transformers: List @@ -306,7 +280,7 @@ internal data class TransformerEntry( @OptIn(InternalSuspendTransformConfigurationApi::class) internal fun SuspendTransformPluginExtension.toConfigurationProvider(objects: ObjectFactory): Provider { val combines = objects.listProperty(TransformerEntry::class.java) - for ((targetPlatform, transformerListProperty) in transformers._containers) { + for ((targetPlatform, transformerListProperty) in transformers.containers) { combines.addAll( transformerListProperty.map { list -> if (list.isEmpty()) { @@ -399,6 +373,7 @@ internal fun SuspendTransformPluginExtension.defaults( /** * @since 0.12.0 */ +@Suppress("unused") abstract class TransformerSpec @Inject constructor(private val objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { /** @@ -438,6 +413,7 @@ abstract class TransformerSpec * @Api4J fun fooXxx(): CompletableFuture = transform(block = { foo() }, scope = this) * } */ + @Suppress("KDocUnresolvedReference") abstract val transformFunctionInfo: Property fun transformFunctionInfo(action: Action) { @@ -634,18 +610,21 @@ abstract class TransformerSpec /** * @since 0.12.0 */ +@Suppress("unused") abstract class MarkAnnotationSpec -@Inject constructor(private val objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { +@Inject constructor(private val objects: ObjectFactory) : + SuspendTransformPluginExtensionSpec, + SuspendTransformPluginExtensionClassInfoSpec { /** * The mark annotation's class info. */ abstract val classInfo: Property - fun classInfo(action: Action) { + override fun classInfo(action: Action) { classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } - fun classInfo(action: ClassInfoSpec.() -> Unit) { + override fun classInfo(action: ClassInfoSpec.() -> Unit) { classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action)) } @@ -743,15 +722,18 @@ interface FunctionInfoSpec : SuspendTransformPluginExtensionSpec { /** * @since 0.12.0 */ +@Suppress("unused") abstract class IncludeAnnotationSpec -@Inject constructor(private val objects: ObjectFactory) : SuspendTransformPluginExtensionSpec { +@Inject constructor(private val objects: ObjectFactory) : + SuspendTransformPluginExtensionSpec, + SuspendTransformPluginExtensionClassInfoSpec { abstract val classInfo: Property - fun classInfo(action: Action) { + override fun classInfo(action: Action) { classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action::execute)) } - fun classInfo(action: ClassInfoSpec.() -> Unit) { + override fun classInfo(action: ClassInfoSpec.() -> Unit) { classInfo.set(classInfo.getOrElse(objects.newInstance()).also(action)) } diff --git a/settings.gradle.kts b/settings.gradle.kts index a789a7e..0e3c35b 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -11,8 +11,8 @@ pluginManagement { } } -@Suppress("UnstableApiUsage") dependencyResolutionManagement { + @Suppress("UnstableApiUsage") repositories { google() mavenCentral() @@ -35,7 +35,7 @@ include(":plugins:suspend-transform-plugin-gradle") // include(":local-helper") //Samples -include(":tests:test-jvm") -include(":tests:test-js") -include(":tests:test-kmp") +// include(":tests:test-jvm") +// include(":tests:test-js") +// include(":tests:test-kmp") // include(":tests:test-android") From a3877869a4c2d362cfafb30c36e198afe3af3070 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Sat, 19 Apr 2025 23:01:01 +0800 Subject: [PATCH 20/21] Fix encode test --- .../cli/ConfigurationSerializeTests.kt | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt b/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt index 3821bab..4264428 100644 --- a/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt +++ b/compiler/suspend-transform-plugin-cli/src/test/kotlin/love/forte/plugin/suspendtrans/cli/ConfigurationSerializeTests.kt @@ -17,7 +17,10 @@ class ConfigurationSerializeTests { @OptIn(InternalSuspendTransformConfigurationApi::class) @Test fun testDecode() { - assertEquals("0801", SuspendTransformConfiguration(emptyMap()).encodeToHex()) + assertEquals( + "", + SuspendTransformConfiguration(emptyMap()).encodeToHex() + ) val config = SuspendTransformConfiguration( transformers = mapOf( @@ -27,6 +30,51 @@ class ConfigurationSerializeTests { ) val hex = config.encodeToHex() + + assertEquals( + "0aa807080112bd030a680a3c0a296c6f76652e666f7274652e706c7567696e2e" + + "73757370656e647472616e732e616e6e6f746174696f6e120b4a766d426c6f63" + + "6b696e67180020001208626173654e616d651a06737566666978220a61735072" + + "6f70657274792a08426c6f636b696e67300012390a266c6f76652e666f727465" + + "2e706c7567696e2e73757370656e647472616e732e72756e74696d65120f2472" + + "756e496e426c6f636b696e672420002a240a1e0a0a6b6f746c696e2e6a766d12" + + "0c4a766d53796e7468657469631800200010001800323c0a360a296c6f76652e" + + "666f7274652e706c7567696e2e73757370656e647472616e732e616e6e6f7461" + + "74696f6e1205417069344a18002000100018013801421e0a0a6b6f746c696e2e" + + "6a766d120c4a766d53796e74686574696318002000423c0a296c6f76652e666f" + + "7274652e706c7567696e2e73757370656e647472616e732e616e6e6f74617469" + + "6f6e120b4a766d426c6f636b696e671800200042390a296c6f76652e666f7274" + + "652e706c7567696e2e73757370656e647472616e732e616e6e6f746174696f6e" + + "12084a766d4173796e631800200042130a066b6f746c696e12054f7074496e18" + + "002000480012e3030a620a390a296c6f76652e666f7274652e706c7567696e2e" + + "73757370656e647472616e732e616e6e6f746174696f6e12084a766d4173796e" + + "63180020001208626173654e616d651a06737566666978220a617350726f7065" + + "7274792a054173796e63300012360a266c6f76652e666f7274652e706c756769" + + "6e2e73757370656e647472616e732e72756e74696d65120c2472756e496e4173" + + "796e63241a2d0a146a6176612e7574696c2e636f6e63757272656e741211436f" + + "6d706c657461626c654675747572651800200020012a240a1e0a0a6b6f746c69" + + "6e2e6a766d120c4a766d53796e7468657469631800200010001800323c0a360a" + + "296c6f76652e666f7274652e706c7567696e2e73757370656e647472616e732e" + + "616e6e6f746174696f6e1205417069344a18002000100018013801421e0a0a6b" + + "6f746c696e2e6a766d120c4a766d53796e74686574696318002000423c0a296c" + + "6f76652e666f7274652e706c7567696e2e73757370656e647472616e732e616e" + + "6e6f746174696f6e120b4a766d426c6f636b696e671800200042390a296c6f76" + + "652e666f7274652e706c7567696e2e73757370656e647472616e732e616e6e6f" + + "746174696f6e12084a766d4173796e631800200042130a066b6f746c696e1205" + + "4f7074496e1800200048000ad202080212cd020a630a3a0a296c6f76652e666f" + + "7274652e706c7567696e2e73757370656e647472616e732e616e6e6f74617469" + + "6f6e12094a7350726f6d697365180020001208626173654e616d651a06737566" + + "666978220a617350726f70657274792a054173796e63300012360a266c6f7665" + + "2e666f7274652e706c7567696e2e73757370656e647472616e732e72756e7469" + + "6d65120c2472756e496e4173796e63241a180a096b6f746c696e2e6a73120750" + + "726f6d697365180020002001323d0a370a296c6f76652e666f7274652e706c75" + + "67696e2e73757370656e647472616e732e616e6e6f746174696f6e1206417069" + + "344a7318002000100018013801423a0a296c6f76652e666f7274652e706c7567" + + "696e2e73757370656e647472616e732e616e6e6f746174696f6e12094a735072" + + "6f6d6973651800200042130a066b6f746c696e12054f7074496e180020004800", + hex + ) + assertEquals( config, decodeSuspendTransformConfigurationFromHex(hex) From 3a61facd2470ecb6ec2581d22081044285ba2572 Mon Sep 17 00:00:00 2001 From: ForteScarlet Date: Sun, 20 Apr 2025 00:03:03 +0800 Subject: [PATCH 21/21] Add factory implementations for transformer and spec creation Introduce `SuspendTransformPluginExtensionSpecFactory` and its implementation to modularize the creation of various specs. Refactor related methods to leverage the factory for cleaner and more consistent object instantiation. --- .../gradle/SuspendTransformPluginExtension.kt | 164 ++++++++++++++---- 1 file changed, 135 insertions(+), 29 deletions(-) diff --git a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt index b6698b8..1e4ab91 100644 --- a/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt +++ b/plugins/suspend-transform-plugin-gradle/src/main/kotlin/love/forte/plugin/suspendtrans/gradle/SuspendTransformPluginExtension.kt @@ -1,4 +1,3 @@ - package love.forte.plugin.suspendtrans.gradle import love.forte.plugin.suspendtrans.configuration.* @@ -12,6 +11,7 @@ import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory +import java.util.* import javax.inject.Inject /** @@ -26,29 +26,119 @@ annotation class SuspendTransformPluginExtensionSpecDslMarker @SuspendTransformPluginExtensionSpecDslMarker interface SuspendTransformPluginExtensionSpec +/** + * @since 0.12.0 + */ @SuspendTransformPluginExtensionSpecDslMarker interface SuspendTransformPluginExtensionClassInfoSpec : SuspendTransformPluginExtensionSpec { fun classInfo(action: Action) fun classInfo(action: ClassInfoSpec.() -> Unit) } -// TODO -// interface SuspendTransformPluginExtensionSpecFactory { -// fun createClassInfo(): ClassInfoSpec -// fun createMarkAnnotation(): MarkAnnotationSpec -// fun createFunctionInfo(): FunctionInfoSpec -// fun createIncludeAnnotation(): IncludeAnnotationSpec -// fun createCopyAnnotationExclude(): CopyAnnotationExcludeSpec -// fun createRuntimeDependency(): RuntimeDependencySpec -// fun createAnnotationDependency(): AnnotationDependencySpec -// fun createTransformFunctionInfo(): TransformFunctionInfoSpec -// fun createTransformReturnType(): TransformReturnTypeSpec -// fun createTransformer(): TransformerSpec -// } -// -// interface SuspendTransformPluginExtensionSpecFactoryAware { -// val factory: SuspendTransformPluginExtensionSpecFactory -// } +/** + * @since 0.12.0 + */ +@Suppress("unused") +interface SuspendTransformPluginExtensionSpecFactory { + fun createClassInfo(action: Action): ClassInfoSpec + fun createClassInfo(action: ClassInfoSpec.() -> Unit): ClassInfoSpec = + createClassInfo(Action(action)) + + fun createClassInfo(): ClassInfoSpec = + createClassInfo { } + + fun createMarkAnnotation(action: Action): MarkAnnotationSpec + fun createMarkAnnotation(action: MarkAnnotationSpec.() -> Unit): MarkAnnotationSpec = + createMarkAnnotation(Action(action)) + + fun createMarkAnnotation(): MarkAnnotationSpec = + createMarkAnnotation { } + + fun createFunctionInfo(action: Action): FunctionInfoSpec + fun createFunctionInfo(action: FunctionInfoSpec.() -> Unit): FunctionInfoSpec = + createFunctionInfo(Action(action)) + + fun createFunctionInfo(): FunctionInfoSpec = + createFunctionInfo { } + + fun createIncludeAnnotation(action: Action): IncludeAnnotationSpec + fun createIncludeAnnotation(action: IncludeAnnotationSpec.() -> Unit): IncludeAnnotationSpec = + createIncludeAnnotation(Action(action)) + + fun createIncludeAnnotation(): IncludeAnnotationSpec = + createIncludeAnnotation { } + + fun createRuntimeDependency(action: Action): RuntimeDependencySpec + fun createRuntimeDependency(action: RuntimeDependencySpec.() -> Unit): RuntimeDependencySpec = + createRuntimeDependency(Action(action)) + + fun createRuntimeDependency(): RuntimeDependencySpec = + createRuntimeDependency { } + + fun createAnnotationDependency(action: Action): AnnotationDependencySpec + fun createAnnotationDependency(action: AnnotationDependencySpec.() -> Unit): AnnotationDependencySpec = + createAnnotationDependency(Action(action)) + + fun createAnnotationDependency(): AnnotationDependencySpec = + createAnnotationDependency { } + + fun createTransformFunctionInfo(action: Action): FunctionInfoSpec + fun createTransformFunctionInfo(action: FunctionInfoSpec.() -> Unit): FunctionInfoSpec = + createTransformFunctionInfo(Action(action)) + + fun createTransformFunctionInfo(): FunctionInfoSpec = + createTransformFunctionInfo { } + + fun createTransformer(action: Action): TransformerSpec + fun createTransformer(action: TransformerSpec.() -> Unit): TransformerSpec = + createTransformer(Action(action)) + + fun createTransformer(): TransformerSpec = + createTransformer { } +} + +/** + * @since 0.12.0 + */ +interface SuspendTransformPluginExtensionSpecFactoryAware { + val factory: SuspendTransformPluginExtensionSpecFactory +} + +private class SuspendTransformPluginExtensionSpecFactoryImpl( + private val objects: ObjectFactory, +) : SuspendTransformPluginExtensionSpecFactory { + override fun createClassInfo(action: Action): ClassInfoSpec { + return objects.newInstance().also(action::execute) + } + + override fun createAnnotationDependency(action: Action): AnnotationDependencySpec { + return objects.newInstance().also(action::execute) + } + + override fun createMarkAnnotation(action: Action): MarkAnnotationSpec { + return objects.newInstance().also(action::execute) + } + + override fun createFunctionInfo(action: Action): FunctionInfoSpec { + return objects.newInstance().also(action::execute) + } + + override fun createIncludeAnnotation(action: Action): IncludeAnnotationSpec { + return objects.newInstance().also(action::execute) + } + + override fun createRuntimeDependency(action: Action): RuntimeDependencySpec { + return objects.newInstance().also(action::execute) + } + + override fun createTransformFunctionInfo(action: Action): FunctionInfoSpec { + return objects.newInstance().also(action::execute) + } + + override fun createTransformer(action: Action): TransformerSpec { + return objects.newInstance().also(action::execute) + } +} /** * @since 0.12.0 @@ -57,11 +147,27 @@ interface SuspendTransformPluginExtensionClassInfoSpec : SuspendTransformPluginE abstract class TransformersContainer @Inject constructor( private val objects: ObjectFactory -) : SuspendTransformPluginExtensionSpec { +) : SuspendTransformPluginExtensionSpec, + SuspendTransformPluginExtensionSpecFactoryAware { + override val factory: SuspendTransformPluginExtensionSpecFactory = + SuspendTransformPluginExtensionSpecFactoryImpl(objects) + + // mutableMapOf() internal val containers: MutableMap> = - mutableMapOf() + EnumMap(TargetPlatform::class.java) + // TODO Maybe ... + // containers: NamedDomainObjectContainer = + // objects.domainObjectContainer(TransformerSpecContainer::class.java) { name -> + // objects.newInstance(TransformerSpecContainer::class.java, name) + // } + // abstract class TransformerSpecContainer @Inject constructor(name: String) { + // val targetPlatform: TargetPlatform = TargetPlatform.valueOf(name) + // abstract val transformerSet: DomainObjectSet + // } + private fun getTransformersInternal(platform: TargetPlatform): ListProperty { + // return containers.maybeCreate(platform.name).transformerSet return containers.computeIfAbsent(platform) { objects.listProperty(TransformerSpec::class.java) } } @@ -76,27 +182,27 @@ abstract class TransformersContainer * Create a [TransformerSpec] but not add. */ fun createTransformer(action: TransformerSpec.() -> Unit): TransformerSpec { - return objects.newInstance().also(action) + return factory.createTransformer(action) } fun add(platform: TargetPlatform, action: Action) { - val listProperty = getTransformersInternal(platform) - listProperty.add(createTransformer(action)) + val transformerSpecs = getTransformersInternal(platform) + transformerSpecs.add(createTransformer(action)) } fun add(platform: TargetPlatform, action: TransformerSpec.() -> Unit) { - val listProperty = getTransformersInternal(platform) - listProperty.add(createTransformer(action)) + val transformerSpecs = getTransformersInternal(platform) + transformerSpecs.add(createTransformer(action)) } fun add(platform: TargetPlatform, transformer: TransformerSpec) { - val listProperty = getTransformersInternal(platform) - listProperty.add(transformer) + val transformerSpecs = getTransformersInternal(platform) + transformerSpecs.add(transformer) } fun add(platform: TargetPlatform, transformer: Provider) { - val listProperty = getTransformersInternal(platform) - listProperty.add(transformer) + val transformerSpecs = getTransformersInternal(platform) + transformerSpecs.add(transformer) } fun add(platform: TargetPlatform, transformer: Transformer) {