Drop support for Gradle 3.x
#KT-27885 Fixed
This commit is contained in:
+2
-7
@@ -47,14 +47,9 @@ enum class KotlinPlatformType: Named, Serializable {
|
|||||||
|
|
||||||
fun setupAttributesMatchingStrategy(attributesSchema: AttributesSchema) {
|
fun setupAttributesMatchingStrategy(attributesSchema: AttributesSchema) {
|
||||||
attributesSchema.attribute(KotlinPlatformType.attribute).run {
|
attributesSchema.attribute(KotlinPlatformType.attribute).run {
|
||||||
if (isGradleAtLeast(4, 0)) {
|
compatibilityRules.add(CompatibilityRule::class.java)
|
||||||
compatibilityRules.add(CompatibilityRule::class.java)
|
disambiguationRules.add(DisambiguationRule::class.java)
|
||||||
disambiguationRules.add(DisambiguationRule::class.java)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isGradleAtLeast(major: Int, minor: Int) =
|
|
||||||
GradleVersion.current() >= GradleVersion.version("$major.$minor")
|
|
||||||
+5
-18
@@ -14,7 +14,7 @@ import kotlin.test.assertTrue
|
|||||||
|
|
||||||
class KotlinAndroidGradleIT : AbstractKotlinAndroidGradleTests(androidGradlePluginVersion = "2.3.0") {
|
class KotlinAndroidGradleIT : AbstractKotlinAndroidGradleTests(androidGradlePluginVersion = "2.3.0") {
|
||||||
override val defaultGradleVersion: GradleVersionRequired
|
override val defaultGradleVersion: GradleVersionRequired
|
||||||
get() = GradleVersionRequired.InRange("3.4", "4.10.2")
|
get() = GradleVersionRequired.InRange("4.0", "4.10.2")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO If we there is a way to fetch the latest Android plugin version, test against the latest version
|
// TODO If we there is a way to fetch the latest Android plugin version, test against the latest version
|
||||||
@@ -329,17 +329,6 @@ abstract class AbstractKotlinAndroidGradleTests(val androidGradlePluginVersion:
|
|||||||
// Execute 'assembleAndroidTest' first, without 'build' side effects
|
// Execute 'assembleAndroidTest' first, without 'build' side effects
|
||||||
project.build("assembleAndroidTest") {
|
project.build("assembleAndroidTest") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
if (project.testGradleVersionBelow("4.0")) {
|
|
||||||
val tasks = ArrayList<String>().apply {
|
|
||||||
for (subProject in listOf("Android", "Lib")) {
|
|
||||||
for (flavor in listOf("Flavor1", "Flavor2")) {
|
|
||||||
add(":$subProject:copy${flavor}DebugKotlinClasses")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// with the new AGP we don't need copy classes tasks
|
|
||||||
assertTasksExecuted(tasks)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,12 +579,10 @@ fun getSomething() = 10
|
|||||||
":libAndroid:compileReleaseUnitTestKotlin"
|
":libAndroid:compileReleaseUnitTestKotlin"
|
||||||
)
|
)
|
||||||
|
|
||||||
val kotlinFolder = if (project.testGradleVersionAtLeast("4.0")) "kotlin" else ""
|
assertFileExists("lib/build/classes/kotlin/main/foo/PlatformClass.kotlin_metadata")
|
||||||
|
assertFileExists("lib/build/classes/kotlin/test/foo/PlatformTest.kotlin_metadata")
|
||||||
assertFileExists("lib/build/classes/$kotlinFolder/main/foo/PlatformClass.kotlin_metadata")
|
assertFileExists("libJvm/build/classes/kotlin/main/foo/PlatformClass.class")
|
||||||
assertFileExists("lib/build/classes/$kotlinFolder/test/foo/PlatformTest.kotlin_metadata")
|
assertFileExists("libJvm/build/classes/kotlin/test/foo/PlatformTest.class")
|
||||||
assertFileExists("libJvm/build/classes/$kotlinFolder/main/foo/PlatformClass.class")
|
|
||||||
assertFileExists("libJvm/build/classes/$kotlinFolder/test/foo/PlatformTest.class")
|
|
||||||
|
|
||||||
assertFileExists("libAndroid/build/tmp/kotlin-classes/debug/foo/PlatformClass.class")
|
assertFileExists("libAndroid/build/tmp/kotlin-classes/debug/foo/PlatformClass.class")
|
||||||
assertFileExists("libAndroid/build/tmp/kotlin-classes/release/foo/PlatformClass.class")
|
assertFileExists("libAndroid/build/tmp/kotlin-classes/release/foo/PlatformClass.class")
|
||||||
|
|||||||
+2
-6
@@ -511,14 +511,10 @@ abstract class BaseGradleIT {
|
|||||||
assertSameFiles(sources, compiledJavaSources.projectRelativePaths(this.project), "Compiled Java files differ:\n ")
|
assertSameFiles(sources, compiledJavaSources.projectRelativePaths(this.project), "Compiled Java files differ:\n ")
|
||||||
|
|
||||||
fun Project.resourcesDir(subproject: String? = null, sourceSet: String = "main"): String =
|
fun Project.resourcesDir(subproject: String? = null, sourceSet: String = "main"): String =
|
||||||
(subproject?.plus("/") ?: "") + "build/" +
|
(subproject?.plus("/") ?: "") + "build/resources/$sourceSet/"
|
||||||
(if (testGradleVersionBelow("4.0")) "classes/" else "resources/") +
|
|
||||||
sourceSet + "/"
|
|
||||||
|
|
||||||
fun Project.classesDir(subproject: String? = null, sourceSet: String = "main", language: String = "kotlin"): String =
|
fun Project.classesDir(subproject: String? = null, sourceSet: String = "main", language: String = "kotlin"): String =
|
||||||
(subproject?.plus("/") ?: "") + "build/classes/" +
|
(subproject?.plus("/") ?: "") + "build/classes/$language/$sourceSet/"
|
||||||
(if (testGradleVersionAtLeast("4.0")) "$language/" else "") +
|
|
||||||
sourceSet + "/"
|
|
||||||
|
|
||||||
fun Project.testGradleVersionAtLeast(version: String): Boolean =
|
fun Project.testGradleVersionAtLeast(version: String): Boolean =
|
||||||
GradleVersion.version(chooseWrapperVersionOrFinishTest()) >= GradleVersion.version(version)
|
GradleVersion.version(chooseWrapperVersionOrFinishTest()) >= GradleVersion.version(version)
|
||||||
|
|||||||
+1
-4
@@ -21,10 +21,7 @@ import org.junit.Assume
|
|||||||
|
|
||||||
sealed class GradleVersionRequired(val minVersion: String, val maxVersion: String?) {
|
sealed class GradleVersionRequired(val minVersion: String, val maxVersion: String?) {
|
||||||
companion object {
|
companion object {
|
||||||
//TODO once the plugin is compiled with API level 1.0, replace with the really supported one (3.2)
|
const val OLDEST_SUPPORTED = "4.0"
|
||||||
// Currently, it will lead to failing tests due to the conflict with the pre-release kotlin-reflect
|
|
||||||
// bundled into Gradle 3.2...3.4
|
|
||||||
const val OLDEST_SUPPORTED = "3.5"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Exact(version: String) : GradleVersionRequired(version, version)
|
class Exact(version: String) : GradleVersionRequired(version, version)
|
||||||
|
|||||||
-22
@@ -308,28 +308,6 @@ open class Kapt3IT : Kapt3BaseIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testKaptClassesDirSync() {
|
|
||||||
val project = Project("autoService", GradleVersionRequired.Exact("3.5"), directoryPrefix = "kapt2")
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertKaptSuccessful()
|
|
||||||
assertFileExists("processor/build/classes/main/META-INF/services/javax.annotation.processing.Processor")
|
|
||||||
assertFileExists("processor/build/classes/main/processor/MyProcessor.class")
|
|
||||||
}
|
|
||||||
|
|
||||||
project.projectDir.getFileByName("MyProcessor.kt").modify {
|
|
||||||
it.replace("@AutoService(Processor::class)", "")
|
|
||||||
}
|
|
||||||
|
|
||||||
project.build(":processor:build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertNoSuchFile("processor/build/classes/main/META-INF/services/javax.annotation.processing.Processor")
|
|
||||||
assertFileExists("processor/build/classes/main/processor/MyProcessor.class")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests that compile arguments are properly copied from compileKotlin to kaptTask
|
* Tests that compile arguments are properly copied from compileKotlin to kaptTask
|
||||||
*/
|
*/
|
||||||
|
|||||||
+4
-4
@@ -133,7 +133,7 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCompilerTestAccessInternalProduction() {
|
fun testCompilerTestAccessInternalProduction() {
|
||||||
val project = Project("kotlin2JsInternalTest", GradleVersionRequired.Exact("3.5"))
|
val project = Project("kotlin2JsInternalTest")
|
||||||
|
|
||||||
project.build("runRhino") {
|
project.build("runRhino") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
@@ -167,7 +167,7 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testKotlinJsBuiltins() {
|
fun testKotlinJsBuiltins() {
|
||||||
val project = Project("kotlinBuiltins", GradleVersionRequired.AtLeast("4.0"))
|
val project = Project("kotlinBuiltins")
|
||||||
|
|
||||||
project.setupWorkingDir()
|
project.setupWorkingDir()
|
||||||
val buildGradle = File(project.projectDir, "app").getFileByName("build.gradle")
|
val buildGradle = File(project.projectDir, "app").getFileByName("build.gradle")
|
||||||
@@ -309,7 +309,7 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
|
|||||||
/** Issue: KT-18495 */
|
/** Issue: KT-18495 */
|
||||||
@Test
|
@Test
|
||||||
fun testNoSeparateClassesDirWarning() {
|
fun testNoSeparateClassesDirWarning() {
|
||||||
val project = Project("kotlin2JsProject", GradleVersionRequired.AtLeast("4.0"))
|
val project = Project("kotlin2JsProject")
|
||||||
project.build("build") {
|
project.build("build") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
assertNotContains("this build assumes a single directory for all classes from a source set")
|
assertNotContains("this build assumes a single directory for all classes from a source set")
|
||||||
@@ -317,7 +317,7 @@ class Kotlin2JsGradlePluginIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testIncrementalCompilation() = Project("kotlin2JsICProject", GradleVersionRequired.AtLeast("4.0")).run {
|
fun testIncrementalCompilation() = Project("kotlin2JsICProject").run {
|
||||||
build("build") {
|
build("build") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
|
assertContains(USING_JS_INCREMENTAL_COMPILATION_MESSAGE)
|
||||||
|
|||||||
+2
-135
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.gradle
|
package org.jetbrains.kotlin.gradle
|
||||||
|
|
||||||
import org.gradle.api.logging.LogLevel
|
import org.gradle.api.logging.LogLevel
|
||||||
import org.jetbrains.kotlin.gradle.plugin.CopyClassesToJavaOutputStatus
|
|
||||||
import org.jetbrains.kotlin.gradle.tasks.USING_JVM_INCREMENTAL_COMPILATION_MESSAGE
|
import org.jetbrains.kotlin.gradle.tasks.USING_JVM_INCREMENTAL_COMPILATION_MESSAGE
|
||||||
import org.jetbrains.kotlin.gradle.util.*
|
import org.jetbrains.kotlin.gradle.util.*
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@@ -259,24 +258,6 @@ class KotlinGradleIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testWipeClassesDirectoryBetweenBuilds() {
|
|
||||||
val project = Project("kotlinJavaProject", GradleVersionRequired.Exact("3.5"))
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
}
|
|
||||||
|
|
||||||
val javaOutputDir = File(project.projectDir, "build/classes")
|
|
||||||
assert(javaOutputDir.isDirectory) { "Classes directory does not exist $javaOutputDir" }
|
|
||||||
javaOutputDir.deleteRecursively()
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertTasksUpToDate(":compileKotlin")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMoveClassToOtherModule() {
|
fun testMoveClassToOtherModule() {
|
||||||
val project = Project("moveClassToOtherModule")
|
val project = Project("moveClassToOtherModule")
|
||||||
@@ -317,7 +298,7 @@ class KotlinGradleIT : BaseGradleIT() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testKotlinBuiltins() {
|
fun testKotlinBuiltins() {
|
||||||
val project = Project("kotlinBuiltins", GradleVersionRequired.AtLeast("4.0"))
|
val project = Project("kotlinBuiltins")
|
||||||
|
|
||||||
project.build("build") {
|
project.build("build") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
@@ -361,42 +342,6 @@ class KotlinGradleIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testChangeDestinationDir() {
|
|
||||||
val project = Project("kotlinProject", GradleVersionRequired.Exact("3.5"))
|
|
||||||
project.setupWorkingDir()
|
|
||||||
|
|
||||||
val fileToRemove = File(project.projectDir, "src/main/kotlin/removeMe.kt")
|
|
||||||
fileToRemove.writeText("val x = 1")
|
|
||||||
val classFilePath = "build/classes/main/RemoveMeKt.class"
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertFileExists(classFilePath)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that after the change the build succeeds and no stale classes remain in the java classes dir
|
|
||||||
File(project.projectDir, "build.gradle").modify {
|
|
||||||
"$it\n\ncompileKotlin.destinationDir = file(\"\${project.buildDir}/compileKotlin\")"
|
|
||||||
}
|
|
||||||
fileToRemove.delete()
|
|
||||||
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertNoSuchFile(classFilePath)
|
|
||||||
// Check that the fallback to non-incremental copying was chosen
|
|
||||||
assertContains("Non-incremental copying files")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that the classes are copied incrementally under normal conditions
|
|
||||||
fileToRemove.writeText("val x = 1")
|
|
||||||
project.build("build") {
|
|
||||||
assertSuccessful()
|
|
||||||
assertFileExists(classFilePath)
|
|
||||||
assertNotContains("Non-incremental copying files")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testDowngradeTo106() {
|
fun testDowngradeTo106() {
|
||||||
val project = Project("kotlinProject")
|
val project = Project("kotlinProject")
|
||||||
@@ -515,7 +460,7 @@ class KotlinGradleIT : BaseGradleIT() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSeparateOutputGradle40() {
|
fun testSeparateOutputGradle40() {
|
||||||
val project = Project("kotlinJavaProject", GradleVersionRequired.AtLeast("4.0"))
|
val project = Project("kotlinJavaProject")
|
||||||
project.build("compileDeployKotlin", "assemble") {
|
project.build("compileDeployKotlin", "assemble") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
|
|
||||||
@@ -529,10 +474,6 @@ class KotlinGradleIT : BaseGradleIT() {
|
|||||||
|
|
||||||
// Check that the Java output is intact:
|
// Check that the Java output is intact:
|
||||||
assertFileExists("build/classes/java/main/demo/Greeter.class")
|
assertFileExists("build/classes/java/main/demo/Greeter.class")
|
||||||
|
|
||||||
// Check that the sync output task is not used with Gradle 4.0+ and there's no old Kotlin output layout
|
|
||||||
assertNotContains(":copyMainKotlinClasses")
|
|
||||||
assertNoSuchFile("build/kotlin-classes")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -574,80 +515,6 @@ class KotlinGradleIT : BaseGradleIT() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testDisableSeparateClassesDirs() {
|
|
||||||
|
|
||||||
fun CompiledProject.check(
|
|
||||||
copyClassesToJavaOutput: Boolean?,
|
|
||||||
expectBuildCacheWarning: Boolean,
|
|
||||||
expectGradleLowVersionWarning: Boolean
|
|
||||||
) {
|
|
||||||
|
|
||||||
val separateDirPath = kotlinClassesDir() + "demo/KotlinGreetingJoiner.class"
|
|
||||||
val singleDirPath = javaClassesDir() + "demo/KotlinGreetingJoiner.class"
|
|
||||||
|
|
||||||
assertSuccessful()
|
|
||||||
when (copyClassesToJavaOutput) {
|
|
||||||
true -> {
|
|
||||||
assertNoSuchFile(separateDirPath)
|
|
||||||
assertFileExists(singleDirPath)
|
|
||||||
}
|
|
||||||
false -> {
|
|
||||||
assertFileExists(separateDirPath)
|
|
||||||
assertNoSuchFile(singleDirPath)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expectBuildCacheWarning)
|
|
||||||
assertContains(CopyClassesToJavaOutputStatus.buildCacheWarningMessage)
|
|
||||||
else
|
|
||||||
assertNotContains(CopyClassesToJavaOutputStatus.buildCacheWarningMessage)
|
|
||||||
|
|
||||||
if (expectGradleLowVersionWarning)
|
|
||||||
assertContains(CopyClassesToJavaOutputStatus.gradleVersionTooLowWarningMessage)
|
|
||||||
else
|
|
||||||
assertNotContains(CopyClassesToJavaOutputStatus.gradleVersionTooLowWarningMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
Project("simpleProject", GradleVersionRequired.Exact("4.0")).apply {
|
|
||||||
build("build") {
|
|
||||||
check(
|
|
||||||
copyClassesToJavaOutput = false,
|
|
||||||
expectBuildCacheWarning = false,
|
|
||||||
expectGradleLowVersionWarning = false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
File(projectDir, "build.gradle").appendText("\nkotlin.copyClassesToJavaOutput = true")
|
|
||||||
build("clean", "build") {
|
|
||||||
check(
|
|
||||||
copyClassesToJavaOutput = true,
|
|
||||||
expectBuildCacheWarning = false,
|
|
||||||
expectGradleLowVersionWarning = false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
build("clean", "build", options = defaultBuildOptions().copy(withBuildCache = true)) {
|
|
||||||
check(
|
|
||||||
copyClassesToJavaOutput = true,
|
|
||||||
expectBuildCacheWarning = true,
|
|
||||||
expectGradleLowVersionWarning = false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
projectDir.deleteRecursively()
|
|
||||||
}
|
|
||||||
|
|
||||||
Project("simpleProject", GradleVersionRequired.Exact("3.4")).apply {
|
|
||||||
setupWorkingDir()
|
|
||||||
File(projectDir, "build.gradle").appendText("\nkotlin.copyClassesToJavaOutput = true")
|
|
||||||
build("build") {
|
|
||||||
check(
|
|
||||||
copyClassesToJavaOutput = null,
|
|
||||||
expectBuildCacheWarning = false,
|
|
||||||
expectGradleLowVersionWarning = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSrcDirTaskDependency() {
|
fun testSrcDirTaskDependency() {
|
||||||
Project("simpleProject", GradleVersionRequired.AtLeast("4.1")).apply {
|
Project("simpleProject", GradleVersionRequired.AtLeast("4.1")).apply {
|
||||||
|
|||||||
+2
-2
@@ -29,7 +29,7 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testMultiplatformCompile() {
|
fun testMultiplatformCompile() {
|
||||||
val project = Project("multiplatformProject", GradleVersionRequired.AtLeast("4.0"))
|
val project = Project("multiplatformProject")
|
||||||
|
|
||||||
project.build("build") {
|
project.build("build") {
|
||||||
assertSuccessful()
|
assertSuccessful()
|
||||||
@@ -89,7 +89,7 @@ class MultiplatformGradleIT : BaseGradleIT() {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSubprojectWithAnotherClassLoader() {
|
fun testSubprojectWithAnotherClassLoader() {
|
||||||
with(Project("multiplatformProject", GradleVersionRequired.AtLeast("4.0"))) {
|
with(Project("multiplatformProject")) {
|
||||||
setupWorkingDir()
|
setupWorkingDir()
|
||||||
|
|
||||||
// Make sure there is a plugin applied with the plugins DSL, so that Gradle loads the
|
// Make sure there is a plugin applied with the plugins DSL, so that Gradle loads the
|
||||||
|
|||||||
+1
-6
@@ -137,12 +137,7 @@ class UpToDateIT : BaseGradleIT() {
|
|||||||
lateinit var helloWorldKtClass: File
|
lateinit var helloWorldKtClass: File
|
||||||
|
|
||||||
override fun mutateProject(project: Project) = with(project) {
|
override fun mutateProject(project: Project) = with(project) {
|
||||||
val kotlinOutputPath =
|
val kotlinOutputPath = project.classesDir()
|
||||||
if (testGradleVersionAtLeast("4.0"))
|
|
||||||
project.classesDir()
|
|
||||||
else
|
|
||||||
// Before 4.0, we should delete the classes from the temporary dir to make compileKotlin rerun:
|
|
||||||
"build/kotlin-classes/main/"
|
|
||||||
|
|
||||||
helloWorldKtClass = File(projectDir, kotlinOutputPath + "demo/KotlinGreetingJoiner.class")
|
helloWorldKtClass = File(projectDir, kotlinOutputPath + "demo/KotlinGreetingJoiner.class")
|
||||||
Assume.assumeTrue(helloWorldKtClass.exists())
|
Assume.assumeTrue(helloWorldKtClass.exists())
|
||||||
|
|||||||
-4
@@ -6,16 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.gradle.model
|
package org.jetbrains.kotlin.gradle.model
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
||||||
import org.jetbrains.kotlin.gradle.GradleVersionRequired
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class AllOpenModelIT : BaseGradleIT() {
|
class AllOpenModelIT : BaseGradleIT() {
|
||||||
override val defaultGradleVersion: GradleVersionRequired
|
|
||||||
get() = GradleVersionRequired.AtLeast("4.0")
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testAllOpenSimple() {
|
fun testAllOpenSimple() {
|
||||||
val project = Project("allOpenSimple")
|
val project = Project("allOpenSimple")
|
||||||
|
|||||||
-5
@@ -6,16 +6,11 @@
|
|||||||
package org.jetbrains.kotlin.gradle.model
|
package org.jetbrains.kotlin.gradle.model
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
||||||
import org.jetbrains.kotlin.gradle.GradleVersionRequired
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
import kotlin.test.assertTrue
|
|
||||||
|
|
||||||
class KaptModelIT : BaseGradleIT() {
|
class KaptModelIT : BaseGradleIT() {
|
||||||
override val defaultGradleVersion: GradleVersionRequired
|
|
||||||
get() = GradleVersionRequired.AtLeast("4.0")
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testKaptSimple() {
|
fun testKaptSimple() {
|
||||||
val project = Project("simple", directoryPrefix = "kapt2")
|
val project = Project("simple", directoryPrefix = "kapt2")
|
||||||
|
|||||||
-3
@@ -14,9 +14,6 @@ import kotlin.test.assertNull
|
|||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class NoArgModelIT : BaseGradleIT() {
|
class NoArgModelIT : BaseGradleIT() {
|
||||||
override val defaultGradleVersion: GradleVersionRequired
|
|
||||||
get() = GradleVersionRequired.AtLeast("4.0")
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testNoArgKt18668() {
|
fun testNoArgKt18668() {
|
||||||
val project = Project("noArgKt18668")
|
val project = Project("noArgKt18668")
|
||||||
|
|||||||
-4
@@ -6,16 +6,12 @@
|
|||||||
package org.jetbrains.kotlin.gradle.model
|
package org.jetbrains.kotlin.gradle.model
|
||||||
|
|
||||||
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
import org.jetbrains.kotlin.gradle.BaseGradleIT
|
||||||
import org.jetbrains.kotlin.gradle.GradleVersionRequired
|
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNull
|
import kotlin.test.assertNull
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
class SamWithReceiverModelIT : BaseGradleIT() {
|
class SamWithReceiverModelIT : BaseGradleIT() {
|
||||||
override val defaultGradleVersion: GradleVersionRequired
|
|
||||||
get() = GradleVersionRequired.AtLeast("4.0")
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSamWithReceiverSimple() {
|
fun testSamWithReceiverSimple() {
|
||||||
val project = Project("samWithReceiverSimple")
|
val project = Project("samWithReceiverSimple")
|
||||||
|
|||||||
+1
-7
@@ -51,13 +51,7 @@ open class KotlinSingleJavaTargetExtension : KotlinProjectExtension() {
|
|||||||
internal lateinit var target: KotlinWithJavaTarget<*>
|
internal lateinit var target: KotlinWithJavaTarget<*>
|
||||||
}
|
}
|
||||||
|
|
||||||
open class KotlinJvmProjectExtension : KotlinSingleJavaTargetExtension() {
|
open class KotlinJvmProjectExtension : KotlinSingleJavaTargetExtension()
|
||||||
/**
|
|
||||||
* With Gradle 4.0+, disables the separate output directory for Kotlin, falling back to sharing the deprecated
|
|
||||||
* single classes directory per source set. With Gradle < 4.0, has no effect.
|
|
||||||
* */
|
|
||||||
var copyClassesToJavaOutput = false
|
|
||||||
}
|
|
||||||
|
|
||||||
open class ExperimentalExtension {
|
open class ExperimentalExtension {
|
||||||
var coroutines: Coroutines? = null
|
var coroutines: Coroutines? = null
|
||||||
|
|||||||
+2
-3
@@ -379,9 +379,8 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
|
|||||||
|
|
||||||
kotlinCompilation?.run {
|
kotlinCompilation?.run {
|
||||||
output.apply {
|
output.apply {
|
||||||
if (tryAddClassesDir { project.files(classesOutputDir).builtBy(kaptTask) }) {
|
addClassesDir { project.files(classesOutputDir).builtBy(kaptTask) }
|
||||||
kotlinCompile.attachClassesDir { classesOutputDir }
|
kotlinCompile.attachClassesDir { classesOutputDir }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-54
@@ -1,54 +0,0 @@
|
|||||||
package org.jetbrains.kotlin.gradle.plugin
|
|
||||||
|
|
||||||
import org.gradle.api.Project
|
|
||||||
import org.gradle.api.Task
|
|
||||||
import org.gradle.api.specs.Spec
|
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
|
||||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
|
||||||
import org.jetbrains.kotlin.gradle.logging.kotlinWarn
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.ParsedGradleVersion
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object CopyClassesToJavaOutputStatus {
|
|
||||||
fun isEnabled(project: Project): Boolean {
|
|
||||||
val kotlinJvmExt = project.kotlinJvmExt ?: return false
|
|
||||||
if (kotlinJvmExt.copyClassesToJavaOutput) {
|
|
||||||
if (isGradleVersionTooLow(project)) {
|
|
||||||
if (warningReportedForProject.add(project)) {
|
|
||||||
project.logger.kotlinWarn(gradleVersionTooLowWarningMessage)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
addCacheWarningToJavaTasks(project)
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private val warningReportedForProject = Collections.newSetFromMap<Project>(WeakHashMap())
|
|
||||||
|
|
||||||
private fun isGradleVersionTooLow(project: Project): Boolean {
|
|
||||||
return (ParsedGradleVersion.parse(project.gradle.gradleVersion) ?: return false) < ParsedGradleVersion(4, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addCacheWarningToJavaTasks(project: Project) {
|
|
||||||
project.tasks.withType(JavaCompile::class.java).all {
|
|
||||||
val warningCacheIfSpec = Spec<Task> {
|
|
||||||
if (warningReportedForProject.add(project)) {
|
|
||||||
project.logger.kotlinWarn(buildCacheWarningMessage)
|
|
||||||
}
|
|
||||||
return@Spec true
|
|
||||||
}
|
|
||||||
it.outputs.javaClass.getMethod("cacheIf", Spec::class.java).invoke(it.outputs, warningCacheIfSpec)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const val buildCacheWarningMessage = "The 'kotlin.copyClassesToJavaOutput' option should not be used with Gradle " +
|
|
||||||
"build cache"
|
|
||||||
|
|
||||||
const val gradleVersionTooLowWarningMessage = "The 'kotlin.copyClassesToJavaOutput' option has no effect when " +
|
|
||||||
"used with Gradle < 4.0"
|
|
||||||
|
|
||||||
private val Project.kotlinJvmExt: KotlinJvmProjectExtension?
|
|
||||||
get() = extensions.findByType(KotlinJvmProjectExtension::class.java)
|
|
||||||
}
|
|
||||||
+16
-76
@@ -59,29 +59,21 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
|||||||
protected abstract fun doTargetSpecificProcessing()
|
protected abstract fun doTargetSpecificProcessing()
|
||||||
protected val logger = Logging.getLogger(this.javaClass)!!
|
protected val logger = Logging.getLogger(this.javaClass)!!
|
||||||
|
|
||||||
protected val isSeparateClassesDirSupported: Boolean by lazy {
|
|
||||||
!CopyClassesToJavaOutputStatus.isEnabled(project) && isGradleVersionAtLeast(4, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected val sourceSetName: String = kotlinCompilation.compilationName
|
protected val sourceSetName: String = kotlinCompilation.compilationName
|
||||||
|
|
||||||
protected val kotlinTask: TaskHolder<out T> = registerKotlinCompileTask()
|
protected val kotlinTask: TaskHolder<out T> = registerKotlinCompileTask()
|
||||||
|
|
||||||
protected val javaSourceSet: SourceSet? = (kotlinCompilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet
|
protected val javaSourceSet: SourceSet? = (kotlinCompilation as? KotlinWithJavaCompilation<*>)?.javaSourceSet
|
||||||
|
|
||||||
protected open val defaultKotlinDestinationDir: File
|
private val defaultKotlinDestinationDir: File
|
||||||
get() {
|
get() {
|
||||||
return if (isSeparateClassesDirSupported) {
|
val kotlinExt = project.kotlinExtension
|
||||||
val kotlinExt = project.kotlinExtension
|
val targetSubDirectory =
|
||||||
val targetSubDirectory =
|
if (kotlinExt is KotlinSingleJavaTargetExtension)
|
||||||
if (kotlinExt is KotlinSingleJavaTargetExtension)
|
"" // In single-target projects, don't add the target name part to this path
|
||||||
"" // In single-target projects, don't add the target name part to this path
|
else
|
||||||
else
|
kotlinCompilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
||||||
kotlinCompilation.target.disambiguationClassifier?.let { "$it/" }.orEmpty()
|
return File(project.buildDir, "classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationName}")
|
||||||
File(project.buildDir, "classes/kotlin/$targetSubDirectory${kotlinCompilation.compilationName}")
|
|
||||||
} else {
|
|
||||||
kotlinCompilation.output.classesDirs.singleFile
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun registerKotlinCompileTask(): TaskHolder<out T> {
|
private fun registerKotlinCompileTask(): TaskHolder<out T> {
|
||||||
@@ -91,7 +83,7 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
|||||||
it.description = taskDescription
|
it.description = taskDescription
|
||||||
it.mapClasspath { kotlinCompilation.compileDependencyFiles }
|
it.mapClasspath { kotlinCompilation.compileDependencyFiles }
|
||||||
it.setDestinationDir { defaultKotlinDestinationDir }
|
it.setDestinationDir { defaultKotlinDestinationDir }
|
||||||
kotlinCompilation.output.tryAddClassesDir { project.files(kotlinTask.doGetTask().destinationDir).builtBy(kotlinTask.doGetTask()) }
|
kotlinCompilation.output.addClassesDir { project.files(kotlinTask.doGetTask().destinationDir).builtBy(kotlinTask.doGetTask()) }
|
||||||
}
|
}
|
||||||
return kotlinCompile
|
return kotlinCompile
|
||||||
}
|
}
|
||||||
@@ -171,11 +163,6 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
) : KotlinSourceSetProcessor<KotlinCompile>(
|
) : KotlinSourceSetProcessor<KotlinCompile>(
|
||||||
project, tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation
|
project, tasksProvider, "Compiles the $kotlinCompilation.", kotlinCompilation
|
||||||
) {
|
) {
|
||||||
override val defaultKotlinDestinationDir: File
|
|
||||||
get() = if (!isSeparateClassesDirSupported)
|
|
||||||
File(project.buildDir, "kotlin-classes/$sourceSetName") else
|
|
||||||
super.defaultKotlinDestinationDir
|
|
||||||
|
|
||||||
override fun doRegisterTask(project: Project, taskName: String, configureAction: (KotlinCompile)->(Unit)): TaskHolder<out KotlinCompile> =
|
override fun doRegisterTask(project: Project, taskName: String, configureAction: (KotlinCompile)->(Unit)): TaskHolder<out KotlinCompile> =
|
||||||
tasksProvider.registerKotlinJVMTask(project, taskName, kotlinCompilation, configureAction)
|
tasksProvider.registerKotlinJVMTask(project, taskName, kotlinCompilation, configureAction)
|
||||||
|
|
||||||
@@ -201,19 +188,8 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
|
|
||||||
javaTask?.let { configureJavaTask(kotlinTaskInstance, it, logger) }
|
javaTask?.let { configureJavaTask(kotlinTaskInstance, it, logger) }
|
||||||
|
|
||||||
var syncOutputTask: SyncOutputTask? = null
|
|
||||||
|
|
||||||
if (!isSeparateClassesDirSupported && javaTask != null) {
|
|
||||||
syncOutputTask = registerSyncOutputTask(project, kotlinTaskInstance, javaTask, sourceSetName)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.pluginManager.hasPlugin("java-library") && sourceSetName == SourceSet.MAIN_SOURCE_SET_NAME) {
|
if (project.pluginManager.hasPlugin("java-library") && sourceSetName == SourceSet.MAIN_SOURCE_SET_NAME) {
|
||||||
val (classesProviderTask, classesDirectory) = when {
|
registerKotlinOutputForJavaLibrary(kotlinTaskInstance.destinationDir, kotlinTaskInstance)
|
||||||
isSeparateClassesDirSupported -> kotlinTaskInstance.let { it to it.destinationDir }
|
|
||||||
else -> syncOutputTask!!.let { it to it.javaOutputDir }
|
|
||||||
}
|
|
||||||
|
|
||||||
registerKotlinOutputForJavaLibrary(classesDirectory, classesProviderTask)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,15 +225,9 @@ internal class Kotlin2JvmSourceSetProcessor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KotlinCompilationOutput.tryAddClassesDir(
|
internal fun KotlinCompilationOutput.addClassesDir(classesDirProvider: () -> FileCollection) {
|
||||||
classesDirProvider: () -> FileCollection
|
classesDirs.from(Callable { classesDirProvider() })
|
||||||
): Boolean =
|
}
|
||||||
if (isGradleVersionAtLeast(4, 0)) {
|
|
||||||
classesDirs.from(Callable { classesDirProvider() })
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
internal class Kotlin2JsSourceSetProcessor(
|
internal class Kotlin2JsSourceSetProcessor(
|
||||||
project: Project,
|
project: Project,
|
||||||
@@ -305,10 +275,6 @@ internal class Kotlin2JsSourceSetProcessor(
|
|||||||
|
|
||||||
kotlinTaskInstance.destinationDir = outputDir
|
kotlinTaskInstance.destinationDir = outputDir
|
||||||
|
|
||||||
if (!isSeparateClassesDirSupported && kotlinCompilation is KotlinWithJavaCompilation<*>) {
|
|
||||||
kotlinCompilation.javaSourceSet.output.setClassesDirCompatible(kotlinTaskInstance.destinationDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
appliedPlugins
|
appliedPlugins
|
||||||
.flatMap { it.getSubpluginKotlinTasks(project, kotlinTaskInstance) }
|
.flatMap { it.getSubpluginKotlinTasks(project, kotlinTaskInstance) }
|
||||||
.forEach { task -> kotlinCompilation.allKotlinSourceSets.forEach { sourceSet -> task.source(sourceSet.kotlin) } }
|
.forEach { task -> kotlinCompilation.allKotlinSourceSets.forEach { sourceSet -> task.source(sourceSet.kotlin) } }
|
||||||
@@ -621,6 +587,8 @@ internal open class KotlinAndroidPlugin(
|
|||||||
) : Plugin<Project> {
|
) : Plugin<Project> {
|
||||||
|
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
|
checkGradleCompatibility()
|
||||||
|
|
||||||
val androidTarget = KotlinAndroidTarget("", project)
|
val androidTarget = KotlinAndroidTarget("", project)
|
||||||
applyToTarget(kotlinPluginVersion, androidTarget)
|
applyToTarget(kotlinPluginVersion, androidTarget)
|
||||||
registry.register(KotlinModelBuilder(kotlinPluginVersion, androidTarget))
|
registry.register(KotlinModelBuilder(kotlinPluginVersion, androidTarget))
|
||||||
@@ -873,38 +841,10 @@ internal fun configureJavaTask(kotlinTask: KotlinCompile, javaTask: AbstractComp
|
|||||||
* ex. it adds some support libraries jars after execution of prepareComAndroidSupportSupportV42311Library task,
|
* ex. it adds some support libraries jars after execution of prepareComAndroidSupportSupportV42311Library task,
|
||||||
* so it's only safe to modify javaTask.classpath right before its usage
|
* so it's only safe to modify javaTask.classpath right before its usage
|
||||||
*/
|
*/
|
||||||
|
// todo: remove?
|
||||||
javaTask.appendClasspathDynamically(kotlinTask.destinationDir!!)
|
javaTask.appendClasspathDynamically(kotlinTask.destinationDir!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun syncOutputTaskName(variantName: String) = "copy${variantName.capitalize()}KotlinClasses"
|
|
||||||
|
|
||||||
internal fun registerSyncOutputTask(
|
|
||||||
project: Project,
|
|
||||||
kotlinCompile: KotlinCompile,
|
|
||||||
javaTask: AbstractCompile,
|
|
||||||
variantName: String
|
|
||||||
): SyncOutputTask {
|
|
||||||
val kotlinDir = kotlinCompile.destinationDir
|
|
||||||
val javaDir = javaTask.destinationDir
|
|
||||||
val taskName = syncOutputTaskName(variantName)
|
|
||||||
|
|
||||||
// registerTask(project: Project, name: String, type: Class<T>, disableLazy: Boolean, body: (T)->(Unit)) : TaskHolder<T> {
|
|
||||||
val syncTask = registerTask(project, taskName, SyncOutputTask::class.java) {
|
|
||||||
it.kotlinOutputDir = kotlinDir
|
|
||||||
it.javaOutputDir = javaDir
|
|
||||||
it.kotlinTask = kotlinCompile
|
|
||||||
it.kaptClassesDir = getKaptGeneratedClassesDir(project, variantName)
|
|
||||||
// copying should be executed after a latter task
|
|
||||||
javaTask.finalizedByIfNotFailed(it)
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlinCompile.javaOutputDir = javaDir
|
|
||||||
|
|
||||||
project.logger.kotlinDebug { "Created task ${syncTask.doGetTask().path} to copy kotlin classes from $kotlinDir to $javaDir" }
|
|
||||||
|
|
||||||
return syncTask.doGetTask()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ifKaptEnabled(project: Project, block: () -> Unit) {
|
private fun ifKaptEnabled(project: Project, block: () -> Unit) {
|
||||||
var triggered = false
|
var triggered = false
|
||||||
|
|
||||||
|
|||||||
+3
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinUsages
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultKotlinSourceSetFactory
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_COMPILER_EMBEDDABLE
|
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_COMPILER_EMBEDDABLE
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_MODULE_GROUP
|
import org.jetbrains.kotlin.gradle.tasks.KOTLIN_MODULE_GROUP
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -49,6 +50,8 @@ abstract class KotlinBasePluginWrapper(
|
|||||||
DefaultKotlinSourceSetFactory(project, fileResolver)
|
DefaultKotlinSourceSetFactory(project, fileResolver)
|
||||||
|
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
|
checkGradleCompatibility()
|
||||||
|
|
||||||
project.configurations.maybeCreate(COMPILER_CLASSPATH_CONFIGURATION_NAME).defaultDependencies {
|
project.configurations.maybeCreate(COMPILER_CLASSPATH_CONFIGURATION_NAME).defaultDependencies {
|
||||||
it.add(project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_COMPILER_EMBEDDABLE:$kotlinPluginVersion"))
|
it.add(project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_COMPILER_EMBEDDABLE:$kotlinPluginVersion"))
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-10
@@ -35,7 +35,6 @@ import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinNativeCompile
|
|||||||
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
|
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeCompile
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
|
import org.jetbrains.kotlin.gradle.tasks.KotlinNativeLink
|
||||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -517,7 +516,7 @@ open class KotlinNativeTargetConfigurator(
|
|||||||
|
|
||||||
destinationDir = klibOutputDirectory(compilation)
|
destinationDir = klibOutputDirectory(compilation)
|
||||||
addCompilerPlugins()
|
addCompilerPlugins()
|
||||||
compilation.output.tryAddClassesDir {
|
compilation.output.addClassesDir {
|
||||||
project.files(this.outputFile).builtBy(this)
|
project.files(this.outputFile).builtBy(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -777,14 +776,7 @@ open class KotlinNativeTargetConfigurator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun Project.usageByName(usageName: String): Usage =
|
internal fun Project.usageByName(usageName: String): Usage =
|
||||||
if (isGradleVersionAtLeast(4, 0)) {
|
project.objects.named(Usage::class.java, usageName)
|
||||||
// `project.objects` is an API introduced in Gradle 4.0
|
|
||||||
project.objects.named(Usage::class.java, usageName)
|
|
||||||
} else {
|
|
||||||
val usagesClass = Class.forName("org.gradle.api.internal.attributes.Usages")
|
|
||||||
val usagesMethod = usagesClass.getMethod("usage", String::class.java)
|
|
||||||
usagesMethod(null, usageName) as Usage
|
|
||||||
}
|
|
||||||
|
|
||||||
fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
|
fun Configuration.usesPlatformOf(target: KotlinTarget): Configuration {
|
||||||
attributes.attribute(KotlinPlatformType.attribute, target.platformType)
|
attributes.attribute(KotlinPlatformType.attribute, target.platformType)
|
||||||
|
|||||||
-7
@@ -63,14 +63,7 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
|
|||||||
javaTask.classpath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
|
javaTask.classpath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
|
||||||
}
|
}
|
||||||
|
|
||||||
getTestedVariantData(variantData)?.let { testedVariantData ->
|
|
||||||
// Android Gradle plugin bypasses the Gradle finalizedBy for its tasks in some cases, and
|
|
||||||
// the Kotlin classes may not be copied for the tested variant. Make sure they are.
|
|
||||||
kotlinTask.dependsOn(syncOutputTaskName(getVariantName(testedVariantData)))
|
|
||||||
}
|
|
||||||
|
|
||||||
configureJavaTask(kotlinTask, javaTask, logger)
|
configureJavaTask(kotlinTask, javaTask, logger)
|
||||||
registerSyncOutputTask(project, kotlinTask, javaTask, getVariantName(variantData))
|
|
||||||
|
|
||||||
// In lib modules, the androidTest variants get the classes jar in their classpath instead of the Java
|
// In lib modules, the androidTest variants get the classes jar in their classpath instead of the Java
|
||||||
// destination dir. Attach the JAR to be consumed as friend path:
|
// destination dir. Attach the JAR to be consumed as friend path:
|
||||||
|
|||||||
+7
-16
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.gradle.plugin
|
|||||||
import org.gradle.api.artifacts.Configuration
|
import org.gradle.api.artifacts.Configuration
|
||||||
import org.gradle.api.attributes.*
|
import org.gradle.api.attributes.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinWithJavaTarget
|
||||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
|
||||||
|
|
||||||
object ProjectLocalConfigurations {
|
object ProjectLocalConfigurations {
|
||||||
val ATTRIBUTE: Attribute<String> = Attribute.of("org.jetbrains.kotlin.localToProject", String::class.java)
|
val ATTRIBUTE: Attribute<String> = Attribute.of("org.jetbrains.kotlin.localToProject", String::class.java)
|
||||||
@@ -18,10 +17,8 @@ object ProjectLocalConfigurations {
|
|||||||
|
|
||||||
fun setupAttributesMatchingStrategy(attributesSchema: AttributesSchema) = with(attributesSchema) {
|
fun setupAttributesMatchingStrategy(attributesSchema: AttributesSchema) = with(attributesSchema) {
|
||||||
attribute(ATTRIBUTE) {
|
attribute(ATTRIBUTE) {
|
||||||
if (gradleVersionSupportsAttributeRules) {
|
it.compatibilityRules.add(ProjectLocalCompatibility::class.java)
|
||||||
it.compatibilityRules.add(ProjectLocalCompatibility::class.java)
|
it.disambiguationRules.add(ProjectLocalDisambiguation::class.java)
|
||||||
it.disambiguationRules.add(ProjectLocalDisambiguation::class.java)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,23 +38,17 @@ object ProjectLocalConfigurations {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun Configuration.setupAsLocalTargetSpecificConfigurationIfSupported(target: KotlinTarget) {
|
internal fun Configuration.setupAsLocalTargetSpecificConfigurationIfSupported(target: KotlinTarget) {
|
||||||
if (gradleVersionSupportsAttributeRules &&
|
// don't setup in old MPP common modules, as their output configurations with KotlinPlatformType attribute would
|
||||||
// don't setup in old MPP common modules, as their output configurations with KotlinPlatformType attribute would
|
// fail to resolve as transitive dependencies of the platform modules, just as we don't mark their
|
||||||
// fail to resolve as transitive dependencies of the platform modules, just as we don't mark their
|
// `api/RuntimeElements` with the KotlinPlatformType
|
||||||
// `api/RuntimeElements` with the KotlinPlatformType
|
if ((target !is KotlinWithJavaTarget<*> || target.platformType != KotlinPlatformType.common)) {
|
||||||
(target !is KotlinWithJavaTarget<*> || target.platformType != KotlinPlatformType.common)
|
|
||||||
) {
|
|
||||||
usesPlatformOf(target)
|
usesPlatformOf(target)
|
||||||
attributes.attribute(ProjectLocalConfigurations.ATTRIBUTE, ProjectLocalConfigurations.LOCAL_TO_PROJECT_PREFIX + target.project.path)
|
attributes.attribute(ProjectLocalConfigurations.ATTRIBUTE, ProjectLocalConfigurations.LOCAL_TO_PROJECT_PREFIX + target.project.path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Configuration.setupAsPublicConfigurationIfSupported(target: KotlinTarget) {
|
internal fun Configuration.setupAsPublicConfigurationIfSupported(target: KotlinTarget) {
|
||||||
if (gradleVersionSupportsAttributeRules &&
|
if ((target !is KotlinWithJavaTarget<*> || target.platformType != KotlinPlatformType.common)) {
|
||||||
(target !is KotlinWithJavaTarget<*> || target.platformType != KotlinPlatformType.common)
|
|
||||||
) {
|
|
||||||
attributes.attribute(ProjectLocalConfigurations.ATTRIBUTE, ProjectLocalConfigurations.PUBLIC_VALUE)
|
attributes.attribute(ProjectLocalConfigurations.ATTRIBUTE, ProjectLocalConfigurations.PUBLIC_VALUE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val gradleVersionSupportsAttributeRules = isGradleVersionAtLeast(4, 0)
|
|
||||||
+3
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.*
|
import org.jetbrains.kotlin.gradle.plugin.*
|
||||||
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
import org.jetbrains.kotlin.gradle.plugin.sources.DefaultLanguageSettingsBuilder
|
||||||
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
import org.jetbrains.kotlin.gradle.utils.SingleWarningPerBuild
|
||||||
|
import org.jetbrains.kotlin.gradle.utils.checkGradleCompatibility
|
||||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||||
import org.jetbrains.kotlin.konan.target.HostManager
|
import org.jetbrains.kotlin.konan.target.HostManager
|
||||||
import org.jetbrains.kotlin.konan.target.presetName
|
import org.jetbrains.kotlin.konan.target.presetName
|
||||||
@@ -59,6 +60,8 @@ class KotlinMultiplatformPlugin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
|
checkGradleCompatibility()
|
||||||
|
|
||||||
project.plugins.apply(JavaBasePlugin::class.java)
|
project.plugins.apply(JavaBasePlugin::class.java)
|
||||||
SingleWarningPerBuild.show(project, "Kotlin Multiplatform Projects are an experimental feature.")
|
SingleWarningPerBuild.show(project, "Kotlin Multiplatform Projects are an experimental feature.")
|
||||||
|
|
||||||
|
|||||||
+3
-5
@@ -97,11 +97,9 @@ object KotlinUsages {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun setupAttributesMatchingStrategy(attributesSchema: AttributesSchema) {
|
internal fun setupAttributesMatchingStrategy(attributesSchema: AttributesSchema) {
|
||||||
if (isGradleVersionAtLeast(4, 0)) {
|
attributesSchema.attribute(Usage.USAGE_ATTRIBUTE) { strategy ->
|
||||||
attributesSchema.attribute(Usage.USAGE_ATTRIBUTE) { strategy ->
|
strategy.compatibilityRules.add(KotlinJavaRuntimeJarsCompatibility::class.java)
|
||||||
strategy.compatibilityRules.add(KotlinJavaRuntimeJarsCompatibility::class.java)
|
strategy.disambiguationRules.add(KotlinUsagesDisambiguation::class.java)
|
||||||
strategy.disambiguationRules.add(KotlinUsagesDisambiguation::class.java)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-7
@@ -9,7 +9,6 @@ import org.gradle.api.Project
|
|||||||
import org.gradle.api.file.ConfigurableFileCollection
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilationOutput
|
||||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.Callable
|
import java.util.concurrent.Callable
|
||||||
|
|
||||||
@@ -48,12 +47,7 @@ class KotlinWithJavaCompilationOutput(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val classesDirs: ConfigurableFileCollection =
|
override val classesDirs: ConfigurableFileCollection =
|
||||||
if (isGradleVersionAtLeast(4, 0))
|
javaSourceSetOutput.classesDirs as ConfigurableFileCollection
|
||||||
javaSourceSetOutput.classesDirs as ConfigurableFileCollection
|
|
||||||
else
|
|
||||||
// In Gradle < 4.0 `SourceSetOutput` does not have `classesDirs`
|
|
||||||
@Suppress("DEPRECATION")
|
|
||||||
compilation.target.project.files(Callable { javaSourceSetOutput.classesDir })
|
|
||||||
|
|
||||||
override val allOutputs: FileCollection
|
override val allOutputs: FileCollection
|
||||||
get() = javaSourceSetOutput
|
get() = javaSourceSetOutput
|
||||||
|
|||||||
+2
-9
@@ -10,8 +10,6 @@ import org.gradle.api.file.FileCollection
|
|||||||
import org.gradle.api.plugins.JavaPluginConvention
|
import org.gradle.api.plugins.JavaPluginConvention
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.jetbrains.kotlin.gradle.utils.isClassFile
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.isGradleVersionAtLeast
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
internal open class InspectClassesForMultiModuleIC : DefaultTask() {
|
internal open class InspectClassesForMultiModuleIC : DefaultTask() {
|
||||||
@@ -33,13 +31,8 @@ internal open class InspectClassesForMultiModuleIC : DefaultTask() {
|
|||||||
val convention = project.convention.findPlugin(JavaPluginConvention::class.java)
|
val convention = project.convention.findPlugin(JavaPluginConvention::class.java)
|
||||||
val sourceSet = convention?.sourceSets?.findByName(sourceSetName) ?: return project.files()
|
val sourceSet = convention?.sourceSets?.findByName(sourceSetName) ?: return project.files()
|
||||||
|
|
||||||
return if (isGradleVersionAtLeast(4, 0)) {
|
val fileTrees = sourceSet.output.classesDirs.map { project.fileTree(it).include("**/*.class") }
|
||||||
val fileTrees = sourceSet.output.classesDirs.map { project.fileTree(it).include("**/*.class") }
|
return project.files(fileTrees)
|
||||||
project.files(fileTrees)
|
|
||||||
} else {
|
|
||||||
sourceSet.output.asFileTree.filter { it.isClassFile() }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
|
|||||||
-216
@@ -1,216 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.tasks
|
|
||||||
|
|
||||||
import org.gradle.api.DefaultTask
|
|
||||||
import org.gradle.api.tasks.*
|
|
||||||
import org.gradle.api.tasks.incremental.IncrementalTaskInputs
|
|
||||||
import org.gradle.api.tasks.incremental.InputFileDetails
|
|
||||||
import org.jetbrains.kotlin.gradle.logging.kotlinDebug
|
|
||||||
import org.jetbrains.kotlin.gradle.utils.isParentOf
|
|
||||||
import java.io.File
|
|
||||||
import java.io.ObjectInputStream
|
|
||||||
import java.io.ObjectOutputStream
|
|
||||||
import java.util.*
|
|
||||||
import kotlin.properties.Delegates
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copies kotlin classes to java output directory.
|
|
||||||
* No other way to get our classes into apk for android until API is provided https://code.google.com/p/android/issues/detail?id=200714
|
|
||||||
*
|
|
||||||
* Utilises gradle for tracking input/output changes.
|
|
||||||
* 0. Gradle takes snapshots of annotated properties after compilation.
|
|
||||||
* 1. kotlinOutputDir as input files. These files will be copied.
|
|
||||||
* Copying will be done incrementally unless output classes are wiped out
|
|
||||||
* (by IncrementalJavaCompilationSafeguard task from android gradle plugin for example).
|
|
||||||
* 2. kotlinClassesInJavaOutputDir as output files -- copied classes in java output dir.
|
|
||||||
* When they are changed or removed gradle tells us that incremental build is not possible (inputs.isIncremental is false).
|
|
||||||
* 3. We do non-incremental sync in the following way:
|
|
||||||
* a. previously copied files are deleted (to do so we save the list of copied files after copying);
|
|
||||||
* b. all kotlin files are copied to java output dir.
|
|
||||||
*
|
|
||||||
* It is possible that some file was converted from kotlin to java.
|
|
||||||
* In this case gradle will tell us to make non-incremental sync.
|
|
||||||
* To workaround this scenario we also save timestamp of copied class.
|
|
||||||
* On step (a) of sync process we do not delete the class in java output dir
|
|
||||||
* if it's timestamp now is newer than when we copied it
|
|
||||||
* (assuming it was modified by javac when class was converted to java).
|
|
||||||
*/
|
|
||||||
internal open class SyncOutputTask : DefaultTask() {
|
|
||||||
@get:InputFiles
|
|
||||||
var kotlinOutputDir: File by Delegates.notNull()
|
|
||||||
|
|
||||||
@get:InputFiles
|
|
||||||
var kaptClassesDir: File by Delegates.notNull()
|
|
||||||
|
|
||||||
// Marked as input to make Gradle fall back to non-incremental build when it changes.
|
|
||||||
@get:Input
|
|
||||||
protected val classesDirs: List<File>
|
|
||||||
get() = listOf(kotlinOutputDir, kaptClassesDir).filter(File::exists)
|
|
||||||
|
|
||||||
@get:OutputDirectory
|
|
||||||
var javaOutputDir: File by Delegates.notNull()
|
|
||||||
|
|
||||||
@get:Internal
|
|
||||||
var kotlinTask: KotlinCompile by Delegates.notNull()
|
|
||||||
|
|
||||||
// OutputDirectory needed for task to be incremental
|
|
||||||
@get:OutputDirectory
|
|
||||||
val workingDir: File by lazy {
|
|
||||||
File(kotlinTask.taskBuildDirectory, "sync")
|
|
||||||
}
|
|
||||||
|
|
||||||
private val timestampsFile: File by lazy {
|
|
||||||
File(workingDir, TIMESTAMP_FILE_NAME)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val timestamps: MutableMap<File, Long> by lazy {
|
|
||||||
readTimestamps(timestampsFile, javaOutputDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
init {
|
|
||||||
outputs.upToDateWhen {
|
|
||||||
for ((file, ts) in timestamps) {
|
|
||||||
if (!file.exists()) {
|
|
||||||
logger.kotlinDebug { "$file does not exist" }
|
|
||||||
return@upToDateWhen false
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.lastModified() != ts) {
|
|
||||||
logger.kotlinDebug { "$file ts is different" }
|
|
||||||
return@upToDateWhen false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return@upToDateWhen true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
@TaskAction
|
|
||||||
fun execute(inputs: IncrementalTaskInputs): Unit {
|
|
||||||
val sourceDirs = classesDirs.joinToString()
|
|
||||||
if (inputs.isIncremental) {
|
|
||||||
logger.kotlinDebug { "Incremental copying files from $sourceDirs to $javaOutputDir" }
|
|
||||||
inputs.outOfDate { processIncrementally(it) }
|
|
||||||
inputs.removed { processIncrementally(it) }
|
|
||||||
} else {
|
|
||||||
logger.kotlinDebug { "Non-incremental copying files from $sourceDirs to $javaOutputDir" }
|
|
||||||
processNonIncrementally()
|
|
||||||
}
|
|
||||||
|
|
||||||
saveTimestamps(timestampsFile, timestamps, javaOutputDir)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processNonIncrementally() {
|
|
||||||
for ((file, timestamp) in timestamps) {
|
|
||||||
// wipe all files written by us
|
|
||||||
// do not remove files converted to java (newer timestamp)
|
|
||||||
if (file.lastModified() == timestamp) {
|
|
||||||
file.delete()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
timestampsFile.delete()
|
|
||||||
timestamps.clear()
|
|
||||||
|
|
||||||
for (dir in classesDirs) {
|
|
||||||
dir.walkTopDown().forEach {
|
|
||||||
copy(it, it.siblingInJavaDir(baseDir = dir))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun processIncrementally(input: InputFileDetails) {
|
|
||||||
val fileInKotlinDir = input.file
|
|
||||||
val fileInJavaDir = fileInKotlinDir.siblingInJavaDir()
|
|
||||||
|
|
||||||
if (input.isRemoved) {
|
|
||||||
// file was removed in kotlin dir, remove from java as well
|
|
||||||
remove(fileInJavaDir)
|
|
||||||
} else {
|
|
||||||
// copy modified or added file from kotlin to java
|
|
||||||
copy(fileInKotlinDir, fileInJavaDir)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun remove(fileInJavaDir: File) {
|
|
||||||
if (!fileInJavaDir.isFile) return
|
|
||||||
|
|
||||||
fileInJavaDir.delete()
|
|
||||||
timestamps.remove(fileInJavaDir)
|
|
||||||
|
|
||||||
logger.kotlinDebug {
|
|
||||||
"Removed kotlin class ${fileInJavaDir.relativeTo(javaOutputDir).path} from $javaOutputDir"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun copy(fileInKotlinDir: File, fileInJavaDir: File) {
|
|
||||||
if (!fileInKotlinDir.isFile) return
|
|
||||||
|
|
||||||
fileInJavaDir.parentFile.mkdirs()
|
|
||||||
fileInKotlinDir.copyTo(fileInJavaDir, overwrite = true)
|
|
||||||
|
|
||||||
timestamps[fileInJavaDir] = fileInJavaDir.lastModified()
|
|
||||||
|
|
||||||
logger.kotlinDebug {
|
|
||||||
"Copied kotlin class ${fileInKotlinDir.relativeTo(kotlinOutputDir).path} from $kotlinOutputDir to $javaOutputDir"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun File.siblingInJavaDir(baseDir: File? = null): File {
|
|
||||||
val base = baseDir ?: classesDirs.find { it.isParentOf(this, strict = true) }!!
|
|
||||||
return File(javaOutputDir, this.relativeTo(base).path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val TIMESTAMP_FILE_NAME = "kotlin-files-in-java-timestamps.bin"
|
|
||||||
|
|
||||||
private fun readTimestamps(tsFile: File, filesBaseDir: File): MutableMap<File, Long> {
|
|
||||||
val result = HashMap<File, Long>()
|
|
||||||
if (!tsFile.isFile) return result
|
|
||||||
|
|
||||||
ObjectInputStream(tsFile.inputStream()).use { input ->
|
|
||||||
val size = input.readInt()
|
|
||||||
|
|
||||||
repeat(size) {
|
|
||||||
val path = input.readUTF()
|
|
||||||
val timestamp = input.readLong()
|
|
||||||
result[File(filesBaseDir, path)] = timestamp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun saveTimestamps(snapshotFile: File, timestamps: Map<File, Long>, filesBaseDir: File) {
|
|
||||||
if (!snapshotFile.exists()) {
|
|
||||||
snapshotFile.parentFile.mkdirs()
|
|
||||||
snapshotFile.createNewFile()
|
|
||||||
} else {
|
|
||||||
snapshotFile.delete()
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectOutputStream(snapshotFile.outputStream()).use { out ->
|
|
||||||
out.writeInt(timestamps.size)
|
|
||||||
|
|
||||||
for ((file, timestamp) in timestamps) {
|
|
||||||
out.writeUTF(file.relativeTo(filesBaseDir).path)
|
|
||||||
out.writeLong(timestamp)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+12
@@ -16,10 +16,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.gradle.utils
|
package org.jetbrains.kotlin.gradle.utils
|
||||||
|
|
||||||
|
import org.gradle.api.GradleException
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.tasks.SourceSetOutput
|
import org.gradle.api.tasks.SourceSetOutput
|
||||||
import org.gradle.api.tasks.TaskInputs
|
import org.gradle.api.tasks.TaskInputs
|
||||||
import org.gradle.api.tasks.TaskOutputs
|
import org.gradle.api.tasks.TaskOutputs
|
||||||
|
import org.gradle.util.GradleVersion
|
||||||
|
|
||||||
internal val Task.inputsCompatible: TaskInputs get() = inputs
|
internal val Task.inputsCompatible: TaskInputs get() = inputs
|
||||||
|
|
||||||
@@ -93,4 +95,14 @@ private val setClassesDirMethod by lazy {
|
|||||||
|
|
||||||
internal fun SourceSetOutput.setClassesDirCompatible(dirPath: Any) {
|
internal fun SourceSetOutput.setClassesDirCompatible(dirPath: Any) {
|
||||||
setClassesDirMethod(this, dirPath)
|
setClassesDirMethod(this, dirPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun checkGradleCompatibility(minSupportedVersion: GradleVersion = GradleVersion.version("4.0")) {
|
||||||
|
val currentVersion = GradleVersion.current()
|
||||||
|
if (currentVersion < minSupportedVersion) {
|
||||||
|
throw GradleException(
|
||||||
|
"Current version of Gradle $currentVersion is not compatible with Kotlin plugin. " +
|
||||||
|
"Please use Gradle $minSupportedVersion or newer or previous version of Kotlin plugin."
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user