Refactoring: inject FileResolver

This is part of refactoring to minimize using of internal API in gradle plugin
This commit is contained in:
Alexey Tsvetkov
2016-07-27 18:43:06 +03:00
parent 2c1d90c79d
commit f0ff0d0a18
5 changed files with 68 additions and 41 deletions
@@ -5,35 +5,30 @@ import org.gradle.api.file.SourceDirectorySet
import org.gradle.api.internal.file.DefaultSourceDirectorySet import org.gradle.api.internal.file.DefaultSourceDirectorySet
import org.gradle.api.internal.file.FileResolver import org.gradle.api.internal.file.FileResolver
import org.gradle.util.ConfigureUtil import org.gradle.util.ConfigureUtil
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProvider
import java.lang.reflect.Constructor import java.lang.reflect.Constructor
interface KotlinSourceSet { internal class KotlinSourceSetProviderImpl constructor(private val fileResolver: FileResolver) : KotlinSourceSetProvider {
override fun create(displayName: String): KotlinSourceSet =
fun getKotlin(): SourceDirectorySet KotlinSourceSetImpl(displayName, fileResolver)
fun kotlin(configureClosure: Closure<Any?>?): KotlinSourceSet
} }
private class KotlinSourceSetImpl(displayName: String, resolver: FileResolver) : KotlinSourceSet {
open class KotlinSourceSetImpl(displayName: String?, resolver: FileResolver?): KotlinSourceSet { override val kotlin: SourceDirectorySet =
createDefaultSourceDirectorySet(displayName + " Kotlin source", resolver)
private val kotlin: DefaultSourceDirectorySet = createDefaultSourceDirectorySet(displayName + " Kotlin source", resolver)
init { init {
kotlin.filter?.include("**/*.java", "**/*.kt") kotlin.filter?.include("**/*.java", "**/*.kt")
} }
override fun getKotlin(): SourceDirectorySet {
return kotlin
}
override fun kotlin(configureClosure: Closure<Any?>?): KotlinSourceSet { override fun kotlin(configureClosure: Closure<Any?>?): KotlinSourceSet {
ConfigureUtil.configure(configureClosure, getKotlin()) ConfigureUtil.configure(configureClosure, kotlin)
return this return this
} }
} }
private val createDefaultSourceDirectorySet: (name: String?, resolver: FileResolver?) -> DefaultSourceDirectorySet = run { private val createDefaultSourceDirectorySet: (name: String?, resolver: FileResolver?) -> SourceDirectorySet = run {
val klass = DefaultSourceDirectorySet::class.java val klass = DefaultSourceDirectorySet::class.java
val defaultConstructor = klass.constructorOrNull(String::class.java, FileResolver::class.java) val defaultConstructor = klass.constructorOrNull(String::class.java, FileResolver::class.java)
@@ -30,8 +30,6 @@ 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.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager import org.jetbrains.kotlin.gradle.internal.AnnotationProcessingManager
import org.jetbrains.kotlin.gradle.internal.KotlinSourceSet
import org.jetbrains.kotlin.gradle.internal.KotlinSourceSetImpl
import org.jetbrains.kotlin.gradle.internal.initKapt import org.jetbrains.kotlin.gradle.internal.initKapt
import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper import org.jetbrains.kotlin.gradle.plugin.android.AndroidGradleWrapper
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
@@ -51,6 +49,7 @@ abstract class KotlinSourceSetProcessor<T : AbstractCompile>(
val javaBasePlugin: JavaBasePlugin, val javaBasePlugin: JavaBasePlugin,
val sourceSet: SourceSet, val sourceSet: SourceSet,
val tasksProvider: KotlinTasksProvider, val tasksProvider: KotlinTasksProvider,
val kotlinSourceSetProvider: KotlinSourceSetProvider,
val pluginName: String, val pluginName: String,
val compileTaskNameSuffix: String, val compileTaskNameSuffix: String,
val taskDescription: String val taskDescription: String
@@ -78,7 +77,7 @@ abstract class KotlinSourceSetProcessor<T : AbstractCompile>(
private fun createKotlinSourceSet(): KotlinSourceSet? = private fun createKotlinSourceSet(): KotlinSourceSet? =
if (sourceSet is HasConvention) { if (sourceSet is HasConvention) {
logger.kotlinDebug("Creating KotlinSourceSet for source set ${sourceSet}") logger.kotlinDebug("Creating KotlinSourceSet for source set ${sourceSet}")
val kotlinSourceSet = KotlinSourceSetImpl(sourceSet.name, project.fileResolver) val kotlinSourceSet = kotlinSourceSetProvider.create(sourceSet.name)
sourceSet.convention.plugins.put(pluginName, kotlinSourceSet) sourceSet.convention.plugins.put(pluginName, kotlinSourceSet)
kotlinSourceSet kotlinSourceSet
} else { } else {
@@ -88,7 +87,7 @@ abstract class KotlinSourceSetProcessor<T : AbstractCompile>(
private fun createKotlinDirSet(): SourceDirectorySet? { private fun createKotlinDirSet(): SourceDirectorySet? {
val srcDir = project.file(sourceRootDir) val srcDir = project.file(sourceRootDir)
logger.kotlinDebug("Creating Kotlin SourceDirectorySet for source set $kotlinSourceSet with src dir $srcDir") logger.kotlinDebug("Creating Kotlin SourceDirectorySet for source set $kotlinSourceSet with src dir $srcDir")
val kotlinDirSet = kotlinSourceSet?.getKotlin() val kotlinDirSet = kotlinSourceSet?.kotlin
kotlinDirSet?.srcDir(srcDir) kotlinDirSet?.srcDir(srcDir)
return kotlinDirSet return kotlinDirSet
} }
@@ -119,9 +118,10 @@ class Kotlin2JvmSourceSetProcessor(
javaBasePlugin: JavaBasePlugin, javaBasePlugin: JavaBasePlugin,
sourceSet: SourceSet, sourceSet: SourceSet,
val scriptHandler: ScriptHandler, val scriptHandler: ScriptHandler,
tasksProvider: KotlinTasksProvider tasksProvider: KotlinTasksProvider,
kotlinSourceSetProvider: KotlinSourceSetProvider
) : KotlinSourceSetProcessor<KotlinCompile>( ) : KotlinSourceSetProcessor<KotlinCompile>(
project, javaBasePlugin, sourceSet, tasksProvider, project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider,
pluginName = "kotlin", pluginName = "kotlin",
compileTaskNameSuffix = "kotlin", compileTaskNameSuffix = "kotlin",
taskDescription = "Compiles the $sourceSet.kotlin." taskDescription = "Compiles the $sourceSet.kotlin."
@@ -185,9 +185,10 @@ class Kotlin2JsSourceSetProcessor(
javaBasePlugin: JavaBasePlugin, javaBasePlugin: JavaBasePlugin,
sourceSet: SourceSet, sourceSet: SourceSet,
val scriptHandler: ScriptHandler, val scriptHandler: ScriptHandler,
tasksProvider: KotlinTasksProvider tasksProvider: KotlinTasksProvider,
kotlinSourceSetProvider: KotlinSourceSetProvider
) : KotlinSourceSetProcessor<Kotlin2JsCompile>( ) : KotlinSourceSetProcessor<Kotlin2JsCompile>(
project, javaBasePlugin, sourceSet, tasksProvider, project, javaBasePlugin, sourceSet, tasksProvider, kotlinSourceSetProvider,
pluginName = "kotlin2js", pluginName = "kotlin2js",
taskDescription = "Compiles the kotlin sources in $sourceSet to JavaScript.", taskDescription = "Compiles the kotlin sources in $sourceSet to JavaScript.",
compileTaskNameSuffix = "kotlin2Js" compileTaskNameSuffix = "kotlin2Js"
@@ -232,7 +233,7 @@ class Kotlin2JsSourceSetProcessor(
} }
abstract class AbstractKotlinPlugin @Inject constructor(val scriptHandler: ScriptHandler, val tasksProvider: KotlinTasksProvider) : Plugin<Project> { abstract class AbstractKotlinPlugin @Inject constructor(val scriptHandler: ScriptHandler, val tasksProvider: KotlinTasksProvider, val kotlinSourceSetProvider: KotlinSourceSetProvider) : Plugin<Project> {
abstract fun buildSourceSetProcessor(project: ProjectInternal, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet): KotlinSourceSetProcessor<*> abstract fun buildSourceSetProcessor(project: ProjectInternal, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet): KotlinSourceSetProcessor<*>
public override fun apply(project: Project) { public override fun apply(project: Project) {
@@ -256,9 +257,13 @@ abstract class AbstractKotlinPlugin @Inject constructor(val scriptHandler: Scrip
} }
open class KotlinPlugin @Inject constructor(scriptHandler: ScriptHandler, tasksProvider: KotlinTasksProvider) : AbstractKotlinPlugin(scriptHandler, tasksProvider) { open class KotlinPlugin(
scriptHandler: ScriptHandler,
tasksProvider: KotlinTasksProvider,
kotlinSourceSetProvider: KotlinSourceSetProvider
) : AbstractKotlinPlugin(scriptHandler, tasksProvider, kotlinSourceSetProvider) {
override fun buildSourceSetProcessor(project: ProjectInternal, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet) = override fun buildSourceSetProcessor(project: ProjectInternal, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet) =
Kotlin2JvmSourceSetProcessor(project, javaBasePlugin, sourceSet, scriptHandler, tasksProvider) Kotlin2JvmSourceSetProcessor(project, javaBasePlugin, sourceSet, scriptHandler, tasksProvider, kotlinSourceSetProvider)
override fun apply(project: Project) { override fun apply(project: Project) {
project.createKaptExtension() project.createKaptExtension()
@@ -267,13 +272,20 @@ open class KotlinPlugin @Inject constructor(scriptHandler: ScriptHandler, tasksP
} }
open class Kotlin2JsPlugin @Inject constructor(scriptHandler: ScriptHandler, tasksProvider: KotlinTasksProvider) : AbstractKotlinPlugin(scriptHandler, tasksProvider) { open class Kotlin2JsPlugin(
scriptHandler: ScriptHandler,
tasksProvider: KotlinTasksProvider,
kotlinSourceSetProvider: KotlinSourceSetProvider
) : AbstractKotlinPlugin(scriptHandler, tasksProvider, kotlinSourceSetProvider) {
override fun buildSourceSetProcessor(project: ProjectInternal, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet) = override fun buildSourceSetProcessor(project: ProjectInternal, javaBasePlugin: JavaBasePlugin, sourceSet: SourceSet) =
Kotlin2JsSourceSetProcessor(project, javaBasePlugin, sourceSet, scriptHandler, tasksProvider) Kotlin2JsSourceSetProcessor(project, javaBasePlugin, sourceSet, scriptHandler, tasksProvider, kotlinSourceSetProvider)
} }
open class KotlinAndroidPlugin(
open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHandler, val tasksProvider: KotlinTasksProvider) : Plugin<Project> { val scriptHandler: ScriptHandler,
val tasksProvider: KotlinTasksProvider,
private val kotlinSourceSetProvider: KotlinSourceSetProvider
) : Plugin<Project> {
val log = Logging.getLogger(this.javaClass) val log = Logging.getLogger(this.javaClass)
@@ -298,9 +310,9 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
ext.sourceSets.all { sourceSet -> ext.sourceSets.all { sourceSet ->
if (sourceSet is HasConvention) { if (sourceSet is HasConvention) {
val sourceSetName = sourceSet.name val sourceSetName = sourceSet.name
val kotlinSourceSet = KotlinSourceSetImpl(sourceSetName, project.fileResolver) val kotlinSourceSet = kotlinSourceSetProvider.create(sourceSetName)
sourceSet.convention.plugins.put("kotlin", kotlinSourceSet) sourceSet.convention.plugins.put("kotlin", kotlinSourceSet)
val kotlinDirSet = kotlinSourceSet.getKotlin() val kotlinDirSet = kotlinSourceSet.kotlin
kotlinDirSet.srcDir(project.file("src/$sourceSetName/kotlin")) kotlinDirSet.srcDir(project.file("src/$sourceSetName/kotlin"))
aptConfigurations.put(sourceSet.name, aptConfigurations.put(sourceSet.name,
@@ -403,8 +415,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
for (provider in variantData.sourceProviders) { for (provider in variantData.sourceProviders) {
val kotlinSourceSet = getExtension<KotlinSourceSet>(provider, "kotlin") val kotlinSourceSet = getExtension<KotlinSourceSet>(provider, "kotlin")
val kotlinSourceDirectorySet = kotlinSourceSet.getKotlin() kotlinTask.source(kotlinSourceSet.kotlin)
kotlinTask.source(kotlinSourceDirectorySet)
} }
for (javaSrcDir in AndroidGradleWrapper.getJavaSources(variantData)) { for (javaSrcDir in AndroidGradleWrapper.getJavaSources(variantData)) {
@@ -3,14 +3,17 @@ package org.jetbrains.kotlin.gradle.plugin
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.initialization.dsl.ScriptHandler import org.gradle.api.initialization.dsl.ScriptHandler
import org.gradle.api.internal.file.FileResolver
import org.gradle.api.logging.Logger import org.gradle.api.logging.Logger
import org.gradle.api.logging.Logging import org.gradle.api.logging.Logging
import org.jetbrains.kotlin.gradle.internal.KotlinSourceSetProviderImpl
import org.jetbrains.kotlin.gradle.tasks.AndroidTasksProvider import org.jetbrains.kotlin.gradle.tasks.AndroidTasksProvider
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import javax.inject.Inject
// TODO: simplify: the complicated structure is a leftover from dynamic loading of plugin core, could be significantly simplified now // TODO: simplify: the complicated structure is a leftover from dynamic loading of plugin core, could be significantly simplified now
abstract class KotlinBasePluginWrapper: Plugin<Project> { abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver): Plugin<Project> {
val log = Logging.getLogger(this.javaClass) val log = Logging.getLogger(this.javaClass)
@@ -55,16 +58,19 @@ abstract class KotlinBasePluginWrapper: Plugin<Project> {
} }
} }
open class KotlinPluginWrapper: KotlinBasePluginWrapper() { open class KotlinPluginWrapper @Inject constructor(fileResolver: FileResolver): KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(scriptHandler: ScriptHandler) = KotlinPlugin(scriptHandler, KotlinTasksProvider()) override fun getPlugin(scriptHandler: ScriptHandler) =
KotlinPlugin(scriptHandler, KotlinTasksProvider(), KotlinSourceSetProviderImpl(fileResolver))
} }
open class KotlinAndroidPluginWrapper : KotlinBasePluginWrapper() { open class KotlinAndroidPluginWrapper @Inject constructor(fileResolver: FileResolver): KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(scriptHandler: ScriptHandler) = KotlinAndroidPlugin(scriptHandler, AndroidTasksProvider()) override fun getPlugin(scriptHandler: ScriptHandler) =
KotlinAndroidPlugin(scriptHandler, AndroidTasksProvider(), KotlinSourceSetProviderImpl(fileResolver))
} }
open class Kotlin2JsPluginWrapper : KotlinBasePluginWrapper() { open class Kotlin2JsPluginWrapper @Inject constructor(fileResolver: FileResolver): KotlinBasePluginWrapper(fileResolver) {
override fun getPlugin(scriptHandler: ScriptHandler) = Kotlin2JsPlugin(scriptHandler, KotlinTasksProvider()) override fun getPlugin(scriptHandler: ScriptHandler) =
Kotlin2JsPlugin(scriptHandler, KotlinTasksProvider(), KotlinSourceSetProviderImpl(fileResolver))
} }
fun Logger.kotlinDebug(message: String) { fun Logger.kotlinDebug(message: String) {
@@ -0,0 +1,10 @@
package org.jetbrains.kotlin.gradle.plugin
import groovy.lang.Closure
import org.gradle.api.file.SourceDirectorySet
interface KotlinSourceSet {
val kotlin: SourceDirectorySet
fun kotlin(configureClosure: Closure<Any?>?): KotlinSourceSet
}
@@ -0,0 +1,5 @@
package org.jetbrains.kotlin.gradle.plugin
interface KotlinSourceSetProvider {
fun create(displayName: String): KotlinSourceSet
}