Tasks wiring improvements & Kapt3 integration through variant wrapping

This commit is contained in:
Sergey Igushkin
2017-05-10 15:53:24 +03:00
committed by Alexey Tsvetkov
parent b0c2c4eba9
commit d2a08c5fe4
5 changed files with 78 additions and 26 deletions
@@ -44,7 +44,7 @@ dependencies {
compileOnly 'org.codehaus.groovy:groovy-all:2.3.9'
compileOnly 'org.jetbrains.kotlin:gradle-api:2.2'
agp25CompileOnly 'com.android.tools.build:gradle:2.4.0-dev'
agp25CompileOnly 'com.android.tools.build:gradle:3.0.0-dev'
agp25CompileOnly 'org.codehaus.groovy:groovy-all:2.3.9'
agp25CompileOnly gradleApi()
@@ -57,7 +57,6 @@ tasks.withType(project.compileKotlin.class) {
}
compileKotlin.dependsOn compileGroovy
compileAgp25Kotlin.dependsOn compileGroovy
compileGroovy.dependsOn.remove("compileJava")
def groovyClassesDir = file("${buildDir}/mainGroovyClasses")
@@ -73,6 +72,8 @@ sourceSets {
}
}
compileAgp25Kotlin.dependsOn compileGroovy
processResources {
expand(project.properties)
}
@@ -9,6 +9,8 @@ import com.android.builder.model.SourceProvider
import org.gradle.api.Project
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
import org.jetbrains.kotlin.gradle.internal.KaptTask
import org.jetbrains.kotlin.gradle.internal.WrappedVariantData
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import java.io.File
@@ -58,10 +60,12 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
project.files()
).builtBy(kotlinTask)
val preJavaClasspathKey = variantData.registerPreJavacGeneratedBytecode(preJavaKotlinOutput)
val kotlinClasspath = variantData.getCompileClasspath(preJavaClasspathKey)
kotlinTask.dependsOn(variantData.getSourceFolders(SourceKind.JAVA))
kotlinTask.conventionMapping.map("classpath") {
val kotlinClasspath = variantData.getCompileClasspath(preJavaClasspathKey)
kotlinClasspath + project.files(AndroidGradleWrapper.getRuntimeJars(androidPlugin, androidExt))
}
@@ -71,12 +75,12 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
// Use kapt1 annotations file for up-to-date check since annotation processing is done with javac
kotlinTask.annotationsFile?.let { javaTask.inputs.file(it) }
val kotlinAfterJavaOutput = project.files(kotlinAfterJavaTask).builtBy(kotlinAfterJavaTask)
variantData.registerPostJavacGeneratedBytecode(kotlinAfterJavaOutput)
if (kotlinAfterJavaTask != null) {
val kotlinAfterJavaOutput = project.files(kotlinAfterJavaTask.destinationDir).builtBy(kotlinAfterJavaTask)
variantData.registerPostJavacGeneratedBytecode(kotlinAfterJavaOutput)
// Then don't register kotlinTask output, but only use it for Java compilation
javaTask.appendClasspath(kotlinTask.destinationDir)
javaTask.classpath = project.files(kotlinTask.destinationDir).from(javaTask.classpath)
}
}
@@ -112,4 +116,21 @@ class Android25ProjectHandler(kotlinConfigurationTools: KotlinConfigurationTools
// Though it is affordable not to implement this for the first previews, because the impact is tolerable
// to some degree -- the dependent projects will rebuild non-incrementally when a library project changes
}
private inner class WrappedVariant(variantData: BaseVariant) : org.jetbrains.kotlin.gradle.internal.WrappedVariantData<BaseVariant>(variantData) {
override val name: String = getVariantName(variantData)
override val sourceProviders: Iterable<SourceProvider> = getSourceProviders(variantData)
override fun addJavaSourceFoldersToModel(generatedFilesDir: File) = addJavaSourceDirectoryToVariantModel(variantData, generatedFilesDir)
override val annotationProcessorOptions: Map<String, String>? = variantData.javaCompileOptions.annotationProcessorOptions.arguments
override fun wireKaptTask(project: Project, task: KaptTask, kotlinTask: KotlinCompile, javaTask: AbstractCompile) {
task.dependsOn(kotlinTask.dependsOn.minus(task))
val kaptSourceOutput = project.fileTree(task.destinationDir).builtBy(task)
variantData.registerExternalAptJavaOutput(kaptSourceOutput)
}
}
override fun wrapVariantData(variantData: BaseVariant): WrappedVariantData<BaseVariant> = WrappedVariant(variantData)
}
@@ -44,6 +44,14 @@ class Kapt3GradleSubplugin : Plugin<Project> {
override fun apply(project: Project) {}
}
abstract class WrappedVariantData<T>(val variantData: T) {
abstract val name: String
abstract val sourceProviders: Iterable<SourceProvider>
abstract fun addJavaSourceFoldersToModel(generatedFilesDir: File)
abstract val annotationProcessorOptions: Map<String, String>?
abstract fun wireKaptTask(project: Project, task: KaptTask, kotlinTask: KotlinCompile, javaTask: AbstractCompile)
}
// Subplugin for the Kotlin Gradle plugin
class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
companion object {
@@ -131,7 +139,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
}
val sourceSetName = if (variantData != null) {
for (provider in (variantData as BaseVariantData<*>).sourceProviders) {
for (provider in (variantData as WrappedVariantData<*>).sourceProviders) {
handleSourceSet((provider as AndroidSourceSet).name)
}
@@ -167,7 +175,7 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
val generatedFilesDir = getKaptGeneratedDir(project, sourceSetName)
if (variantData != null) {
(variantData as BaseVariantData<*>).addJavaSourceFoldersToModel(generatedFilesDir)
(variantData as WrappedVariantData<*>).addJavaSourceFoldersToModel(generatedFilesDir)
}
pluginOptions += SubpluginOption("aptMode", aptMode)
@@ -195,15 +203,17 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
}
val androidOptions = if (variantData != null)
AndroidGradleWrapper.getAnnotationProcessorOptionsFromAndroidVariant(variantData) ?: emptyMap()
(variantData as WrappedVariantData<*>).annotationProcessorOptions ?: emptyMap()
else
emptyMap()
kotlinSourcesOutputDir.mkdirs()
val apOptions = kaptExtension.getAdditionalArguments(project, variantData, androidPlugin) +
androidOptions +
mapOf("kapt.kotlin.generated" to kotlinSourcesOutputDir.absolutePath)
val apOptions = kaptExtension.getAdditionalArguments(
project,
(variantData as WrappedVariantData<*>).variantData,
androidPlugin
) + androidOptions + mapOf("kapt.kotlin.generated" to kotlinSourcesOutputDir.absolutePath)
pluginOptions += SubpluginOption("apoptions", encodeOptions(apOptions))
@@ -272,10 +282,9 @@ class Kapt3KotlinGradleSubplugin : KotlinGradleSubplugin<KotlinCompile> {
kaptTask.dependsOn(kaptGenerateStubsTask)
kotlinCompile.dependsOn(kaptTask)
(variantData as WrappedVariantData<*>).wireKaptTask(project, kaptTask, kotlinCompile, javaCompile)
// Add generated source dir as a source root for kotlinCompile and javaCompile
kotlinCompile.source(sourcesOutputDir, kotlinSourcesOutputDir)
javaCompile.source(sourcesOutputDir)
buildAndAddOptionsTo(kaptTask.pluginOptions, aptMode = "apt")
}
@@ -22,11 +22,8 @@ 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.gradle.dsl.KotlinJvmOptionsImpl
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin
import org.jetbrains.kotlin.gradle.internal.*
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.getKaptClasssesDir
import org.jetbrains.kotlin.gradle.internal.initKapt
import org.jetbrains.kotlin.gradle.tasks.*
import org.jetbrains.kotlin.gradle.utils.ParsedGradleVersion
import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation
@@ -378,7 +375,6 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
protected val KotlinCompile.annotationsFile: File? get() = kaptOptions.annotationsFile
protected fun KotlinCompile.setJavaOutput(file: File) { javaOutputDir = file }
protected fun AbstractCompile.appendClasspath(file: File) = appendClasspathDynamically(file)
protected val logger = Logging.getLogger(this.javaClass)
@@ -406,6 +402,8 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
kotlinTask: KotlinCompile,
kotlinAfterJavaTask: KotlinCompile?)
protected abstract fun wrapVariantData(variantData: V): WrappedVariantData<V>
fun handleProject(project: Project) {
val ext = project.extensions.getByName("android") as BaseExtension
val aptConfigurations = hashMapOf<String, Configuration>()
@@ -492,9 +490,6 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
removeAnnotationProcessingPluginClasspathEntry(kotlinTask)
}
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
project, kotlinTask, javaTask, variantData, null)
var kotlinAfterJavaTask: KotlinCompile? = null
if (javaTask is JavaCompile && aptFiles.isNotEmpty() && !isKapt3Enabled) {
@@ -513,13 +508,16 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
configureSources(task, variantData)
}
appliedPlugins.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
.forEach { configureSources(it, variantData) }
wireKotlinTasks(project, androidPlugin, androidExt, variantData, javaTask,
kotlinTask, kotlinAfterJavaTask)
configureMultiProjectIc(project, variantData, javaTask, kotlinTask, kotlinAfterJavaTask)
val appliedPlugins = subpluginEnvironment.addSubpluginOptions(
project, kotlinTask, javaTask, wrapVariantData(variantData), null)
appliedPlugins.flatMap { it.getSubpluginKotlinTasks(project, kotlinTask) }
.forEach { configureSources(it, variantData) }
}
private fun configureSources(compileTask: AbstractCompile, variantData: V) {
@@ -9,6 +9,8 @@ import com.android.builder.model.SourceProvider
import org.gradle.api.Project
import org.gradle.api.ProjectConfigurationException
import org.gradle.api.tasks.compile.AbstractCompile
import org.jetbrains.kotlin.gradle.internal.KaptTask
import org.jetbrains.kotlin.gradle.internal.WrappedVariantData
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.incremental.configureMultiProjectIncrementalCompilation
@@ -103,4 +105,25 @@ internal class LegacyAndroidAndroidProjectHandler(kotlinConfigurationTools: Kotl
private val BaseVariantData<*>.sourceProviders: List<SourceProvider>
get() = variantConfiguration.sortedSourceProviders
private inner class WrappedLegacyVariantData(variantData: BaseVariantData<out BaseVariantOutputData>)
: WrappedVariantData<BaseVariantData<out BaseVariantOutputData>>(variantData) {
override val name: String = variantData.name
override val sourceProviders: Iterable<SourceProvider> = getSourceProviders(variantData)
override fun addJavaSourceFoldersToModel(generatedFilesDir: File) =
addJavaSourceDirectoryToVariantModel(variantData, generatedFilesDir)
override val annotationProcessorOptions: Map<String, String>? =
AndroidGradleWrapper.getAnnotationProcessorOptionsFromAndroidVariant(variantData)
override fun wireKaptTask(project: Project, task: KaptTask, kotlinTask: KotlinCompile, javaTask: AbstractCompile) {
task.dependsOn(*(javaTask.dependsOn.filter { it !== kotlinTask }.toTypedArray()))
javaTask.source(task.destinationDir)
}
}
override fun wrapVariantData(variantData: BaseVariantData<out BaseVariantOutputData>)
: WrappedVariantData<BaseVariantData<out BaseVariantOutputData>> =
WrappedLegacyVariantData(variantData)
}