Minor: move kapt-related stuff to AnnotationProcessingManager

This commit is contained in:
Yan Zhulanow
2015-08-18 16:08:10 +03:00
parent b044e4be07
commit acbc39bf9f
2 changed files with 104 additions and 119 deletions
@@ -17,18 +17,92 @@
package org.jetbrains.kotlin.gradle.internal package org.jetbrains.kotlin.gradle.internal
import com.android.build.gradle.BaseExtension import com.android.build.gradle.BaseExtension
import org.gradle.api.Project
import org.gradle.api.UnknownDomainObjectException import org.gradle.api.UnknownDomainObjectException
import org.gradle.api.plugins.ExtraPropertiesExtension
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.gradle.plugin.KaptExtension import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.plugin.kotlinDebug
import java.io.File import java.io.File
import java.io.IOException import java.io.IOException
import java.lang.ref.WeakReference
import java.util.*
import java.util.zip.ZipFile import java.util.zip.ZipFile
fun Project.initKapt(
kotlinTask: AbstractCompile,
javaTask: AbstractCompile,
kaptManager: AnnotationProcessingManager,
variantName: String,
kotlinOutputDir: File,
subpluginEnvironment: SubpluginEnvironment,
taskFactory: (suffix: String) -> AbstractCompile
): AbstractCompile? {
val kaptExtension = extensions.getByType(javaClass<KaptExtension>())
val kotlinAfterJavaTask: AbstractCompile?
if (kaptExtension.generateStubs) {
kotlinAfterJavaTask = createKotlinAfterJavaTask(javaTask, kotlinOutputDir, taskFactory)
kotlinTask.logger.kotlinDebug("kapt: Using class file stubs")
val stubsDir = File(getBuildDir(), "tmp/kapt/$variantName/classFileStubs")
kotlinTask.extensions.extraProperties.set("kaptStubsDir", stubsDir)
javaTask.classpath = javaTask.classpath + files(stubsDir)
kotlinTask.doFirst {
kotlinAfterJavaTask.source(kotlinTask.source)
}
subpluginEnvironment.addSubpluginArguments(this, kotlinAfterJavaTask)
} else {
kotlinAfterJavaTask = null
kotlinTask.logger.kotlinDebug("kapt: Class file stubs are not used")
}
if (kaptExtension.inheritedAnnotations) {
kotlinTask.extensions.extraProperties.set("kaptInheritedAnnotations", true)
}
kotlinTask.doFirst {
kaptManager.generateJavaHackFile()
kotlinAfterJavaTask?.source(kaptManager.getGeneratedKotlinSourceDir())
}
javaTask.doFirst {
kaptManager.setupKapt()
kaptManager.generateJavaHackFile()
kotlinAfterJavaTask?.source(kaptManager.getGeneratedKotlinSourceDir())
}
javaTask.doLast {
kaptManager.afterJavaCompile()
}
kotlinTask.storeKaptAnnotationsFile(kaptManager)
return kotlinAfterJavaTask
}
private fun Project.createKotlinAfterJavaTask(
javaTask: AbstractCompile,
kotlinOutputDir: File,
taskFactory: (suffix: String) -> AbstractCompile
): AbstractCompile {
val kotlinAfterJavaTask = with (taskFactory(KOTLIN_AFTER_JAVA_TASK_SUFFIX)) {
setProperty("kotlinDestinationDir", kotlinOutputDir)
destinationDir = javaTask.destinationDir
classpath = javaTask.classpath
this
}
getAllTasks(false)
.flatMap { it.getValue() }
.filter { javaTask in it.taskDependencies.getDependencies(it) }
.forEach { it.dependsOn(kotlinAfterJavaTask) }
kotlinAfterJavaTask.dependsOn(javaTask)
return kotlinAfterJavaTask
}
public class AnnotationProcessingManager( public class AnnotationProcessingManager(
private val task: AbstractCompile, private val task: AbstractCompile,
private val javaTask: JavaCompile, private val javaTask: JavaCompile,
@@ -39,7 +113,7 @@ public class AnnotationProcessingManager(
private val coreClassLoader: ClassLoader, private val coreClassLoader: ClassLoader,
private val androidVariant: Any? = null) { private val androidVariant: Any? = null) {
private val project = task.getProject() private val project = task.project
private companion object { private companion object {
val JAVA_FQNAME_PATTERN = "^([\\p{L}_$][\\p{L}\\p{N}_$]*\\.)*[\\p{L}_$][\\p{L}\\p{N}_$]*$".toRegex() val JAVA_FQNAME_PATTERN = "^([\\p{L}_$][\\p{L}\\p{N}_$]*\\.)*[\\p{L}_$][\\p{L}\\p{N}_$]*$".toRegex()
@@ -63,8 +137,8 @@ public class AnnotationProcessingManager(
fun setupKapt() { fun setupKapt() {
if (aptFiles.isEmpty()) return if (aptFiles.isEmpty()) return
if (project.getPlugins().findPlugin(ANDROID_APT_PLUGIN_ID) != null) { if (project.plugins.findPlugin(ANDROID_APT_PLUGIN_ID) != null) {
project.getLogger().warn("Please do not use `$ANDROID_APT_PLUGIN_ID` with kapt.") project.logger.warn("Please do not use `$ANDROID_APT_PLUGIN_ID` with kapt.")
} }
val annotationProcessorFqNames = lookupAnnotationProcessors(aptFiles) val annotationProcessorFqNames = lookupAnnotationProcessors(aptFiles)
@@ -84,11 +158,11 @@ public class AnnotationProcessingManager(
} }
fun afterJavaCompile() { fun afterJavaCompile() {
val generatedFile = File(javaTask.getDestinationDir(), "$GEN_ANNOTATION/Cl.class") val generatedFile = File(javaTask.destinationDir, "$GEN_ANNOTATION/Cl.class")
if (generatedFile.exists()) { if (generatedFile.exists()) {
generatedFile.delete() generatedFile.delete()
} else { } else {
project.getLogger().kotlinDebug("kapt: Java file stub was not found at $generatedFile") project.logger.kotlinDebug("kapt: Java file stub was not found at $generatedFile")
} }
} }
@@ -101,7 +175,7 @@ public class AnnotationProcessingManager(
val javaHackClFile = File(javaHackPackageDir, "Cl.java") val javaHackClFile = File(javaHackPackageDir, "Cl.java")
if (!javaHackClFile.exists()) { if (!javaHackClFile.exists()) {
javaHackClFile.writeText("package __gen.annotation; class Cl { @__gen.KotlinAptAnnotation boolean v; }") javaHackClFile.writeText("package __gen.annotation; class Cl { @__gen.KotlinAptAnnotation boolean v; }")
project.getLogger().kotlinDebug("kapt: Java file stub generated: $javaHackClFile") project.logger.kotlinDebug("kapt: Java file stub generated: $javaHackClFile")
} }
if (!javaTask.source.contains(javaHackClFile)) { if (!javaTask.source.contains(javaHackClFile)) {
@@ -117,7 +191,7 @@ public class AnnotationProcessingManager(
} }
private fun appendAdditionalComplerArgs() { private fun appendAdditionalComplerArgs() {
val kaptExtension = project.getExtensions().getByType(javaClass<KaptExtension>()) val kaptExtension = project.extensions.getByType(javaClass<KaptExtension>())
val args = kaptExtension.getAdditionalArguments(project, androidVariant, getAndroidExtension()) val args = kaptExtension.getAdditionalArguments(project, androidVariant, getAndroidExtension())
if (args.isEmpty()) return if (args.isEmpty()) return
@@ -128,7 +202,7 @@ public class AnnotationProcessingManager(
private fun generateAnnotationProcessorStubs(javaTask: JavaCompile, processorFqNames: Set<String>, outputDir: File) { private fun generateAnnotationProcessorStubs(javaTask: JavaCompile, processorFqNames: Set<String>, outputDir: File) {
val aptAnnotationFile = invokeCoreKaptMethod("generateKotlinAptAnnotation", outputDir) as File val aptAnnotationFile = invokeCoreKaptMethod("generateKotlinAptAnnotation", outputDir) as File
project.getLogger().kotlinDebug("kapt: Stub annotation generated: $aptAnnotationFile") project.logger.kotlinDebug("kapt: Stub annotation generated: $aptAnnotationFile")
val stubOutputPackageDir = File(outputDir, "__gen") val stubOutputPackageDir = File(outputDir, "__gen")
stubOutputPackageDir.mkdirs() stubOutputPackageDir.mkdirs()
@@ -151,7 +225,9 @@ public class AnnotationProcessingManager(
addWrappersToCompilerArgs(javaTask, annotationProcessorWrapperFqNames) addWrappersToCompilerArgs(javaTask, annotationProcessorWrapperFqNames)
} }
private fun JavaCompile.appendClasspath(file: File) = setClasspath(getClasspath() + project.files(file)) private fun JavaCompile.appendClasspath(file: File) {
setClasspath(getClasspath() + project.files(file))
}
private fun addWrappersToCompilerArgs(javaTask: JavaCompile, wrapperFqNames: String) { private fun addWrappersToCompilerArgs(javaTask: JavaCompile, wrapperFqNames: String) {
javaTask.addCompilerArgument("-processor") { prevValue -> javaTask.addCompilerArgument("-processor") { prevValue ->
@@ -161,7 +237,7 @@ public class AnnotationProcessingManager(
private fun getAndroidExtension(): BaseExtension? { private fun getAndroidExtension(): BaseExtension? {
try { try {
return project.getExtensions().getByName("android") as BaseExtension return project.extensions.getByName("android") as BaseExtension
} catch (e: UnknownDomainObjectException) { } catch (e: UnknownDomainObjectException) {
return null return null
} }
@@ -172,7 +248,7 @@ public class AnnotationProcessingManager(
javaTask.addCompilerArgument("-s") { prevValue -> javaTask.addCompilerArgument("-s") { prevValue ->
if (prevValue != null) if (prevValue != null)
javaTask.getLogger().warn("Destination for generated sources was modified by kapt. Previous value = $prevValue") javaTask.logger.warn("Destination for generated sources was modified by kapt. Previous value = $prevValue")
outputDir.getAbsolutePath() outputDir.getAbsolutePath()
} }
} }
@@ -180,7 +256,7 @@ public class AnnotationProcessingManager(
private fun setProcessorPath(javaTask: JavaCompile, path: String) { private fun setProcessorPath(javaTask: JavaCompile, path: String) {
javaTask.addCompilerArgument("-processorpath") { prevValue -> javaTask.addCompilerArgument("-processorpath") { prevValue ->
if (prevValue != null) if (prevValue != null)
javaTask.getLogger().warn("Processor path was modified by kapt. Previous value = $prevValue") javaTask.logger.warn("Processor path was modified by kapt. Previous value = $prevValue")
path path
} }
} }
@@ -204,10 +280,10 @@ public class AnnotationProcessingManager(
} }
private inline fun JavaCompile.modifyCompilerArguments(modifier: (MutableList<String>) -> Unit) { private inline fun JavaCompile.modifyCompilerArguments(modifier: (MutableList<String>) -> Unit) {
val compilerArgs: List<Any> = getOptions().getCompilerArgs() val compilerArgs: List<Any> = this.options.compilerArgs
val newCompilerArgs = compilerArgs.mapTo(arrayListOf<String>()) { it.toString() } val newCompilerArgs = compilerArgs.mapTo(arrayListOf<String>()) { it.toString() }
modifier(newCompilerArgs) modifier(newCompilerArgs)
getOptions().setCompilerArgs(newCompilerArgs) options.compilerArgs = newCompilerArgs
} }
private fun lookupAnnotationProcessors(files: Set<File>): Set<String> { private fun lookupAnnotationProcessors(files: Set<File>): Set<String> {
@@ -251,7 +327,7 @@ public class AnnotationProcessingManager(
} }
} }
project.getLogger().kotlinDebug("kapt: Discovered annotation processors: ${annotationProcessors.joinToString()}") project.logger.kotlinDebug("kapt: Discovered annotation processors: ${annotationProcessors.joinToString()}")
return annotationProcessors return annotationProcessors
} }
@@ -11,22 +11,12 @@ import java.io.File
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.tasks.compile.AbstractCompile import org.gradle.api.tasks.compile.AbstractCompile
import com.android.build.gradle.BaseExtension import com.android.build.gradle.BaseExtension
import com.android.build.gradle.AppExtension
import com.android.build.gradle.LibraryExtension
import org.gradle.api.internal.DefaultDomainObjectSet
import com.android.build.gradle.api.BaseVariant
import com.android.build.gradle.api.AndroidSourceSet import com.android.build.gradle.api.AndroidSourceSet
import java.util.ArrayList
import com.android.build.gradle.BasePlugin import com.android.build.gradle.BasePlugin
import com.android.build.gradle.api.LibraryVariant
import com.android.build.gradle.api.ApkVariant
import com.android.build.gradle.api.TestVariant
import com.android.build.gradle.internal.variant.BaseVariantData import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.BaseVariantOutputData import com.android.build.gradle.internal.variant.BaseVariantOutputData
import com.android.builder.core.VariantType
import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.artifacts.ConfigurationContainer
import org.gradle.api.UnknownDomainObjectException
import org.gradle.api.initialization.dsl.ScriptHandler import org.gradle.api.initialization.dsl.ScriptHandler
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
import javax.inject.Inject import javax.inject.Inject
@@ -35,16 +25,15 @@ import kotlin.properties.Delegates
import org.gradle.api.tasks.Delete import org.gradle.api.tasks.Delete
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
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.plugins.* import org.gradle.api.plugins.*
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
import org.jetbrains.kotlin.gradle.internal.initKapt
import java.net.URL import java.net.URL
import java.util.jar.Manifest import java.util.jar.Manifest
import java.lang.ref.WeakReference
val DEFAULT_ANNOTATIONS = "org.jebrains.kotlin.gradle.defaultAnnotations" val DEFAULT_ANNOTATIONS = "org.jebrains.kotlin.gradle.defaultAnnotations"
@@ -167,7 +156,7 @@ class Kotlin2JvmSourceSetProcessor(
subpluginEnvironment.addSubpluginArguments(project, kotlinTask) subpluginEnvironment.addSubpluginArguments(project, kotlinTask)
if (aptConfiguration.getDependencies().size() > 1 && javaTask is JavaCompile) { if (aptConfiguration.getDependencies().size() > 1 && javaTask is JavaCompile) {
val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(kotlinTask, sourceSetName) val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(sourceSetName)
val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, sourceSetName, val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, sourceSetName,
aptConfiguration.resolve(), aptOutputDir, aptWorkingDir, tasksProvider.tasksLoader) aptConfiguration.resolve(), aptOutputDir, aptWorkingDir, tasksProvider.tasksLoader)
@@ -432,7 +421,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
javaTask.dependsOn(kotlinTaskName) javaTask.dependsOn(kotlinTaskName)
val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(kotlinTask, variantDataName) val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(variantDataName)
variantData.addJavaSourceFoldersToModel(aptOutputDir) variantData.addJavaSourceFoldersToModel(aptOutputDir)
if (javaTask is JavaCompile && aptFiles.isNotEmpty()) { if (javaTask is JavaCompile && aptFiles.isNotEmpty()) {
@@ -491,7 +480,7 @@ private fun loadSubplugins(project: Project): SubpluginEnvironment {
} }
} }
private class SubpluginEnvironment( class SubpluginEnvironment(
val subpluginClasspaths: Map<KotlinGradleSubplugin, List<String>>, val subpluginClasspaths: Map<KotlinGradleSubplugin, List<String>>,
val subplugins: List<KotlinGradleSubplugin> val subplugins: List<KotlinGradleSubplugin>
) { ) {
@@ -518,7 +507,7 @@ private class SubpluginEnvironment(
} }
} }
val extraProperties = compileTask.extraProperties val extraProperties = compileTask.extensions.extraProperties
extraProperties.set("compilerPluginClasspaths", realPluginClasspaths.toTypedArray()) extraProperties.set("compilerPluginClasspaths", realPluginClasspaths.toTypedArray())
extraProperties.set("compilerPluginArguments", pluginArguments.toTypedArray()) extraProperties.set("compilerPluginArguments", pluginArguments.toTypedArray())
} }
@@ -544,11 +533,11 @@ 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 AbstractCompile.storeKaptAnnotationsFile(kapt: AnnotationProcessingManager) { fun AbstractCompile.storeKaptAnnotationsFile(kapt: AnnotationProcessingManager) {
extraProperties.set("kaptAnnotationsFile", kapt.getAnnotationFile()) extensions.extraProperties.set("kaptAnnotationsFile", kapt.getAnnotationFile())
} }
private fun Project.getAptDirsForSourceSet(kotlinTask: AbstractCompile, sourceSetName: String): Pair<File, File> { private fun Project.getAptDirsForSourceSet(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)
@@ -571,83 +560,6 @@ private fun Project.createKaptExtension() {
getExtensions().create("kapt", javaClass<KaptExtension>()) getExtensions().create("kapt", javaClass<KaptExtension>())
} }
private fun Project.initKapt(
kotlinTask: AbstractCompile,
javaTask: AbstractCompile,
kaptManager: AnnotationProcessingManager,
variantName: String,
kotlinOutputDir: File,
subpluginEnvironment: SubpluginEnvironment,
taskFactory: (suffix: String) -> AbstractCompile
): AbstractCompile? {
val kaptExtension = getExtensions().getByType(javaClass<KaptExtension>())
val kotlinAfterJavaTask: AbstractCompile?
if (kaptExtension.generateStubs) {
kotlinAfterJavaTask = createKotlinAfterJavaTask(javaTask, kotlinOutputDir, taskFactory)
kotlinTask.getLogger().kotlinDebug("kapt: Using class file stubs")
val stubsDir = File(getBuildDir(), "tmp/kapt/$variantName/classFileStubs")
kotlinTask.extraProperties.set("kaptStubsDir", stubsDir)
javaTask.setClasspath(javaTask.getClasspath() + files(stubsDir))
kotlinTask.doFirst {
kotlinAfterJavaTask.source(kotlinTask.getSource())
}
subpluginEnvironment.addSubpluginArguments(this, kotlinAfterJavaTask)
} else {
kotlinAfterJavaTask = null
kotlinTask.getLogger().kotlinDebug("kapt: Class file stubs are not used")
}
if (kaptExtension.inheritedAnnotations) {
kotlinTask.extraProperties.set("kaptInheritedAnnotations", true)
}
kotlinTask.doFirst {
kaptManager.generateJavaHackFile()
kotlinAfterJavaTask?.source(kaptManager.getGeneratedKotlinSourceDir())
}
javaTask.doFirst {
kaptManager.setupKapt()
kaptManager.generateJavaHackFile()
kotlinAfterJavaTask?.source(kaptManager.getGeneratedKotlinSourceDir())
}
javaTask.doLast {
kaptManager.afterJavaCompile()
}
kotlinTask.storeKaptAnnotationsFile(kaptManager)
return kotlinAfterJavaTask
}
private fun Project.createKotlinAfterJavaTask(
javaTask: AbstractCompile,
kotlinOutputDir: File,
taskFactory: (suffix: String) -> AbstractCompile
): AbstractCompile {
val kotlinAfterJavaTask = with (taskFactory(KOTLIN_AFTER_JAVA_TASK_SUFFIX)) {
setProperty("kotlinDestinationDir", kotlinOutputDir)
setDestinationDir(javaTask.getDestinationDir())
setClasspath(javaTask.getClasspath())
this
}
getAllTasks(false)
.flatMap { it.getValue() }
.filter { javaTask in it.getTaskDependencies().getDependencies(it) }
.forEach { it.dependsOn(kotlinAfterJavaTask) }
kotlinAfterJavaTask.dependsOn(javaTask)
return kotlinAfterJavaTask
}
//copied from BasePlugin.getLocalVersion //copied from BasePlugin.getLocalVersion
private fun loadAndroidPluginVersion(): String? { private fun loadAndroidPluginVersion(): String? {
try { try {
@@ -671,9 +583,6 @@ private fun loadAndroidPluginVersion(): String? {
} }
} }
private val AbstractCompile.extraProperties: ExtraPropertiesExtension
get() = getExtensions().getExtraProperties()
//Copied from StringUtil.compareVersionNumbers //Copied from StringUtil.compareVersionNumbers
private fun compareVersionNumbers(v1: String?, v2: String?): Int { private fun compareVersionNumbers(v1: String?, v2: String?): Int {
if (v1 == null && v2 == null) { if (v1 == null && v2 == null) {