Merge tag '1.6.4' into kotlinx.coroutines-upgrade

Bug: 239834928
Change-Id: I5b1f7fdac0270c86807b4838cefb1e69f5e0ddff
Merged-In: I5b1f7fdac0270c86807b4838cefb1e69f5e0ddff
Test: manual -- all existing tests and builds should pass
diff --git a/build.gradle b/build.gradle
index e4b12ff..4d6af16 100644
--- a/build.gradle
+++ b/build.gradle
@@ -2,21 +2,16 @@
  * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
  */
 
+
+import org.jetbrains.kotlin.config.KotlinCompilerVersion
 import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformType
+import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
 import org.jetbrains.kotlin.konan.target.HostManager
-import org.gradle.util.VersionNumber
 import org.jetbrains.dokka.gradle.DokkaTaskPartial
-import org.jetbrains.dokka.gradle.DokkaMultiModuleTask
+
+import static Projects.*
 
 apply plugin: 'jdk-convention'
-apply from: rootProject.file("gradle/opt-in.gradle")
-
-def coreModule = "kotlinx-coroutines-core"
-// Not applicable for Kotlin plugin
-def sourceless = ['kotlinx.coroutines', 'kotlinx-coroutines-bom', 'integration-testing']
-def internal = ['kotlinx.coroutines', 'benchmarks', 'integration-testing']
-// Not published
-def unpublished = internal + ['example-frontend-js', 'android-unit-tests']
 
 buildscript {
     /*
@@ -47,12 +42,6 @@
         }
     }
 
-    if (using_snapshot_version) {
-        repositories {
-            mavenLocal()
-        }
-    }
-
     repositories {
         mavenCentral()
         maven { url "https://plugins.gradle.org/m2/" }
@@ -65,11 +54,13 @@
         classpath "org.jetbrains.dokka:dokka-gradle-plugin:$dokka_version"
         classpath "org.jetbrains.kotlinx:atomicfu-gradle-plugin:$atomicfu_version"
         classpath "org.jetbrains.kotlinx:kotlinx-knit:$knit_version"
-        classpath "com.moowork.gradle:gradle-node-plugin:$gradle_node_version"
+        classpath "com.github.node-gradle:gradle-node-plugin:$gradle_node_version"
         classpath "org.jetbrains.kotlinx:binary-compatibility-validator:$binary_compatibility_validator_version"
+        classpath "ru.vyarus:gradle-animalsniffer-plugin:1.5.4" // Android API check
+        classpath "org.jetbrains.kotlinx:kover:$kover_version"
 
         // JMH plugins
-        classpath "com.github.jengelman.gradle.plugins:shadow:5.1.0"
+        classpath "gradle.plugin.com.github.johnrengelman:shadow:7.1.2"
     }
 
     CacheRedirector.configureBuildScript(buildscript, rootProject)
@@ -102,13 +93,6 @@
         kotlin_version = rootProject.properties['kotlin_snapshot_version']
     }
 
-    if (using_snapshot_version) {
-        repositories {
-            mavenLocal()
-            maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
-        }
-    }
-
     ext.unpublished = unpublished
 
     // This project property is set during nightly stress test
@@ -121,11 +105,14 @@
 }
 
 apply plugin: "binary-compatibility-validator"
+apply plugin: "base"
+apply plugin: "kover-conventions"
+
 apiValidation {
     ignoredProjects += unpublished + ["kotlinx-coroutines-bom"]
     if (build_snapshot_train) {
         ignoredProjects.remove("example-frontend-js")
-        ignoredProjects.add("kotlinx-coroutines-core")
+        ignoredProjects.add(coreModule)
     }
     ignoredPackages += "kotlinx.coroutines.internal"
 }
@@ -139,30 +126,54 @@
          */
         google()
         mavenCentral()
+        maven { url "https://maven.pkg.jetbrains.space/kotlin/p/kotlin/dev" }
     }
 }
 
