Repository: JetBrains/compose-multiplatform
File: gradle-plugins/compose/src/main/kotlin/org/jetbrains/compose/experimental/internal/checkExperimentalTargets.kt (Kotlin)

Code before:

package org.jetbrains.compose.experimental.internal

import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget

internal fun Project.configureExperimentalTargetsFlagsCheck(mppExt: KotlinMultiplatformExtension) {
    gradle.taskGraph.whenReady {
        checkExperimentalTargetsWithSkikoIsEnabled(project, mppExt)
    }
}

private const val SKIKO_ARTIFACT_PREFIX = "org.jetbrains.skiko:skiko"

private class TargetType(
    val id: String,
    val presets: List<String>
)

private val TargetType.gradlePropertyName get() = "org.jetbrains.compose.experimental.$id.enabled"

private val EXPERIMENTAL_TARGETS: Set<TargetType> = setOf(
    TargetType("macos", presets = listOf("macosX64", "macosArm64")),
    TargetType("jscanvas", presets = listOf("jsIr", "js")),
    TargetType("wasm", presets = listOf("wasm", "wasmJs")),
)

private sealed interface CheckResult {
    object Success : CheckResult
    class Fail(val target: TargetType) : CheckResult
}

private fun checkExperimentalTargetsWithSkikoIsEnabled(
    project: Project,
    mppExt: KotlinMultiplatformExtension,
) {
    val failedResults = mppExt.targets.map { checkTarget(project, it) }
        .filterIsInstance<CheckResult.Fail>()
        .distinctBy { it.target }

    if (failedResults.isNotEmpty()) {
        val ids = failedResults.map { it.target.id }
        val msg = buildString {
            appendLine("ERROR: Compose targets '$ids' are experimental and may have bugs!")
            appendLine("But, if you still want to use them, add to gradle.properties:")
            failedResults.forEach {
                appendLine("${it.target.gradlePropertyName}=true")
            }
        }


Review comment (suggestion):
Note: I keep jscanvas above! 
We'll try to support k/js target of CM at least until Safari enables WasmGC. But still, it's better to keep it as an experimental target for now. 

Code after:

package org.jetbrains.compose.experimental.internal

import org.gradle.api.Project
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.plugin.KotlinTarget

internal fun Project.configureExperimentalTargetsFlagsCheck(mppExt: KotlinMultiplatformExtension) {
    gradle.taskGraph.whenReady {
        checkExperimentalTargetsWithSkikoIsEnabled(project, mppExt)
    }
}

private const val SKIKO_ARTIFACT_PREFIX = "org.jetbrains.skiko:skiko"

private class TargetType(
    val id: String,
    val presets: List<String>
)

private val TargetType.gradlePropertyName get() = "org.jetbrains.compose.experimental.$id.enabled"

private val EXPERIMENTAL_TARGETS: Set<TargetType> = setOf(
    TargetType("macos", presets = listOf("macosX64", "macosArm64")),
    TargetType("jscanvas", presets = listOf("jsIr", "js")),
)

private sealed interface CheckResult {
    object Success : CheckResult
    class Fail(val target: TargetType) : CheckResult
}

private fun checkExperimentalTargetsWithSkikoIsEnabled(
    project: Project,
    mppExt: KotlinMultiplatformExtension,
) {
    val failedResults = mppExt.targets.map { checkTarget(project, it) }
        .filterIsInstance<CheckResult.Fail>()
        .distinctBy { it.target }

    if (failedResults.isNotEmpty()) {
        val ids = failedResults.map { it.target.id }
        val msg = buildString {
            appendLine("ERROR: Compose targets '$ids' are experimental and may have bugs!")
            appendLine("But, if you still want to use them, add to gradle.properties:")
            failedResults.forEach {
                appendLine("${it.target.gradlePropertyName}=true")
            }
        }

        project.logger.error(msg)