Move AnnotationProcessingManager to main kotlin-gradle-plugin

This commit is contained in:
Yan Zhulanow
2015-05-21 01:51:14 +03:00
parent 6de79f46e4
commit 89d3a4b623
3 changed files with 49 additions and 51 deletions
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.utils.LibraryUtils
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import org.apache.commons.io.FilenameUtils import org.apache.commons.io.FilenameUtils
import org.gradle.api.file.FileCollection import org.gradle.api.file.FileCollection
import org.gradle.api.plugins.ExtraPropertiesExtension
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.org.objectweb.asm.ClassWriter import org.jetbrains.org.objectweb.asm.ClassWriter
import java.io.IOException import java.io.IOException
@@ -105,14 +106,8 @@ public open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments
override val compiler = K2JVMCompiler() override val compiler = K2JVMCompiler()
override fun createBlankArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments() override fun createBlankArgs(): K2JVMCompilerArguments = K2JVMCompilerArguments()
public var aptFiles: Set<File> = emptySet()
public var kotlinAptOutputDir: File? = null
public var kotlinAptWorkingDir: File? = null
val srcDirsSources = HashSet<SourceDirectorySet>() val srcDirsSources = HashSet<SourceDirectorySet>()
val annotationProcessingManager = AnnotationProcessingManager(this)
override fun populateTargetSpecificArgs(args: K2JVMCompilerArguments) { override fun populateTargetSpecificArgs(args: K2JVMCompilerArguments) {
// show kotlin compiler where to look for java source files // show kotlin compiler where to look for java source files
args.freeArgs = (args.freeArgs + getJavaSourceRoots().map { it.getAbsolutePath() }).toSet().toList() args.freeArgs = (args.freeArgs + getJavaSourceRoots().map { it.getAbsolutePath() }).toSet().toList()
@@ -133,10 +128,10 @@ public open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments
val pluginOptions = arrayListOf(*basePluginOptions) val pluginOptions = arrayListOf(*basePluginOptions)
if (aptFiles.isNotEmpty()) { val kaptAnnotationsFile = extraProperties.getOrNull<File>("kaptAnnotationsFile")
val annotationDeclarationsFile = annotationProcessingManager.getAnnotationFile() if (kaptAnnotationsFile != null) {
if (annotationDeclarationsFile.exists()) annotationDeclarationsFile.delete() if (kaptAnnotationsFile.exists()) kaptAnnotationsFile.delete()
pluginOptions.add("plugin:$ANNOTATIONS_PLUGIN_NAME:output=" + annotationDeclarationsFile) pluginOptions.add("plugin:$ANNOTATIONS_PLUGIN_NAME:output=" + kaptAnnotationsFile)
} }
args.pluginOptions = pluginOptions.toTypedArray() args.pluginOptions = pluginOptions.toTypedArray()
@@ -173,8 +168,6 @@ public open class KotlinCompile() : AbstractKotlinCompile<K2JVMCompilerArguments
if (outputDirFile.exists()) { if (outputDirFile.exists()) {
FileUtils.copyDirectory(outputDirFile, getDestinationDir()) FileUtils.copyDirectory(outputDirFile, getDestinationDir())
} }
annotationProcessingManager.afterKotlinCompile()
} }
// override setSource to track source directory sets // override setSource to track source directory sets
@@ -335,6 +328,14 @@ public open class KDoc() : SourceTask() {
} }
} }
private inline fun <reified T: Any> ExtraPropertiesExtension.getOrNull(id: String): T? {
try {
return get(id) as T
} catch (e: ExtraPropertiesExtension.UnknownPropertyException) {
return null
}
}
fun getAnnotations(project: Project, logger: Logger): Collection<File> { fun getAnnotations(project: Project, logger: Logger): Collection<File> {
[suppress("UNCHECKED_CAST")] [suppress("UNCHECKED_CAST")]
val annotations = project.getExtensions().getByName(DEFAULT_ANNOTATIONS) as Collection<File> val annotations = project.getExtensions().getByName(DEFAULT_ANNOTATIONS) as Collection<File>
@@ -14,20 +14,24 @@
* limitations under the License. * limitations under the License.
*/ */
package org.jetbrains.kotlin.gradle.tasks package org.jetbrains.kotlin.gradle.internal
import org.gradle.api.plugins.ExtraPropertiesExtension import org.gradle.api.plugins.ExtraPropertiesExtension
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.org.objectweb.asm.ClassWriter import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Opcodes.*
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.util.zip.ZipFile
import org.jetbrains.org.objectweb.asm.*
import org.jetbrains.org.objectweb.asm.Opcodes.*
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
import kotlin.properties.Delegates import java.util.zip.ZipFile
public class AnnotationProcessingManager(private val task: KotlinCompile) { public class AnnotationProcessingManager(
private val task: AbstractCompile,
val javaTask: JavaCompile,
val aptFiles: Set<File>,
val aptOutputDir: File,
val aptWorkingDir: File) {
private val project = task.getProject() private val project = task.getProject()
@@ -38,29 +42,12 @@ public class AnnotationProcessingManager(private val task: KotlinCompile) {
} }
fun getAnnotationFile(): File { fun getAnnotationFile(): File {
val aptWorkingDir = task.kotlinAptWorkingDir!!
aptWorkingDir.mkdirs() aptWorkingDir.mkdirs()
return File(aptWorkingDir, "$WRAPPERS_DIRECTORY/$ANNOTATIONS_FILENAME") return File(aptWorkingDir, "$WRAPPERS_DIRECTORY/$ANNOTATIONS_FILENAME")
} }
fun afterKotlinCompile() { fun setupKapt() {
val extraProperties = task.getExtensions().getExtraProperties() if (aptFiles.isEmpty()) return
val javaTask = try {
[suppress("UNCHECKED_CAST")]
(extraProperties.get("javaTask") as? WeakReference<JavaCompile>)?.get()
}
catch (e: ExtraPropertiesExtension.UnknownPropertyException) {
null
}
val aptFiles = task.aptFiles
val aptWorkingDir = task.kotlinAptWorkingDir
val aptOutputDir = task.kotlinAptOutputDir
if (javaTask == null || aptFiles.isEmpty() || aptWorkingDir == null || aptOutputDir == null) return
val annotationDeclarationsFile = File(aptWorkingDir, ANNOTATIONS_FILENAME)
generateJavaHackFile(aptWorkingDir, javaTask) generateJavaHackFile(aptWorkingDir, javaTask)
@@ -43,6 +43,8 @@ import org.gradle.api.file.FileCollection
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import java.util.ServiceLoader import java.util.ServiceLoader
import org.gradle.api.logging.* import org.gradle.api.logging.*
import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
import java.net.URL import java.net.URL
import java.util.jar.Manifest import java.util.jar.Manifest
import java.lang.ref.WeakReference import java.lang.ref.WeakReference
@@ -163,11 +165,16 @@ class Kotlin2JvmSourceSetProcessor(
kotlinDirSet?.srcDir(dir) kotlinDirSet?.srcDir(dir)
} }
if (aptConfiguration.getDependencies().size() > 1) { if (aptConfiguration.getDependencies().size() > 1 && javaTask is JavaCompile) {
kotlinTask.setProperty("aptFiles", aptConfiguration.resolve()) val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(kotlinTask, sourceSet.getName())
}
project.setAptDirsForSourceSet(kotlinTask, sourceSet.getName()) val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, aptConfiguration.resolve(), aptOutputDir, aptWorkingDir)
kotlinTask.storeKaptAnnotationsFile(kaptManager)
javaTask.doFirst {
kaptManager.setupKapt()
}
}
} }
} }
@@ -414,9 +421,7 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
subpluginEnvironment.addSubpluginArguments(project, kotlinTask) subpluginEnvironment.addSubpluginArguments(project, kotlinTask)
kotlinTask.setProperty("aptFiles", aptFiles) val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(kotlinTask, variantDataName)
val aptOutputDir = project.setAptDirsForSourceSet(kotlinTask, variantDataName)
variantData.addJavaSourceFoldersToModel(aptOutputDir) variantData.addJavaSourceFoldersToModel(aptOutputDir)
kotlinTask doFirst { kotlinTask doFirst {
@@ -425,11 +430,14 @@ open class KotlinAndroidPlugin [Inject] (val scriptHandler: ScriptHandler, val t
(it as AbstractCompile).setClasspath(fullClasspath) (it as AbstractCompile).setClasspath(fullClasspath)
} }
kotlinTask.getExtensions().getExtraProperties().set("javaTask", WeakReference(javaTask))
javaTask.dependsOn(kotlinTaskName) javaTask.dependsOn(kotlinTaskName)
javaTask doFirst { val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, aptFiles.toSet(), aptOutputDir, aptWorkingDir)
kotlinTask.storeKaptAnnotationsFile(kaptManager)
javaTask doFirst {
javaTask.setClasspath(javaTask.getClasspath() + project.files(kotlinTask.property("kotlinDestinationDir"))) javaTask.setClasspath(javaTask.getClasspath() + project.files(kotlinTask.property("kotlinDestinationDir")))
kaptManager.setupKapt()
} }
} }
} }
@@ -527,16 +535,18 @@ open class GradleUtils(val scriptHandler: ScriptHandler, val project: ProjectInt
public fun resolveJsLibrary(): File = resolveDependencies(kotlinJsLibraryCoordinates()).first() public fun resolveJsLibrary(): File = resolveDependencies(kotlinJsLibraryCoordinates()).first()
} }
private fun Project.setAptDirsForSourceSet(kotlinTask: AbstractCompile, sourceSetName: String): File { private fun AbstractCompile.storeKaptAnnotationsFile(kapt: AnnotationProcessingManager) {
getExtensions().getExtraProperties().set("kaptAnnotationsFile", kapt.getAnnotationFile())
}
private fun Project.getAptDirsForSourceSet(kotlinTask: AbstractCompile, sourceSetName: String): Pair<File, File> {
val aptOutputDir = File(getBuildDir(), "generated/source/kapt") val aptOutputDir = File(getBuildDir(), "generated/source/kapt")
val aptOutputDirForVariant = File(aptOutputDir, sourceSetName) val aptOutputDirForVariant = File(aptOutputDir, sourceSetName)
kotlinTask.setProperty("kotlinAptOutputDir", aptOutputDirForVariant)
val aptWorkingDir = File(getBuildDir(), "tmp/kapt") val aptWorkingDir = File(getBuildDir(), "tmp/kapt")
val aptWorkingDirForVariant = File(aptWorkingDir, sourceSetName) val aptWorkingDirForVariant = File(aptWorkingDir, sourceSetName)
kotlinTask.setProperty("kotlinAptWorkingDir", aptWorkingDirForVariant)
return aptOutputDirForVariant return aptOutputDirForVariant to aptWorkingDirForVariant
} }
private fun Project.createAptConfiguration(sourceSetName: String, kotlinAnnotationProcessingDep: String): Configuration { private fun Project.createAptConfiguration(sourceSetName: String, kotlinAnnotationProcessingDep: String): Configuration {