+// needs to be before evaluationDependsOn due to weird Gradle ordering
+apply plugin: "animalsniffer-conventions"
+
 // Add dependency to core source sets. Core is configured in kx-core/build.gradle
 configure(subprojects.findAll { !sourceless.contains(it.name) && it.name != coreModule }) {
     evaluationDependsOn(":$coreModule")
-    def platform = PlatformKt.platformOf(it)
-    apply plugin: "kotlin-${platform}-conventions"
-    dependencies {
-        // See comment below for rationale, it will be replaced with "project" dependency
-        api project(":$coreModule")
-        // the only way IDEA can resolve test classes
-        testImplementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
+    if (isMultiplatform(it)) {
+        apply plugin: "kotlin-multiplatform"
+        apply from: rootProject.file("gradle/compile-jvm-multiplatform.gradle")
+        apply from: rootProject.file("gradle/compile-common.gradle")
+
+        if (rootProject.ext["native_targets_enabled"] as Boolean) {
+            apply from: rootProject.file("gradle/compile-native-multiplatform.gradle")
+        }
+
+        apply from: rootProject.file("gradle/compile-js-multiplatform.gradle")
+        apply from: rootProject.file("gradle/publish-npm-js.gradle")
+        kotlin.sourceSets.commonMain.dependencies {
+            api project(":$coreModule")
+        }
+        kotlin.sourceSets.jvmTest.dependencies {
+            implementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
+        }
+    } else {
+        def platform = PlatformKt.platformOf(it)
+        apply plugin: "kotlin-${platform}-conventions"
+        dependencies {
+            api project(":$coreModule")
+            // the only way IDEA can resolve test classes
+            testImplementation project(":$coreModule").kotlin.targets.jvm.compilations.test.output.allOutputs
+        }
     }
 }
 
+apply plugin: "bom-conventions"
+
 // Configure subprojects with Kotlin sources
 configure(subprojects.findAll { !sourceless.contains(it.name) }) {
     // Use atomicfu plugin, it also adds all the necessary dependencies
     apply plugin: 'kotlinx-atomicfu'
 
     // Configure options for all Kotlin compilation tasks
-    tasks.withType(org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile).all {
-        kotlinOptions.freeCompilerArgs += optInAnnotations.collect { "-Xopt-in=" + it }
+    tasks.withType(AbstractKotlinCompile).all {
+        kotlinOptions.freeCompilerArgs += OptInPreset.optInAnnotations.collect { "-Xopt-in=" + it }
         kotlinOptions.freeCompilerArgs += "-progressive"
         // Disable KT-36770 for RxJava2 integration
         kotlinOptions.freeCompilerArgs += "-XXLanguage:-ProhibitUsingNullableTypeParameterAgainstNotNullAnnotated"
@@ -189,7 +200,7 @@
     }
 
     println "Manifest of kotlin-compiler-embeddable.jar for coroutines"
-    configure(subprojects.findAll { it.name == "kotlinx-coroutines-core" }) {
+    configure(subprojects.findAll { it.name == coreModule }) {
         configurations.matching { it.name == "kotlinCompilerClasspath" }.all {
             resolvedConfiguration.getFiles().findAll { it.name.contains("kotlin-compiler-embeddable") }.each {
                 def manifest = zipTree(it).matching {
@@ -206,9 +217,8 @@
 
 // Redefine source sets because we are not using 'kotlin/main/fqn' folder convention
 configure(subprojects.findAll {
-    !sourceless.contains(it.name) &&
+    !sourceless.contains(it.name) && !isMultiplatform(it) &&
             it.name != "benchmarks" &&
-            it.name != coreModule &&
             it.name != "example-frontend-js"
 }) {
     // Pure JS and pure MPP doesn't have this notion and are configured separately
@@ -221,11 +231,11 @@
     }
 }
 
-def core_docs_url = "https://kotlin.github.io/kotlinx.coroutines/$coreModule/"
+def core_docs_url = "https://kotlinlang.org/api/kotlinx.coroutines/$coreModule/"
 def core_docs_file = "$projectDir/kotlinx-coroutines-core/build/dokka/htmlPartial/package-list"
 apply plugin: "org.jetbrains.dokka"
 
-configure(subprojects.findAll { !unpublished.contains(it.name) }) {
+configure(subprojects.findAll { !unpublished.contains(it.name) && it.name != coreModule }) {
     if (it.name != 'kotlinx-coroutines-bom') {
         apply from: rootProject.file('gradle/dokka.gradle.kts')
     }
@@ -245,10 +255,44 @@
             }
         }
     }
+
+    def thisProject = it
+    if (thisProject.name in sourceless) {
+        return
+    }
+
+    def versionFileTask = thisProject.tasks.register("versionFileTask") {
+        def name = thisProject.name.replace("-", "_")
+        def versionFile = thisProject.layout.buildDirectory.file("${name}.version")
+        it.outputs.file(versionFile)
+
+        it.doLast {
+            versionFile.get().asFile.text = version.toString()
+        }
+    }
+
+    List<String> jarTasks
+    if (isMultiplatform(it)) {
+        jarTasks = ["jvmJar", "metadataJar"]
+    } else if (it.name == "kotlinx-coroutines-debug") {
+        // We shadow debug module instead of just packaging it
+        jarTasks = ["shadowJar"]
+    } else {
+        jarTasks = ["jar"]
+    }
+
+    for (name in jarTasks) {
+        thisProject.tasks.named(name, Jar) {
+            it.dependsOn versionFileTask
+            it.from(versionFileTask) {
+                into("META-INF")
+            }
+        }
+    }
 }
 
 // Report Kotlin compiler version when building project
-println("Using Kotlin compiler version: $org.jetbrains.kotlin.config.KotlinCompilerVersion.VERSION")
+println("Using Kotlin compiler version: $KotlinCompilerVersion.VERSION")
 
 // --------------- Cache redirector ---------------
 
@@ -262,8 +306,6 @@
 
 task deploy(dependsOn: publishTasks)
 
-apply plugin: 'base'
-
 clean.dependsOn gradle.includedBuilds.collect { it.task(':clean') }
 
 // --------------- Knit configuration ---------------
@@ -271,7 +313,7 @@
 apply plugin: 'kotlinx-knit'
 
 knit {
-    siteRoot = "https://kotlin.github.io/kotlinx.coroutines"
+    siteRoot = "https://kotlinlang.org/api/kotlinx.coroutines"
     moduleRoots = [".", "integration", "reactive", "ui"]
     moduleDocs = "build/dokka/htmlPartial"
     dokkaMultiModuleRoot = "build/dokka/htmlMultiModule/"
@@ -302,12 +344,12 @@
             .matching {
                 // Excluding substituted project itself because of circular dependencies, but still do it
                 // for "*Test*" configurations
-                subProject.name != "kotlinx-coroutines-core" || it.name.contains("Test")
+                subProject.name != coreModule || it.name.contains("Test")
             }
             .configureEach { conf ->
                 conf.resolutionStrategy.dependencySubstitution {
-                    substitute(module("org.jetbrains.kotlinx:kotlinx-coroutines-core"))
-                            .using(project(":kotlinx-coroutines-core"))
+                    substitute(module("org.jetbrains.kotlinx:$coreModule"))
+                            .using(project(":$coreModule"))
                             .because("Because Kotlin compiler embeddable leaks coroutines into the runtime classpath, " +
                                     "triggering all sort of incompatible class changes errors")
                 }