Introduce tooling model for Kapt gradle projects

A Kapt model for Gradle projects including 'kotlin-kapt'plugin is
introduced. Its model builder KaptModelBuilder produces an
implementation of these models and can be queried through the Gradle
Tooling API when needed. Model builder is registered in
Kapt3GradleSubplugin.
This commit is contained in:
Lucas Smaira
2018-06-05 13:08:02 +01:00
committed by Sergey Igushkin
parent 9def6f020f
commit 5671dbb929
10 changed files with 350 additions and 1 deletions
@@ -0,0 +1,55 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model
import org.jetbrains.kotlin.gradle.BaseGradleIT
import org.junit.Test
import kotlin.test.assertEquals
import kotlin.test.assertNull
import kotlin.test.assertTrue
class KaptModelIT : BaseGradleIT() {
@Test
fun testKaptSimple() {
val project = Project("simple", directoryPrefix = "kapt2")
val kaptModel = project.getModels(Kapt::class.java).getModel(":")!!
kaptModel.assertBasics("simple")
assertEquals(2, kaptModel.kaptSourceSets.size)
val mainSourceSet = kaptModel.kaptSourceSets.find { it.name == "main" }!!
val testSourceSet = kaptModel.kaptSourceSets.find { it.name == "test" }!!
assertEquals(KaptSourceSet.KaptSourceSetType.PRODUCTION, mainSourceSet.type)
assertTrue(mainSourceSet.generatedSourcesDirectory.absolutePath.contains("build/generated/source/kapt/main"))
assertTrue(mainSourceSet.generatedKotlinSourcesDirectory.absolutePath.contains("build/generated/source/kaptKotlin/main"))
assertTrue(mainSourceSet.generatedClassesDirectory.absolutePath.contains("tmp/kapt3/classes/main"))
assertEquals(KaptSourceSet.KaptSourceSetType.TEST, testSourceSet.type)
assertTrue(testSourceSet.generatedSourcesDirectory.absolutePath.contains("build/generated/source/kapt/test"))
assertTrue(testSourceSet.generatedKotlinSourcesDirectory.absolutePath.contains("build/generated/source/kaptKotlin/test"))
assertTrue(testSourceSet.generatedClassesDirectory.absolutePath.contains("tmp/kapt3/classes/test"))
}
@Test
fun testNonJvmProjects() {
val project = Project("kotlin2JsProject")
val models = project.getModels(Kapt::class.java)
assertNull(models.getModel(":"))
assertNull(models.getModel(":libraryProject"))
assertNull(models.getModel(":mainProject"))
}
companion object {
private fun Kapt.assertBasics(expectedName: String) {
assertEquals(1L, modelVersion)
assertEquals(expectedName, name)
}
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
/**
* Entry point for annotation processor model.
* Plugin 'kotlin-kapt' can produce this model.
*/
public interface Kapt {
/**
* Return a number representing the version of this API.
* Always increasing if changed.
*
* @return the version of this model.
*/
long getModelVersion();
/**
* Returns the module (Gradle project) name.
*
* @return the module name.
*/
@NotNull
String getName();
/**
* Return all kapt source sets.
*
* @return all kapt source sets.
*/
@NotNull
Collection<KaptSourceSet> getKaptSourceSets();
}
@@ -0,0 +1,65 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model;
import org.jetbrains.annotations.NotNull;
import java.io.File;
/**
* Represents a source set for a given kapt model.
* @see Kapt
*/
public interface KaptSourceSet {
/**
* Possible source set types.
*/
enum KaptSourceSetType {
PRODUCTION,
TEST
}
/**
* Return the source set name.
*
* @return the source set name.
*/
@NotNull
String getName();
/**
* Return the type of the source set.
*
* @return the type of the source set.
*/
@NotNull
KaptSourceSetType getType();
/**
* Return generated sources directory.
*
* @return generated sources directory.
*/
@NotNull
File getGeneratedSourcesDirectory();
/**
* Return Kotlin generated sources directory.
*
* @return Kotlin generated sources directory.
*/
@NotNull
File getGeneratedKotlinSourcesDirectory();
/**
* Return Kotlin generated classes directory.
*
* @return Kotlin generated classes directory.
*/
@NotNull
File getGeneratedClassesDirectory();
}
@@ -18,10 +18,12 @@ import org.gradle.api.tasks.TaskDependency
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.process.CommandLineArgumentProvider
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedClassesDir
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedKotlinSourcesDir
import org.jetbrains.kotlin.gradle.internal.Kapt3GradleSubplugin.Companion.getKaptGeneratedSourcesDir
import org.jetbrains.kotlin.gradle.internal.Kapt3KotlinGradleSubplugin.Companion.KAPT_WORKER_DEPENDENCIES_CONFIGURATION_NAME
import org.jetbrains.kotlin.gradle.model.builder.KaptModelBuilder
import org.jetbrains.kotlin.gradle.tasks.isWorkerAPISupported
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.tasks.CompilerPluginOptions
@@ -31,9 +33,10 @@ import java.io.ByteArrayOutputStream
import java.io.File
import java.io.ObjectOutputStream
import java.util.*
import javax.inject.Inject
// apply plugin: 'kotlin-kapt'
class Kapt3GradleSubplugin : Plugin<Project> {
class Kapt3GradleSubplugin @Inject internal constructor(private val registry: ToolingModelBuilderRegistry) : Plugin<Project> {
companion object {
fun isEnabled(project: Project) = project.plugins.findPlugin(Kapt3GradleSubplugin::class.java) != null
@@ -61,6 +64,7 @@ class Kapt3GradleSubplugin : Plugin<Project> {
} ?: project.logger.error("Kotlin plugin should be enabled before 'kotlin-kapt'")
}
}
registry.register(KaptModelBuilder())
}
}
@@ -0,0 +1,51 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model.builder
import org.gradle.api.Project
import org.gradle.tooling.provider.model.ToolingModelBuilder
import org.jetbrains.kotlin.gradle.internal.KaptTask
import org.jetbrains.kotlin.gradle.model.Kapt
import org.jetbrains.kotlin.gradle.model.KaptSourceSet
import org.jetbrains.kotlin.gradle.model.impl.KaptImpl
import org.jetbrains.kotlin.gradle.model.impl.KaptSourceSetImpl
/**
* [ToolingModelBuilder] for [Kapt] models.
* This model builder is registered for Kapt Gradle sub-plugin.
*/
class KaptModelBuilder : ToolingModelBuilder {
override fun canBuild(modelName: String): Boolean {
return modelName == Kapt::class.java.name
}
override fun buildAll(modelName: String, project: Project): Any? {
if (modelName == Kapt::class.java.name) {
val kaptTasks = project.tasks.withType(KaptTask::class.java)
return KaptImpl(project.name, kaptTasks.map { it.createKaptSourceSet() })
}
return null
}
companion object {
private fun KaptTask.createKaptSourceSet(): KaptSourceSet {
val sourceSetName = kotlinCompileTask.sourceSetName
return KaptSourceSetImpl(
sourceSetName,
if (sourceSetName.contains(
"test",
true
)
) KaptSourceSet.KaptSourceSetType.TEST else KaptSourceSet.KaptSourceSetType.PRODUCTION,
destinationDir,
kotlinSourcesDestinationDir,
classesDir
)
}
}
}
@@ -0,0 +1,35 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model.impl
import org.jetbrains.kotlin.gradle.model.Kapt
import org.jetbrains.kotlin.gradle.model.KaptSourceSet
import java.io.Serializable
/**
* Implementation of the [Kapt] interface.
*/
data class KaptImpl(
private val myName: String,
private val kaptSourceSets: Collection<KaptSourceSet>
) : Kapt, Serializable {
override fun getModelVersion(): Long {
return serialVersionUID
}
override fun getName(): String {
return myName
}
override fun getKaptSourceSets(): Collection<KaptSourceSet> {
return kaptSourceSets
}
companion object {
private const val serialVersionUID = 1L
}
}
@@ -0,0 +1,42 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model.impl
import org.jetbrains.kotlin.gradle.model.KaptSourceSet
import java.io.File
import java.io.Serializable
/**
* Implementation of the [KaptSourceSet] interface.
*/
data class KaptSourceSetImpl(
private val myName: String,
private val myType: KaptSourceSet.KaptSourceSetType,
private val myGeneratedSourcesDirectory: File,
private val myGeneratedKotlinSourcesDirectory: File,
private val myGeneratedClassesDirectory: File
) : KaptSourceSet, Serializable {
override fun getName(): String {
return myName
}
override fun getType(): KaptSourceSet.KaptSourceSetType {
return myType
}
override fun getGeneratedSourcesDirectory(): File {
return myGeneratedSourcesDirectory
}
override fun getGeneratedKotlinSourcesDirectory(): File {
return myGeneratedKotlinSourcesDirectory
}
override fun getGeneratedClassesDirectory(): File {
return myGeneratedClassesDirectory
}
}
@@ -0,0 +1,20 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model.builder
import org.jetbrains.kotlin.gradle.model.Kapt
import org.junit.Test
import kotlin.test.assertFalse
import kotlin.test.assertTrue
class KaptModelBuilderTest {
@Test
fun testCanBuild() {
val modelBuilder = KaptModelBuilder()
assertTrue(modelBuilder.canBuild(Kapt::class.java.name))
assertFalse(modelBuilder.canBuild("wrongModel"))
}
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model.impl
import nl.jqno.equalsverifier.EqualsVerifier
import nl.jqno.equalsverifier.Warning
import org.junit.Test
class KaptImplTest {
@Test
@Throws(Exception::class)
fun equals() {
EqualsVerifier.forClass(KaptImpl::class.java).suppress(Warning.NULL_FIELDS).verify()
}
}
@@ -0,0 +1,18 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.gradle.model.impl
import nl.jqno.equalsverifier.EqualsVerifier
import nl.jqno.equalsverifier.Warning
import org.junit.Test
class KaptSourceSetImplTest {
@Test
@Throws(Exception::class)
fun equals() {
EqualsVerifier.forClass(KaptSourceSetImpl::class.java).suppress(Warning.NULL_FIELDS).verify()
}
}