Provide an opt-out flag for separate classes dirs with Gradle 4.0+
Issue #KT-19774 Fixed (cherry picked from commit 2aa6f5a)
This commit is contained in:
+11
-2
@@ -18,9 +18,10 @@ package org.jetbrains.kotlin.gradle.dsl
|
||||
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.plugins.DslObject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
internal fun Project.createKotlinExtension() {
|
||||
val kotlinExt = extensions.create("kotlin", KotlinProjectExtension::class.java)
|
||||
internal fun Project.createKotlinExtension(extensionClass: KClass<out KotlinProjectExtension>) {
|
||||
val kotlinExt = extensions.create("kotlin", extensionClass.java)
|
||||
DslObject(kotlinExt).extensions.create("experimental", ExperimentalExtension::class.java)
|
||||
}
|
||||
|
||||
@@ -29,6 +30,14 @@ open class KotlinProjectExtension {
|
||||
get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java)!!
|
||||
}
|
||||
|
||||
open class KotlinJvmProjectExtension : KotlinProjectExtension() {
|
||||
/**
|
||||
* 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 {
|
||||
var coroutines: Coroutines? = null
|
||||
}
|
||||
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
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.utils.ParsedGradleVersion
|
||||
import java.util.*
|
||||
|
||||
object CopyClassesToJavaOutputStatus {
|
||||
fun isEnabled(project: Project): Boolean {
|
||||
val kotlinJvmExt = project.kotlinJvmExt ?: return false
|
||||
if (kotlinJvmExt.copyClassesToJavaOutput) {
|
||||
if (isGradleVersionTooLow(project) && warningReportedForProject.add(project)) {
|
||||
project.logger.kotlinWarn(gradleVersionTooLowWarningMessage)
|
||||
}
|
||||
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)
|
||||
}
|
||||
+4
-2
@@ -55,8 +55,10 @@ internal abstract class KotlinSourceSetProcessor<T : AbstractKotlinCompile<*>>(
|
||||
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 isSeparateClassesDirSupported: Boolean by lazy {
|
||||
!CopyClassesToJavaOutputStatus.isEnabled(project) &&
|
||||
sourceSet.output.javaClass.methods.any { it.name == "getClassesDirs" }
|
||||
}
|
||||
|
||||
protected val sourceSetName: String = sourceSet.name
|
||||
protected val sourceRootDir: String = "src/$sourceSetName/kotlin"
|
||||
|
||||
+12
-4
@@ -19,17 +19,20 @@ package org.jetbrains.kotlin.gradle.plugin
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.file.FileResolver
|
||||
import org.gradle.api.internal.plugins.DslObject
|
||||
import org.gradle.api.logging.Logger
|
||||
import org.gradle.api.logging.Logging
|
||||
import org.jetbrains.kotlin.gradle.dsl.ExperimentalExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
|
||||
import org.jetbrains.kotlin.gradle.dsl.createKotlinExtension
|
||||
import org.jetbrains.kotlin.gradle.internal.KotlinSourceSetProviderImpl
|
||||
import org.jetbrains.kotlin.gradle.tasks.*
|
||||
import org.jetbrains.kotlin.gradle.tasks.AndroidTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCommonTasksProvider
|
||||
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
|
||||
import java.io.FileNotFoundException
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver): Plugin<Project> {
|
||||
private val log = Logging.getLogger(this.javaClass)
|
||||
@@ -40,18 +43,23 @@ abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver)
|
||||
System.setProperty(org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true")
|
||||
val kotlinGradleBuildServices = KotlinGradleBuildServices.getInstance(project.gradle)
|
||||
|
||||
project.createKotlinExtension()
|
||||
project.createKotlinExtension(projectExtensionClass)
|
||||
|
||||
val plugin = getPlugin(kotlinGradleBuildServices)
|
||||
plugin.apply(project)
|
||||
}
|
||||
|
||||
internal abstract fun getPlugin(kotlinGradleBuildServices: KotlinGradleBuildServices): Plugin<Project>
|
||||
|
||||
open val projectExtensionClass: KClass<out KotlinProjectExtension> get() = KotlinProjectExtension::class
|
||||
}
|
||||
|
||||
open class KotlinPluginWrapper @Inject constructor(fileResolver: FileResolver): KotlinBasePluginWrapper(fileResolver) {
|
||||
override fun getPlugin(kotlinGradleBuildServices: KotlinGradleBuildServices) =
|
||||
KotlinPlugin(KotlinTasksProvider(), KotlinSourceSetProviderImpl(fileResolver), kotlinPluginVersion, kotlinGradleBuildServices)
|
||||
|
||||
override val projectExtensionClass: KClass<out KotlinJvmProjectExtension>
|
||||
get() = KotlinJvmProjectExtension::class
|
||||
}
|
||||
|
||||
open class KotlinCommonPluginWrapper @Inject constructor(fileResolver: FileResolver): KotlinBasePluginWrapper(fileResolver) {
|
||||
|
||||
Reference in New Issue
Block a user