Build improvements: Kotlin 1.9.20-RC, default target hierarchy, bump Okio (#2473)

* Build improvements: Kotlin 1.9.20-RC, default target hierarchy, bump Okio

Updated to Kotlin 1.9.20-RC:
- Kotlin 1.9.0/10 had some blockers in XCode 15 support.
- Simplify WASM setup (it has been changed in 1.9.20).
- Drop obsolete Native targets

Apply default target hierarchy:
- Greatly simplified buildscript for native targets.
- Supported targets are now runnable from gutter in the IDE.
- Now all possible targets are built by default (without -Pnative.deploy flag), resulting in less confusion for contributors and CI (but longer local `check` times).
- Publishing library with K2 should be possible now, no more incorrect `publishNativeKotlinMetadata` failing task.
- More targets available in integration-test project.

Updated Okio for:
- linuxArm64 target support
diff --git a/formats/json-okio/build.gradle.kts b/formats/json-okio/build.gradle.kts
index 43859e4..a51fff0 100644
--- a/formats/json-okio/build.gradle.kts
+++ b/formats/json-okio/build.gradle.kts
@@ -52,16 +52,11 @@
 }
 
 
-// Right now it is used for conditional support of kotlin 1.9.0 and 1.9.20+
 // TODO: Remove this after okio will be updated to the version with 1.9.20 stdlib dependency
