From 10396ecc84075e6fcf9796f67738ecc71e16d62b Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Wed, 6 Apr 2016 16:08:49 +0300 Subject: [PATCH] Refactoring: extract properties for gradle task's properties access in plugin --- .../internal/AnnotationProcessingManager.kt | 7 ++-- .../kotlin/gradle/plugin/KotlinPlugin.kt | 35 ++++++++----------- .../kotlin/gradle/plugin/taskUtils.kt | 29 +++++++++++++++ 3 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/taskUtils.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt index 2bfb497d15d..58e573ee3ee 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/AnnotationProcessingManager.kt @@ -32,7 +32,6 @@ fun Project.initKapt( javaTask: AbstractCompile, kaptManager: AnnotationProcessingManager, variantName: String, - kotlinOutputDir: File, kotlinOptions: Any?, subpluginEnvironment: SubpluginEnvironment, taskFactory: (suffix: String) -> AbstractCompile @@ -41,8 +40,7 @@ fun Project.initKapt( val kotlinAfterJavaTask: AbstractCompile? if (kaptExtension.generateStubs) { - kotlinAfterJavaTask = createKotlinAfterJavaTask(javaTask, kotlinTask, - kotlinOutputDir, kotlinOptions, taskFactory) + kotlinAfterJavaTask = createKotlinAfterJavaTask(javaTask, kotlinTask, kotlinOptions, taskFactory) kotlinTask.logger.kotlinDebug("kapt: Using class file stubs") @@ -89,12 +87,11 @@ fun Project.initKapt( private fun Project.createKotlinAfterJavaTask( javaTask: AbstractCompile, kotlinTask: AbstractCompile, - kotlinOutputDir: File, kotlinOptions: Any?, taskFactory: (suffix: String) -> AbstractCompile ): AbstractCompile { val kotlinAfterJavaTask = with (taskFactory(KOTLIN_AFTER_JAVA_TASK_SUFFIX)) { - setProperty("kotlinDestinationDir", kotlinOutputDir) + kotlinDestinationDir = kotlinTask.kotlinDestinationDir destinationDir = javaTask.destinationDir classpath = javaTask.classpath this 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 c79f2087450..79bbb80f5d4 100644 --- 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 @@ -130,9 +130,7 @@ class Kotlin2JvmSourceSetProcessor( } override fun doTargetSpecificProcessing() { - // store kotlin classes in separate directory. They will serve as class-path to java compiler - val kotlinDestinationDir = File(project.buildDir, "kotlin-classes/${sourceSetName}") - kotlinTask.setProperty("kotlinDestinationDir", kotlinDestinationDir) + kotlinTask.kotlinDestinationDir = File(project.buildDir, "kotlin-classes/$sourceSetName") val javaTask = project.tasks.findByName(sourceSet.compileJavaTaskName) as AbstractCompile? if (javaTask != null) { @@ -166,7 +164,7 @@ class Kotlin2JvmSourceSetProcessor( aptConfiguration.resolve(), aptOutputDir, aptWorkingDir, tasksProvider.tasksLoader) val kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager, - sourceSetName, kotlinDestinationDir, null, subpluginEnvironment) { + sourceSetName, null, subpluginEnvironment) { createKotlinCompileTask(it) } @@ -200,7 +198,7 @@ class Kotlin2JsSourceSetProcessor( val build = project.tasks.findByName("build") val defaultKotlinDestinationDir = File(project.buildDir, "kotlin2js/${sourceSetName}") - private fun kotlinTaskDestinationDir(): File? = kotlinTask.property("kotlinDestinationDir") as File? + private fun kotlinTaskDestinationDir(): File? = kotlinTask.kotlinDestinationDir private fun kotlinJsDestinationDir(): File? = (kotlinTask.property("outputFile") as String).let { File(it) }.let { if (it.isDirectory) it else it.parentFile } private fun kotlinSourcePathsForSourceMap() = sourceSet.getAllSource() @@ -211,7 +209,7 @@ class Kotlin2JsSourceSetProcessor( private fun shouldGenerateSourceMap() = kotlinTask.property("sourceMap") override fun doTargetSpecificProcessing() { - kotlinTask.setProperty("kotlinDestinationDir", defaultKotlinDestinationDir) + kotlinTask.kotlinDestinationDir = defaultKotlinDestinationDir build?.dependsOn(kotlinTaskName) clean?.dependsOn("clean" + kotlinTaskName.capitalize()) @@ -366,8 +364,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand } // store kotlin classes in separate directory. They will serve as class-path to java compiler - val kotlinOutputDir = File(project.buildDir, "tmp/kotlin-classes/${variantDataName}") - kotlinTask.setProperty("kotlinDestinationDir", kotlinOutputDir) + kotlinTask.kotlinDestinationDir = File(project.buildDir, "tmp/kotlin-classes/$variantDataName") kotlinTask.destinationDir = javaTask.destinationDir kotlinTask.description = "Compiles the ${variantDataName} kotlin." kotlinTask.classpath = javaTask.classpath @@ -413,7 +410,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand kotlinTask.doFirst { val androidRT = project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt)) - val fullClasspath = (javaTask.classpath + androidRT) - project.files(kotlinTask.property("kotlinDestinationDir")) + val fullClasspath = (javaTask.classpath + androidRT) - project.files(kotlinTask.kotlinDestinationDir) (it as AbstractCompile).classpath = fullClasspath for (task in project.getTasksByName(kotlinTaskName + KOTLIN_AFTER_JAVA_TASK_SUFFIX, false)) { @@ -430,8 +427,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand kotlinTask.storeKaptAnnotationsFile(kaptManager) - project.initKapt(kotlinTask, javaTask, kaptManager, variantDataName, - kotlinOutputDir, kotlinOptions, subpluginEnvironment) { + project.initKapt(kotlinTask, javaTask, kaptManager, variantDataName, kotlinOptions, subpluginEnvironment) { tasksProvider.createKotlinJVMTask(project, kotlinTaskName + KOTLIN_AFTER_JAVA_TASK_SUFFIX) } } @@ -456,16 +452,15 @@ private fun setUpKotlinToJavaDependency(project: Project, kotlinTask: AbstractCo // Since we cannot update classpath statically, java not able to detect changes in the classpath after kotlin compiler. // Therefore this (probably inefficient since java cannot decide "uptodateness" by the list of changed class files, but told // explicitly being out of date whenever any kotlin files are compiled - if (kotlinTask.hasProperty("anyClassesCompiled")) { - kotlinTask.property("anyClassesCompiled")?.let { - kotlinTask.setProperty("anyClassesCompiled", false) - javaTask.outputs.upToDateWhen { task -> - val kotlinClassesCompiled = kotlinTask.property("anyClassesCompiled") as? Boolean ?: false - if (kotlinClassesCompiled) { - logger.info("Marking $task out of date, because kotlin classes are changed") - } - !kotlinClassesCompiled + if (kotlinTask.anyClassesCompiled != null) { + kotlinTask.anyClassesCompiled = false + + javaTask.outputs.upToDateWhen { task -> + val kotlinClassesCompiled = kotlinTask.anyClassesCompiled ?: false + if (kotlinClassesCompiled) { + logger.info("Marking $task out of date, because kotlin classes are changed") } + !kotlinClassesCompiled } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/taskUtils.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/taskUtils.kt new file mode 100644 index 00000000000..c37aa8ea3a0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/taskUtils.kt @@ -0,0 +1,29 @@ +package org.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.internal.AbstractTask +import org.gradle.api.tasks.compile.AbstractCompile +import java.io.File +import kotlin.reflect.KProperty + +internal var AbstractTask.anyClassesCompiled: Boolean? by TaskPropertyDelegate("anyClassesCompiled") +internal var AbstractTask.kotlinDestinationDir: File? by TaskPropertyDelegate("kotlinDestinationDir") + +inline +internal fun TaskPropertyDelegate(propertyName: String) = + TaskPropertyDelegate(propertyName, T::class.java) + +internal class TaskPropertyDelegate(private val propertyName: String, private val klass: Class) { + operator fun getValue(task: Any?, property: KProperty<*>): T? { + if (task !is AbstractCompile) throw IllegalStateException("TaskPropertyDelegate could extend only AbstractCompile") + + if ( !task.hasProperty(propertyName)) return null + + return task.property(propertyName)?.let { klass.cast(it) } + } + + operator fun setValue(task: Any?, property: KProperty<*>, value: T?) { + if (task !is AbstractCompile) throw IllegalStateException("TaskPropertyDelegate could extend only AbstractCompile") + + task.setProperty(propertyName, value) + } +} \ No newline at end of file