(partial) Replace the KotlinSourceSet implementation and its factory
(Note: this commit leaves the repository in a non-compilable state as it leaves some of the old API usages unchanged; they are replaced with new implementations in further commits where more appropriate) The new implementation covers the wider interface, and the factory should now be used not on its own but in a named domain object container (the API for creating a source set is now provided through the source sets container rather than the factory, so that source sets are also properly registered).
This commit is contained in:
+9
-1
@@ -25,9 +25,17 @@ internal fun Project.createKotlinExtension(extensionClass: KClass<out KotlinProj
|
||||
DslObject(kotlinExt).extensions.create("experimental", ExperimentalExtension::class.java)
|
||||
}
|
||||
|
||||
internal val Project.kotlinExtension: KotlinProjectExtension
|
||||
get() = extensions.getByName(KOTLIN_PROJECT_EXTENSION_NAME) as KotlinProjectExtension
|
||||
|
||||
open class KotlinProjectExtension {
|
||||
val experimental: ExperimentalExtension
|
||||
get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java)!!
|
||||
get() = DslObject(this).extensions.getByType(ExperimentalExtension::class.java)
|
||||
|
||||
var sourceSets: NamedDomainObjectContainer<out KotlinSourceSet>
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
get() = DslObject(this).extensions.getByName("sourceSets") as NamedDomainObjectContainer<out KotlinSourceSet>
|
||||
internal set(value) { DslObject(this).extensions.add("sourceSets", value) }
|
||||
}
|
||||
|
||||
open class KotlinJvmProjectExtension : KotlinProjectExtension() {
|
||||
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.internal
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.internal.file.DefaultSourceDirectorySet
|
||||
import org.gradle.api.internal.file.FileResolver
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSetProvider
|
||||
import java.lang.reflect.Constructor
|
||||
|
||||
internal class KotlinSourceSetProviderImpl constructor(private val fileResolver: FileResolver) : KotlinSourceSetProvider {
|
||||
override fun create(displayName: String): KotlinSourceSet =
|
||||
KotlinSourceSetImpl(displayName, fileResolver)
|
||||
}
|
||||
|
||||
private class KotlinSourceSetImpl(displayName: String, resolver: FileResolver) : KotlinSourceSet {
|
||||
override val kotlin: SourceDirectorySet =
|
||||
createDefaultSourceDirectorySet(displayName + " Kotlin source", resolver)
|
||||
|
||||
init {
|
||||
kotlin.filter?.include("**/*.java", "**/*.kt", "**/*.kts")
|
||||
}
|
||||
|
||||
override fun kotlin(configureClosure: Closure<Any?>?): KotlinSourceSet {
|
||||
ConfigureUtil.configure(configureClosure, kotlin)
|
||||
return this
|
||||
}
|
||||
}
|
||||
|
||||
private val createDefaultSourceDirectorySet: (name: String?, resolver: FileResolver?) -> SourceDirectorySet = run {
|
||||
val klass = DefaultSourceDirectorySet::class.java
|
||||
val defaultConstructor = klass.constructorOrNull(String::class.java, FileResolver::class.java)
|
||||
|
||||
if (defaultConstructor != null && defaultConstructor.getAnnotation(java.lang.Deprecated::class.java) == null) {
|
||||
// TODO: drop when gradle < 2.12 are obsolete
|
||||
{ name, resolver -> defaultConstructor.newInstance(name, resolver) }
|
||||
}
|
||||
else {
|
||||
val directoryFileTreeFactoryClass = Class.forName("org.gradle.api.internal.file.collections.DirectoryFileTreeFactory")
|
||||
val alternativeConstructor = klass.getConstructor(String::class.java, FileResolver::class.java, directoryFileTreeFactoryClass)
|
||||
|
||||
val defaultFileTreeFactoryClass = Class.forName("org.gradle.api.internal.file.collections.DefaultDirectoryFileTreeFactory")
|
||||
val defaultFileTreeFactory = defaultFileTreeFactoryClass.getConstructor().newInstance()
|
||||
return@run { name, resolver -> alternativeConstructor.newInstance(name, resolver, defaultFileTreeFactory) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> Class<T>.constructorOrNull(vararg parameterTypes: Class<*>): Constructor<T>? =
|
||||
try {
|
||||
getConstructor(*parameterTypes)
|
||||
}
|
||||
catch (e: NoSuchMethodException) {
|
||||
null
|
||||
}
|
||||
+1
-1
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.gradle.model.impl.KotlinProjectImpl
|
||||
import org.jetbrains.kotlin.gradle.model.impl.SourceSetImpl
|
||||
import org.jetbrains.kotlin.gradle.plugin.KOTLIN_DSL_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KOTLIN_JS_DSL_NAME
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.getConvention
|
||||
import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.tasks.AbstractKotlinCompile
|
||||
|
||||
/**
|
||||
|
||||
+7
-3
@@ -511,9 +511,13 @@ abstract class AbstractAndroidProjectHandler<V>(private val kotlinConfigurationT
|
||||
val aptConfigurations = hashMapOf<String, Configuration>()
|
||||
|
||||
ext.sourceSets.all { sourceSet ->
|
||||
logger.kotlinDebug("Creating KotlinSourceSet for source set $sourceSet")
|
||||
val kotlinSourceSet = kotlinConfigurationTools.kotlinSourceSetProvider.create(sourceSet.name)
|
||||
kotlinSourceSet.kotlin.srcDir(project.file(project.file("src/${sourceSet.name}/kotlin")))
|
||||
logger.kotlinDebug("Creating KotlinBaseSourceSet for source set $sourceSet")
|
||||
val kotlinSourceSet = project.kotlinExtension.sourceSets.maybeCreate(
|
||||
lowerCamelCaseName(kotlinAndroidTarget.disambiguationClassifier, sourceSet.name)
|
||||
).apply {
|
||||
kotlin.srcDir(project.file(project.file("src/${sourceSet.name}/kotlin")))
|
||||
kotlin.srcDirs(sourceSet.java.srcDirs)
|
||||
}
|
||||
sourceSet.addConvention(KOTLIN_DSL_NAME, kotlinSourceSet)
|
||||
Kapt3KotlinGradleSubplugin.createAptConfigurationIfNeeded(project, sourceSet.name)
|
||||
}
|
||||
|
||||
+12
-2
@@ -37,6 +37,11 @@ abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver)
|
||||
private val log = Logging.getLogger(this.javaClass)
|
||||
val kotlinPluginVersion = loadKotlinVersionFromResource(log)
|
||||
|
||||
open val projectExtensionClass: KClass<out KotlinProjectExtension> get() = KotlinProjectExtension::class
|
||||
|
||||
internal open fun kotlinSourceSetFactory(project: Project): KotlinSourceSetFactory<out KotlinSourceSet> =
|
||||
DefaultKotlinSourceSetFactory(project, fileResolver)
|
||||
|
||||
override fun apply(project: Project) {
|
||||
project.configurations.maybeCreate(COMPILER_CLASSPATH_CONFIGURATION_NAME).defaultDependencies {
|
||||
it.add(project.dependencies.create("$KOTLIN_MODULE_GROUP:$KOTLIN_COMPILER_EMBEDDABLE:$kotlinPluginVersion"))
|
||||
@@ -50,9 +55,14 @@ abstract class KotlinBasePluginWrapper(protected val fileResolver: FileResolver)
|
||||
System.setProperty(org.jetbrains.kotlin.cli.common.KOTLIN_COMPILER_ENVIRONMENT_KEEPALIVE_PROPERTY, "true")
|
||||
val kotlinGradleBuildServices = KotlinGradleBuildServices.getInstance(project.gradle)
|
||||
|
||||
project.createKotlinExtension(projectExtensionClass)
|
||||
project.createKotlinExtension(projectExtensionClass).apply {
|
||||
fun <T : KotlinSourceSet> kotlinSourceSetContainer(factory: KotlinSourceSetFactory<T>) =
|
||||
project.container(factory.itemClass, factory)
|
||||
|
||||
val plugin = getPlugin(kotlinGradleBuildServices)
|
||||
project.kotlinExtension.sourceSets = kotlinSourceSetContainer(kotlinSourceSetFactory(project))
|
||||
}
|
||||
|
||||
val plugin = getPlugin(project, kotlinGradleBuildServices)
|
||||
plugin.apply(project)
|
||||
}
|
||||
|
||||
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.gradle.plugin
|
||||
|
||||
internal interface KotlinSourceSetProvider {
|
||||
fun create(displayName: String): KotlinSourceSet
|
||||
}
|
||||
+85
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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.plugin.sources
|
||||
|
||||
import groovy.lang.Closure
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.file.SourceDirectorySet
|
||||
import org.gradle.api.internal.file.DefaultSourceDirectorySet
|
||||
import org.gradle.api.internal.file.FileResolver
|
||||
import org.gradle.util.ConfigureUtil
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.plugin.mpp.DefaultKotlinDependencyHandler
|
||||
import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet
|
||||
import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSetWithResources
|
||||
import org.jetbrains.kotlin.gradle.utils.lowerCamelCaseName
|
||||
import java.lang.reflect.Constructor
|
||||
|
||||
class DefaultKotlinSourceSet(
|
||||
private val project: Project,
|
||||
val displayName: String,
|
||||
fileResolver: FileResolver
|
||||
) : KotlinSourceSetWithResources {
|
||||
|
||||
override val apiConfigurationName: String
|
||||
get() = disambiguateName("api")
|
||||
|
||||
override val implementationConfigurationName: String
|
||||
get() = disambiguateName("implementation")
|
||||
|
||||
override val compileOnlyConfigurationName: String
|
||||
get() = disambiguateName("compileOnly")
|
||||
|
||||
override val runtimeOnlyConfigurationName: String
|
||||
get() = disambiguateName("runtimeOnly")
|
||||
|
||||
override val kotlin: SourceDirectorySet = createDefaultSourceDirectorySet(name + " Kotlin source", fileResolver).apply {
|
||||
filter.include("**/*.java", "**/*.kt", "**/*.kts")
|
||||
}
|
||||
|
||||
override val resources: SourceDirectorySet = createDefaultSourceDirectorySet(displayName + " resources", fileResolver)
|
||||
|
||||
override fun kotlin(configureClosure: Closure<Any?>): SourceDirectorySet = kotlin.apply { ConfigureUtil.configure(configureClosure, this) }
|
||||
|
||||
override fun getName(): String = displayName
|
||||
|
||||
override fun dependencies(configure: KotlinDependencyHandler.() -> Unit): Unit =
|
||||
DefaultKotlinDependencyHandler(this, project).run(configure)
|
||||
|
||||
override fun dependencies(configureClosure: Closure<Any?>) =
|
||||
dependencies f@{ ConfigureUtil.configure(configureClosure, this@f) }
|
||||
|
||||
override fun toString(): String = "source set $name"
|
||||
}
|
||||
|
||||
internal fun KotlinSourceSet.disambiguateName(simpleName: String): String {
|
||||
val nameParts = listOfNotNull(this.name.takeIf { it != "main" }, simpleName)
|
||||
return lowerCamelCaseName(*nameParts.toTypedArray())
|
||||
}
|
||||
|
||||
private val createDefaultSourceDirectorySet: (name: String?, resolver: FileResolver?) -> SourceDirectorySet = run {
|
||||
val klass = DefaultSourceDirectorySet::class.java
|
||||
val defaultConstructor = klass.constructorOrNull(String::class.java, FileResolver::class.java)
|
||||
|
||||
if (defaultConstructor != null && defaultConstructor.getAnnotation(java.lang.Deprecated::class.java) == null) {
|
||||
// TODO: drop when gradle < 2.12 are obsolete
|
||||
{ name, resolver -> defaultConstructor.newInstance(name, resolver) }
|
||||
} else {
|
||||
val directoryFileTreeFactoryClass = Class.forName("org.gradle.api.internal.file.collections.DirectoryFileTreeFactory")
|
||||
val alternativeConstructor = klass.getConstructor(String::class.java, FileResolver::class.java, directoryFileTreeFactoryClass)
|
||||
|
||||
val defaultFileTreeFactoryClass = Class.forName("org.gradle.api.internal.file.collections.DefaultDirectoryFileTreeFactory")
|
||||
val defaultFileTreeFactory = defaultFileTreeFactoryClass.getConstructor().newInstance()
|
||||
return@run { name, resolver -> alternativeConstructor.newInstance(name, resolver, defaultFileTreeFactory) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun <T> Class<T>.constructorOrNull(vararg parameterTypes: Class<*>): Constructor<T>? =
|
||||
try {
|
||||
getConstructor(*parameterTypes)
|
||||
} catch (e: NoSuchMethodException) {
|
||||
null
|
||||
}
|
||||
+55
@@ -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.plugin.sources
|
||||
|
||||
import org.gradle.api.NamedDomainObjectFactory
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.internal.file.FileResolver
|
||||
import org.jetbrains.kotlin.gradle.plugin.source.KotlinSourceSet
|
||||
import java.io.File
|
||||
|
||||
internal abstract class KotlinSourceSetFactory<T : KotlinSourceSet> internal constructor(
|
||||
protected val fileResolver: FileResolver,
|
||||
protected val project: Project
|
||||
) : NamedDomainObjectFactory<T> {
|
||||
|
||||
abstract val itemClass: Class<T>
|
||||
|
||||
override fun create(name: String): T {
|
||||
val result = doCreateSourceSet(name)
|
||||
setUpSourceSetDefaults(result)
|
||||
return result
|
||||
}
|
||||
|
||||
protected open fun defaultSourceLocation(sourceSetName: String): File =
|
||||
project.file("src/$sourceSetName")
|
||||
|
||||
protected open fun setUpSourceSetDefaults(sourceSet: T) {
|
||||
with(sourceSet) {
|
||||
sourceSet.kotlin.srcDir(File(defaultSourceLocation(sourceSet.name), "kotlin"))
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract fun doCreateSourceSet(name: String): T
|
||||
}
|
||||
|
||||
internal class DefaultKotlinSourceSetFactory(
|
||||
project: Project,
|
||||
fileResolver: FileResolver
|
||||
) : KotlinSourceSetFactory<DefaultKotlinSourceSet>(fileResolver, project) {
|
||||
|
||||
override val itemClass: Class<DefaultKotlinSourceSet>
|
||||
get() = DefaultKotlinSourceSet::class.java
|
||||
|
||||
override fun setUpSourceSetDefaults(sourceSet: DefaultKotlinSourceSet) {
|
||||
super.setUpSourceSetDefaults(sourceSet)
|
||||
sourceSet.resources.srcDir(File(defaultSourceLocation(sourceSet.name), "resources"))
|
||||
}
|
||||
|
||||
override fun doCreateSourceSet(name: String): DefaultKotlinSourceSet {
|
||||
return DefaultKotlinSourceSet(project, name, fileResolver)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user