-val kotlin_version: String by project
-val isNewWasmTargetEnabled = isKotlinVersionAtLeast(kotlin_version, 1, 9, 20)
-if (isNewWasmTargetEnabled) {
-    configurations.all {
-        resolutionStrategy.eachDependency {
-            if (requested.name == "kotlin-stdlib-wasm") {
-                useTarget("org.jetbrains.kotlin:kotlin-stdlib-wasm-js:${requested.version}")
-            }
+configurations.all {
+    resolutionStrategy.eachDependency {
+        if (requested.name == "kotlin-stdlib-wasm") {
+            useTarget("org.jetbrains.kotlin:kotlin-stdlib-wasm-js:${requested.version}")
         }
     }
 }
diff --git a/formats/json-tests/build.gradle.kts b/formats/json-tests/build.gradle.kts
index 3c84e29..6be0a3a 100644
--- a/formats/json-tests/build.gradle.kts
+++ b/formats/json-tests/build.gradle.kts
@@ -50,24 +50,11 @@
 
 project.configureJava9ModuleInfo()
 
-// Right now it is used for conditional support of kotlin 1.9.0 and 1.9.20+
 // TODO: Remove this after okio will be updated to the version with 1.9.20 stdlib dependency
-val kotlin_version: String by project
-val isNewWasmTargetEnabled = isKotlinVersionAtLeast(kotlin_version, 1, 9, 20)
-if (isNewWasmTargetEnabled) {
-    configurations.all {
-        resolutionStrategy.eachDependency {
-            if (requested.name == "kotlin-stdlib-wasm") {
-                useTarget("org.jetbrains.kotlin:kotlin-stdlib-wasm-js:${requested.version}")
-            }
+configurations.all {
+    resolutionStrategy.eachDependency {
+        if (requested.name == "kotlin-stdlib-wasm") {
+            useTarget("org.jetbrains.kotlin:kotlin-stdlib-wasm-js:${requested.version}")
         }
     }
 }
-
-// TODO: Remove this after default kotlin will be updated to 1.9.20
-// https://youtrack.jetbrains.com/issue/KT-60212
-if (!isNewWasmTargetEnabled) {
-    tasks.named("wasmD8Test", KotlinJsTest::class) {
-        filter.excludePatterns += "kotlinx.serialization.features.EmojiTest"
-    }
-}
diff --git a/formats/json/build.gradle b/formats/json/build.gradle
index 105c8de..a71366f 100644
--- a/formats/json/build.gradle
+++ b/formats/json/build.gradle
@@ -20,9 +20,6 @@
     enabled = false
 }
 
-// Right now it is used for conditional support of kotlin 1.9.0 and 1.9.20+
-def isNewWasmTargetEnabled = isKotlinVersionAtLeast(rootProject.properties["kotlin_version"], 1, 9, 20)
-
 kotlin {
     sourceSets {
         configureEach {
@@ -42,14 +39,8 @@
         jsMain {
             dependsOn(sourceSets.jsWasmMain)
         }
-        if (isNewWasmTargetEnabled) {
-            wasmJsMain {
-                dependsOn(sourceSets.jsWasmMain)
-            }
-        } else {
-            wasmMain {
-                dependsOn(sourceSets.jsWasmMain)
-            }
+        wasmJsMain {
+            dependsOn(sourceSets.jsWasmMain)
         }
     }
 }
diff --git a/gradle.properties b/gradle.properties
index dd42f7b..bab6b61 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,7 +5,7 @@
 group=org.jetbrains.kotlinx
 version=1.6.1-SNAPSHOT
 
-kotlin.version=1.9.0
+kotlin.version=1.9.20-RC
 
 # This version takes precedence if 'bootstrap' property passed to project
 kotlin.version.snapshot=1.9.255-SNAPSHOT
@@ -20,7 +20,7 @@
 # Only for tests
 coroutines_version=1.6.4
 kover_version=0.4.2
-okio_version=3.5.0
+okio_version=3.6.0
 
 kover.enabled=true
 
diff --git a/gradle/configure-source-sets.gradle b/gradle/configure-source-sets.gradle
index e43a9bb..532e2ca 100644
--- a/gradle/configure-source-sets.gradle
+++ b/gradle/configure-source-sets.gradle
@@ -14,9 +14,6 @@
     options.release = 8
 }
 
-// Right now it is used for conditional support of kotlin 1.9.0 and 1.9.20+
-def isNewWasmTargetEnabled = isKotlinVersionAtLeast(rootProject.properties["kotlin_version"], 1, 9, 20)
-
 kotlin {
     jvm {
         withJava()
@@ -45,14 +42,8 @@
         }
     }
 
-    if (isNewWasmTargetEnabled) {
-        wasmJs {
-            d8()
-        }
-    } else {
-        wasm {
-            d8()
-        }
+    wasmJs {
+        d8()
     }
 
     sourceSets.all {
@@ -105,35 +96,22 @@
             }
         }
 
-        if(isNewWasmTargetEnabled) {
-            wasmJsMain {
-                kotlin {
-                    srcDir 'wasmMain/src'
-                }
-                dependencies {
-                    api 'org.jetbrains.kotlin:kotlin-stdlib-wasm-js'
-                }
-            }
 
-            wasmJsTest {
-                kotlin {
-                    srcDir 'wasmTest/src'
-                }
-                dependencies {
-                    api 'org.jetbrains.kotlin:kotlin-test-wasm-js'
-                }
+        wasmJsMain {
+            kotlin {
+                srcDir 'wasmMain/src'
             }
-        } else {
-            wasmMain {
-                dependencies {
-                    api 'org.jetbrains.kotlin:kotlin-stdlib-wasm'
-                }
+            dependencies {
+                api 'org.jetbrains.kotlin:kotlin-stdlib-wasm-js'
             }
+        }
 
-            wasmTest {
-                dependencies {
-                    api 'org.jetbrains.kotlin:kotlin-test-wasm'
-                }
+        wasmJsTest {
+            kotlin {
+                srcDir 'wasmTest/src'
+            }
+            dependencies {
+                api 'org.jetbrains.kotlin:kotlin-test-wasm-js'
             }
         }
 
@@ -169,8 +147,7 @@
         }
     }
 
-    // TODO: Remove deprecated linuxArm32Hfp and mingwX86 targets in 1.9.20.
-    def targetsWithoutTestRunners = ["linuxArm32Hfp", "linuxArm64", "mingwX86"]
+    def targetsWithoutTestRunners = ["linuxArm64"]
     configure(targets) {
         // Configure additional binaries to run tests in the background
         if (["macos", "linux", "mingw"].any { name.startsWith(it) && !targetsWithoutTestRunners.contains(name) }) {
@@ -184,4 +161,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/gradle/native-targets.gradle b/gradle/native-targets.gradle
index 880b4b6..5b7f8a4 100644
--- a/gradle/native-targets.gradle
+++ b/gradle/native-targets.gradle
@@ -2,178 +2,41 @@
  * Copyright 2017-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
  */
 
-/**
- * Specifies what subset of Native targets to build
- *
- * ALL — all possible for compilation
- * HOST — host-specific ones, without cross compilation (e.g. do not build linuxX64 on macOS host)
- * SINGLE — only for current OS (to import into IDEA / quickly run tests)
- * DISABLED — disable all Native targets (useful with Kotlin compiler built from sources)
- *
- * For HOST mode, all targets are still listed in .module file, so HOST mode is useful for release process.
- */
-enum NativeState {
-    ALL, HOST, SINGLE, DISABLED
-}
-
-def getNativeState(String description) {
-    if (description == null) return NativeState.SINGLE
-    switch (description.toLowerCase()) {
-        case 'all':
-        case 'true':
-            return NativeState.ALL
-        case 'host':
-            return NativeState.HOST
-        case 'disabled':
-            return NativeState.DISABLED
-            // 'single', 'false', etc
-        default:
-            return NativeState.SINGLE
-    }
-}
-
-project.ext.ideaActive = System.getProperty('idea.active') == 'true'
-project.ext.nativeState = getNativeState(property('native.deploy'))
-project.ext.singleTargetMode = project.ext.ideaActive || (project.ext.nativeState == NativeState.SINGLE)
-
-project.ext.nativeMainSets = []
-project.ext.nativeTestSets = []
-
-/**
- * Disables compilation but leaves the target in .module file
- */
-def disableCompilation(targets) {
-    configure(targets) {
-        compilations.all {
-            cinterops.all { project.tasks[interopProcessingTaskName].enabled = false }
-            compileKotlinTask.enabled = false
-        }
-        binaries.all { linkTask.enabled = false }
-
-        mavenPublication { publicationToDisable ->
-            tasks.withType(AbstractPublishToMaven).all {
-                onlyIf { publication != publicationToDisable }
-            }
-            tasks.withType(GenerateModuleMetadata).all {
-                onlyIf { publication.get() != publicationToDisable }
-            }
-        }
-    }
-}
-
-def getHostName() {
-    def target = System.getProperty("os.name")
-    if (target == 'Linux') return 'linux'
-    if (target.startsWith('Windows')) return 'windows'
-    if (target.startsWith('Mac')) return 'macos'
-    return 'unknown'
-}
-
 static def doesNotDependOnOkio(project) {
     return !project.name.contains("json-okio") && !project.name.contains("json-tests")
 }
 
 kotlin {
-    targets {
-        def manager = project.ext.hostManager
-        def linuxEnabled = manager.isEnabled(presets.linuxX64.konanTarget)
-        def macosEnabled = manager.isEnabled(presets.macosX64.konanTarget)
-        def winEnabled = manager.isEnabled(presets.mingwX64.konanTarget)
+    applyDefaultHierarchyTemplate {
 
-        def ideaPreset = presets.linuxX64
-        if (macosEnabled) ideaPreset = presets.macosX64
-        if (winEnabled) ideaPreset = presets.mingwX64
-        project.ext.ideaPreset = ideaPreset
-    }
+        // According to https://kotlinlang.org/docs/native-target-support.html
+        // Tier 1
+        linuxX64()
+        macosX64()
+        macosArm64()
+        iosSimulatorArm64()
+        iosX64()
 
-    targets {
-        delegate.metaClass.addTarget = { preset ->
-            def target = delegate.fromPreset(preset, preset.name)
-            project.ext.nativeMainSets.add(target.compilations['main'].kotlinSourceSets.first())
-            project.ext.nativeTestSets.add(target.compilations['test'].kotlinSourceSets.first())
-        }
-    }
+        // Tier 2
+        watchosSimulatorArm64()
+        watchosX64()
+        watchosArm32()
+        watchosArm64()
+        tvosSimulatorArm64()
+        tvosX64()
+        tvosArm64()
+        iosArm64()
+        linuxArm64()
 
-    targets {
-        if (project.ext.nativeState == NativeState.DISABLED) return
-
-        String[] versionComponents = (~/[.-]/).split(compilerVersion, 4)
-        String[] versionComponents1920 = ["1", "9", "20"]
-        def isAtLeast1920 = Arrays.compare(versionComponents, versionComponents1920) { lhs, rhs ->
-            (lhs as int) <=> (rhs as int)
-        } >= 0
-
-        if (project.ext.singleTargetMode) {
-            fromPreset(project.ext.ideaPreset, 'native')
-        } else {
-            // According to https://kotlinlang.org/docs/native-target-support.html
-            // Tier 1
-            addTarget(presets.linuxX64)
-            addTarget(presets.macosX64)
-            addTarget(presets.macosArm64)
-            addTarget(presets.iosSimulatorArm64)
-            addTarget(presets.iosX64)
-
-            // Tier 2
-            if (doesNotDependOnOkio(project)) {
-                addTarget(presets.linuxArm64)
-            }
-            addTarget(presets.watchosSimulatorArm64)
-            addTarget(presets.watchosX64)
-            addTarget(presets.watchosArm32)
-            addTarget(presets.watchosArm64)
-            addTarget(presets.tvosSimulatorArm64)
-            addTarget(presets.tvosX64)
-            addTarget(presets.tvosArm64)
-            addTarget(presets.iosArm64)
-
-            // Tier 3
-            if (doesNotDependOnOkio(project)) {
-                addTarget(presets.androidNativeArm32)
-                addTarget(presets.androidNativeArm64)
-                addTarget(presets.androidNativeX86)
-                addTarget(presets.androidNativeX64)
-                addTarget(presets.watchosDeviceArm64)
-            }
-
-            addTarget(presets.mingwX64)
-
-            // Deprecated, but were provided by kotlinx.serialization; can be removed only in 1.9.20 release.
-            if (!isAtLeast1920) {
-                addTarget(presets.watchosX86)
-
-                if (doesNotDependOnOkio(project)) {
-                    addTarget(presets.iosArm32)
-                    addTarget(presets.linuxArm32Hfp)
-                    addTarget(presets.mingwX86)
-                }
-            }
-
-        }
-
-        if (project.ext.nativeState == NativeState.HOST) {
-            // linux targets that can cross-compile on all three hosts
-            def linuxCrossCompileTargets = isAtLeast1920 ? [presets.linuxX64] : [presets.linuxX64, presets.linuxArm32Hfp, presets.linuxArm64]
-            if (getHostName() != "linux") {
-                disableCompilation(linuxCrossCompileTargets)
-            }
-        }
-    }
-
-
-    sourceSets {
-        nativeMain { dependsOn commonMain }
-        // Empty source set is required in order to have native tests task
-        nativeTest { dependsOn commonTest }
-
-        if (!project.ext.singleTargetMode) {
-            configure(project.ext.nativeMainSets) {
-                dependsOn nativeMain
-            }
-
-            configure(project.ext.nativeTestSets) {
-                dependsOn nativeTest
-            }
+        // Tier 3
+        mingwX64()
+        // https://github.com/square/okio/issues/1242#issuecomment-1759357336
+        if (doesNotDependOnOkio(project)) {
+            androidNativeArm32()
+            androidNativeArm64()
+            androidNativeX86()
+            androidNativeX64()
+            watchosDeviceArm64()
         }
     }
 }
diff --git a/integration-test/build.gradle b/integration-test/build.gradle
index 99afce4..225181b 100644
--- a/integration-test/build.gradle
+++ b/integration-test/build.gradle
@@ -41,18 +41,17 @@
             }
         }
     }
-    wasm {
+    wasmJs {
         d8()
     }
     jvm {
         withJava()
     }
-    // For ARM, should be changed to iosArm32 or iosArm64
-    // For Linux, should be changed to e.g. linuxX64
-    // For MacOS, should be changed to e.g. macosX64
-    // For Windows, should be changed to e.g. mingwX64
-    macosX64("macos")
-    linuxX64("linux")
+    macosX64()
+    macosArm64()
+    linuxX64()
+    mingwX64()
+
     sourceSets {
         all {
             languageSettings {
@@ -98,27 +97,29 @@
                 implementation kotlin('test-js')
             }
         }
-        wasmMain {
+        wasmJsMain {
             dependencies {
-                implementation kotlin('stdlib-wasm')
+                api 'org.jetbrains.kotlin:kotlin-stdlib-wasm-js'
+            }
+        }
 
-            }
-        }
-        wasmTest {
+        wasmJsTest {
             dependencies {
-                implementation kotlin('test-wasm')
+                api 'org.jetbrains.kotlin:kotlin-test-wasm-js'
             }
         }
-        macosMain {
-            dependencies {
+    }
+
+    targets.all {
+        compilations.all {
+            kotlinOptions {
+                freeCompilerArgs += "-Xexpect-actual-classes"
             }
         }
-        macosTest {}
-        linuxMain {
-            kotlin.srcDirs = ["src/macosMain/kotlin"]
-        }
-        linuxTest {
-            kotlin.srcDirs = ["src/macosTest/kotlin"]
+        compilations.main {
+            kotlinOptions {
+                allWarningsAsErrors = true
+            }
         }
     }
 }
diff --git a/integration-test/gradle.properties b/integration-test/gradle.properties
index e0e8855..a0c9623 100644
--- a/integration-test/gradle.properties
+++ b/integration-test/gradle.properties
@@ -2,7 +2,7 @@
 # Copyright 2017-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 #
 
-mainKotlinVersion=1.9.0
+mainKotlinVersion=1.9.20-RC
 mainLibVersion=1.6.1-SNAPSHOT
 
 kotlin.code.style=official
diff --git a/integration-test/src/macosMain/kotlin/sample/SampleMacos.kt b/integration-test/src/nativeMain/kotlin/sample/SampleMacos.kt
similarity index 100%
rename from integration-test/src/macosMain/kotlin/sample/SampleMacos.kt
rename to integration-test/src/nativeMain/kotlin/sample/SampleMacos.kt
diff --git a/integration-test/src/macosTest/kotlin/sample/SampleTestsNative.kt b/integration-test/src/nativeTest/kotlin/sample/SampleTestsNative.kt
similarity index 99%
rename from integration-test/src/macosTest/kotlin/sample/SampleTestsNative.kt
rename to integration-test/src/nativeTest/kotlin/sample/SampleTestsNative.kt
index 5ea6727..f86bf96 100644
--- a/integration-test/src/macosTest/kotlin/sample/SampleTestsNative.kt
+++ b/integration-test/src/nativeTest/kotlin/sample/SampleTestsNative.kt
@@ -8,4 +8,4 @@
     fun testHello() {
         assertTrue("Native" in hello())
     }
-}
\ No newline at end of file
+}
diff --git a/integration-test/src/wasmMain/kotlin/sample/SampleWasm.kt b/integration-test/src/wasmJsMain/kotlin/sample/SampleWasm.kt
similarity index 100%
rename from integration-test/src/wasmMain/kotlin/sample/SampleWasm.kt
rename to integration-test/src/wasmJsMain/kotlin/sample/SampleWasm.kt
diff --git a/integration-test/src/wasmTest/kotlin/sample/SampleTestsWasm.kt b/integration-test/src/wasmJsTest/kotlin/sample/SampleTestsWasm.kt
similarity index 100%
rename from integration-test/src/wasmTest/kotlin/sample/SampleTestsWasm.kt
rename to integration-test/src/wasmJsTest/kotlin/sample/SampleTestsWasm.kt