From 700b162233a97ce279d9d4fa3b2e54ff38b4b16a Mon Sep 17 00:00:00 2001 From: Sergey Igushkin Date: Sun, 25 Jun 2017 21:45:55 +0300 Subject: [PATCH] Implemented separate classes dirs support in the Gradle plugins. Issue #KT-18495 Fixed Issue #KT-18544 Fixed (cherry picked from commit e25f0fd) --- .../kotlin/gradle/plugin/KotlinPlugin.kt | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt index 5054e115b71..bd4af82fab2 100755 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt @@ -10,6 +10,8 @@ import org.gradle.api.InvalidUserDataException import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.FileCollection import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging import org.gradle.api.plugins.InvalidPluginException @@ -18,10 +20,12 @@ import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPluginConvention import org.gradle.api.tasks.Delete import org.gradle.api.tasks.SourceSet +import org.gradle.api.tasks.SourceSetOutput import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.JavaCompile import org.jetbrains.kotlin.com.intellij.openapi.util.io.FileUtil import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtil.compareVersionNumbers +import org.jetbrains.kotlin.com.intellij.util.ReflectionUtil import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptionsImpl import org.jetbrains.kotlin.gradle.internal.* import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.getKaptClasssesDir @@ -31,6 +35,7 @@ import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilat import java.io.File import java.net.URL import java.util.* +import java.util.concurrent.Callable import java.util.jar.Manifest val KOTLIN_AFTER_JAVA_TASK_SUFFIX = "AfterJava" @@ -51,12 +56,18 @@ internal abstract class KotlinSourceSetProcessor>( abstract protected fun doTargetSpecificProcessing() protected val logger = Logging.getLogger(this.javaClass)!! + protected val isSeparateClassesDirSupported: Boolean = + sourceSet.output.javaClass.methods.any { it.name == "getClassesDirs" } + protected val sourceSetName: String = sourceSet.name protected val sourceRootDir: String = "src/$sourceSetName/kotlin" protected val kotlinSourceSet: KotlinSourceSet = createKotlinSourceSet() protected val kotlinTask: T = createKotlinCompileTask() + protected open val defaultKotlinDestinationDir: File - get() = sourceSet.output.classesDir + get() = if (isSeparateClassesDirSupported) + File(project.buildDir, "classes/kotlin/${sourceSet.name}") else + sourceSet.output.classesDir fun run() { addKotlinDirSetToSources() @@ -85,6 +96,7 @@ internal abstract class KotlinSourceSetProcessor>( kotlinCompile.description = taskDescription kotlinCompile.mapClasspath { sourceSet.compileClasspath } kotlinCompile.destinationDir = defaultKotlinDestinationDir + sourceSet.output.tryAddClassesDir { project.files(kotlinTask.destinationDir).builtBy(kotlinTask) } return kotlinCompile } @@ -106,7 +118,9 @@ internal class Kotlin2JvmSourceSetProcessor( taskDescription = "Compiles the $sourceSet.kotlin." ) { override val defaultKotlinDestinationDir: File - get() = File(project.buildDir, "kotlin-classes/$sourceSetName") + get() = if (!isSeparateClassesDirSupported) + File(project.buildDir, "kotlin-classes/$sourceSetName") else + super.defaultKotlinDestinationDir override fun doCreateTask(project: Project, taskName: String): KotlinCompile = tasksProvider.createKotlinJVMTask(project, taskName, sourceSet.name) @@ -149,7 +163,11 @@ internal class Kotlin2JvmSourceSetProcessor( .forEach { it.source(kotlinSourceSet.kotlin) } configureJavaTask(kotlinTask, javaTask, logger) - createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, sourceSetName) + + if (!isSeparateClassesDirSupported) { + createSyncOutputTask(project, kotlinTask, javaTask, kotlinAfterJavaTask, sourceSetName) + } + val artifactFile = project.tryGetSingleArtifact() configureMultiProjectIncrementalCompilation(project, kotlinTask, javaTask, kotlinAfterJavaTask, kotlinGradleBuildServices.artifactDifferenceRegistryProvider, @@ -175,6 +193,21 @@ internal class Kotlin2JvmSourceSetProcessor( } } +private fun SourceSetOutput.tryAddClassesDir( + classesDirProvider: () -> FileCollection +): Boolean { + val getClassesDirs = ReflectionUtil.findMethod( + javaClass.methods.asList(), + "getClassesDirs" + ) ?: return false + + val classesDirs = getClassesDirs(this) as? ConfigurableFileCollection + ?: return false + + classesDirs.from(Callable { classesDirProvider() }) + return true +} + internal class Kotlin2JsSourceSetProcessor( project: Project, javaBasePlugin: JavaBasePlugin, @@ -187,7 +220,6 @@ internal class Kotlin2JsSourceSetProcessor( taskDescription = "Compiles the kotlin sources in $sourceSet to JavaScript.", compileTaskNameSuffix = "kotlin2Js" ) { - override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile = tasksProvider.createKotlinJSTask(project, taskName, sourceSet.name) @@ -208,8 +240,11 @@ internal class Kotlin2JsSourceSetProcessor( "Gradle will not be able to build the project because of the root directory lock.\n" + "To fix this, consider using the default outputFile location instead of providing it explicitly.") - sourceSet.output.setClassesDir(outputDir) kotlinTask.destinationDir = outputDir + + if (!isSeparateClassesDirSupported) { + sourceSet.output.setClassesDir(kotlinTask.destinationDir) + } } } @@ -247,9 +282,6 @@ internal class KotlinCommonSourceSetProcessor( } } - override val defaultKotlinDestinationDir: File - get() = sourceSet.output.classesDir - override fun doCreateTask(project: Project, taskName: String): KotlinCompileCommon = tasksProvider.createKotlinCommonTask(project, taskName, sourceSet.name) }