Refactoring: remove remainings of custom classloader in gradle plugin

This commit is contained in:
Alexey Tsvetkov
2016-07-28 18:59:11 +03:00
parent aa91b5a1b0
commit f297de401c
5 changed files with 33 additions and 65 deletions
@@ -22,13 +22,16 @@ import org.gradle.api.UnknownDomainObjectException
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.gradle.plugin.*
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.kapt.generateAnnotationProcessorWrapper
import org.jetbrains.kotlin.gradle.tasks.kapt.generateKotlinAptAnnotation
import java.io.File
import java.io.IOException
import java.util.*
import java.util.zip.ZipFile
fun Project.initKapt(
kotlinTask: AbstractCompile,
kotlinTask: KotlinCompile,
javaTask: AbstractCompile,
kaptManager: AnnotationProcessingManager,
variantName: String,
@@ -129,7 +132,6 @@ public class AnnotationProcessingManager(
private val aptFiles: Set<File>,
val aptOutputDir: File,
private val aptWorkingDir: File,
private val coreClassLoader: ClassLoader,
private val androidVariant: Any? = null) {
private val project = task.project
@@ -223,19 +225,19 @@ public class AnnotationProcessingManager(
}
private fun generateAnnotationProcessorStubs(javaTask: JavaCompile, processorFqNames: Set<String>, outputDir: File) {
val aptAnnotationFile = invokeCoreKaptMethod("generateKotlinAptAnnotation", outputDir) as File
val aptAnnotationFile = generateKotlinAptAnnotation(outputDir)
project.logger.kotlinDebug("kapt: Stub annotation generated: $aptAnnotationFile")
val stubOutputPackageDir = File(outputDir, "__gen")
stubOutputPackageDir.mkdirs()
for (processorFqName in processorFqNames) {
val wrapperFile = invokeCoreKaptMethod("generateAnnotationProcessorWrapper",
val wrapperFile = generateAnnotationProcessorWrapper(
processorFqName,
"__gen",
stubOutputPackageDir,
getProcessorStubClassName(processorFqName),
taskQualifier) as File
taskQualifier)
project.logger.kotlinDebug("kapt: Wrapper for $processorFqName generated: $wrapperFile")
}
@@ -348,16 +350,4 @@ public class AnnotationProcessingManager(
project.logger.kotlinDebug("kapt: Discovered annotation processors: ${annotationProcessors.joinToString()}")
return annotationProcessors
}
private fun invokeCoreKaptMethod(methodName: String, vararg args: Any): Any {
val array = arrayOfNulls<Class<*>>(args.size)
args.forEachIndexed { i, arg -> array[i] = arg.javaClass }
val method = getCoreKaptPackageClass().getMethod(methodName, *array)
return method.invoke(null, *args)
}
private fun getCoreKaptPackageClass(): Class<*> {
return Class.forName("org.jetbrains.kotlin.gradle.tasks.kapt.KaptStubGeneratorUtilsKt", false, coreClassLoader)
}
}
@@ -33,13 +33,13 @@ private fun comparableVersionStr(version: String) =
?.let { if (it.all { (it?.value?.length ?: 0).let { it > 0 && it < 4 }}) it else null }
?.joinToString(".", transform = { it!!.value.padStart(3, '0') })
class CleanUpBuildListener(pluginClassLoader: ClassLoader, private val project: Project) : BuildAdapter() {
class CleanUpBuildListener(private val project: Project) : BuildAdapter() {
companion object {
const val FORCE_SYSTEM_GC_MESSAGE = "Forcing System.gc()"
}
private val log = Logging.getLogger(this.javaClass)
private val cleanup = CompilerServicesCleanup(pluginClassLoader)
private val cleanup = CompilerServicesCleanup()
private var startMemory: Long? = null
// There is function with the same name in BuildAdapter,
@@ -93,12 +93,10 @@ class CleanUpBuildListener(pluginClassLoader: ClassLoader, private val project:
}
class CompilerServicesCleanup(private var pluginClassLoader: ClassLoader?) {
class CompilerServicesCleanup() {
val log = Logging.getLogger(this.javaClass)
operator fun invoke(gradleVersion: String) {
assert(pluginClassLoader != null)
log.kotlinDebug("compiler services cleanup")
// clearing jar cache to avoid problems like KT-9440 (unable to clean/rebuild a project due to locked jar file)
@@ -125,8 +123,6 @@ class CompilerServicesCleanup(private var pluginClassLoader: ClassLoader?) {
stopZipFileCache()
}
}
pluginClassLoader = null
}
private fun stopZipFileCache() {
@@ -138,7 +134,7 @@ class CompilerServicesCleanup(private var pluginClassLoader: ClassLoader?) {
val shortName = classFqName.substring(classFqName.lastIndexOf('.') + 1)
log.kotlinDebug("Looking for $shortName class")
val cls = pluginClassLoader!!.loadClass(classFqName)
val cls = Class.forName(classFqName)
log.kotlinDebug("Looking for $methodName() method")
val method = cls.getMethod(methodName)
@@ -27,11 +27,14 @@ import org.gradle.api.tasks.Delete
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.tasks.compile.JavaCompile
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
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.plugin.android.AndroidGradleWrapper
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinTasksProvider
import org.jetbrains.kotlin.gradle.tasks.SyncOutputTask
import java.io.File
@@ -120,7 +123,7 @@ class Kotlin2JvmSourceSetProcessor(
sourceSet: SourceSet,
val scriptHandler: ScriptHandler,
tasksProvider: KotlinTasksProvider
) : KotlinSourceSetProcessor<AbstractCompile>(
) : KotlinSourceSetProcessor<KotlinCompile>(
project, javaBasePlugin, sourceSet, tasksProvider,
pluginName = "kotlin",
compileTaskNameSuffix = "kotlin",
@@ -131,7 +134,7 @@ class Kotlin2JvmSourceSetProcessor(
private var cachedKotlinAnnotationProcessingDep: String? = null
}
override fun doCreateTask(project: Project, taskName: String): AbstractCompile =
override fun doCreateTask(project: Project, taskName: String): KotlinCompile =
tasksProvider.createKotlinJVMTask(project, taskName)
override fun doTargetSpecificProcessing() {
@@ -166,7 +169,7 @@ class Kotlin2JvmSourceSetProcessor(
val (aptOutputDir, aptWorkingDir) = project.getAptDirsForSourceSet(sourceSetName)
val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, sourceSetName,
aptConfiguration.resolve(), aptOutputDir, aptWorkingDir, tasksProvider.tasksLoader)
aptConfiguration.resolve(), aptOutputDir, aptWorkingDir)
kotlinAfterJavaTask = project.initKapt(kotlinTask, javaTask, kaptManager,
sourceSetName, null, subpluginEnvironment) {
@@ -193,7 +196,7 @@ class Kotlin2JsSourceSetProcessor(
sourceSet: SourceSet,
val scriptHandler: ScriptHandler,
tasksProvider: KotlinTasksProvider
) : KotlinSourceSetProcessor<AbstractCompile>(
) : KotlinSourceSetProcessor<Kotlin2JsCompile>(
project, javaBasePlugin, sourceSet, tasksProvider,
pluginName = "kotlin2js",
taskDescription = "Compiles the kotlin sources in $sourceSet to JavaScript.",
@@ -215,7 +218,7 @@ class Kotlin2JsSourceSetProcessor(
private fun shouldGenerateSourceMap() = kotlinTask.property("sourceMap")
override fun doCreateTask(project: Project, taskName: String): AbstractCompile =
override fun doCreateTask(project: Project, taskName: String): Kotlin2JsCompile =
tasksProvider.createKotlinJSTask(project, taskName)
override fun doTargetSpecificProcessing() {
@@ -325,7 +328,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
})
val extensions = (ext as ExtensionAware).extensions
extensions.add("kotlinOptions", tasksProvider.kotlinJVMOptionsClass)
extensions.add("kotlinOptions", K2JVMCompilerArguments::class.java)
AndroidGradleWrapper.setNoJdk(extensions.getByName("kotlinOptions"))
project.createKaptExtension()
@@ -437,7 +440,7 @@ open class KotlinAndroidPlugin @Inject constructor(val scriptHandler: ScriptHand
if (javaTask is JavaCompile && aptFiles.isNotEmpty()) {
val kaptManager = AnnotationProcessingManager(kotlinTask, javaTask, variantDataName,
aptFiles.toSet(), aptOutputDir, aptWorkingDir, tasksProvider.tasksLoader, variantData)
aptFiles.toSet(), aptOutputDir, aptWorkingDir, variantData)
kotlinTask.storeKaptAnnotationsFile(kaptManager)
@@ -27,15 +27,15 @@ abstract class KotlinBasePluginWrapper: Plugin<Project> {
val kotlinPluginVersion = loadKotlinVersionFromResource(log)
project.extensions.extraProperties?.set("kotlin.gradle.plugin.version", kotlinPluginVersion)
val plugin = getPlugin(this.javaClass.classLoader, sourceBuildScript)
val plugin = getPlugin(sourceBuildScript)
plugin.apply(project)
val cleanUpBuildListener = CleanUpBuildListener(this.javaClass.classLoader, project)
val cleanUpBuildListener = CleanUpBuildListener(project)
cleanUpBuildListener.buildStarted()
project.gradle.addBuildListener(cleanUpBuildListener)
}
protected abstract fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler): Plugin<Project>
protected abstract fun getPlugin(scriptHandler: ScriptHandler): Plugin<Project>
private fun findSourceBuildScript(project: Project): ScriptHandler? {
log.kotlinDebug("Looking for proper script handler")
@@ -56,15 +56,15 @@ abstract class KotlinBasePluginWrapper: Plugin<Project> {
}
open class KotlinPluginWrapper: KotlinBasePluginWrapper() {
override fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler) = KotlinPlugin(scriptHandler, KotlinTasksProvider(pluginClassLoader))
override fun getPlugin(scriptHandler: ScriptHandler) = KotlinPlugin(scriptHandler, KotlinTasksProvider())
}
open class KotlinAndroidPluginWrapper : KotlinBasePluginWrapper() {
override fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler) = KotlinAndroidPlugin(scriptHandler, AndroidTasksProvider(pluginClassLoader))
override fun getPlugin(scriptHandler: ScriptHandler) = KotlinAndroidPlugin(scriptHandler, AndroidTasksProvider())
}
open class Kotlin2JsPluginWrapper : KotlinBasePluginWrapper() {
override fun getPlugin(pluginClassLoader: ClassLoader, scriptHandler: ScriptHandler) = Kotlin2JsPlugin(scriptHandler, KotlinTasksProvider(pluginClassLoader))
override fun getPlugin(scriptHandler: ScriptHandler) = Kotlin2JsPlugin(scriptHandler, KotlinTasksProvider())
}
fun Logger.kotlinDebug(message: String) {
@@ -1,45 +1,24 @@
package org.jetbrains.kotlin.gradle.tasks
import org.gradle.api.tasks.compile.AbstractCompile
import org.gradle.api.Task
import org.gradle.api.Project
import org.gradle.api.tasks.SourceTask
import org.jetbrains.kotlin.gradle.plugin.RegexTaskToFriendTaskMapper
import org.jetbrains.kotlin.gradle.plugin.TaskToFriendTaskMapper
import org.jetbrains.kotlin.gradle.plugin.friendTaskName
import java.net.URLClassLoader
/**
* Tasks provider to be used wrapper
* Created by Nikita.Skvortsov
* date: 17.12.2014.
*/
open class KotlinTasksProvider(val tasksLoader: ClassLoader) {
val kotlinJVMCompileTaskClass: Class<AbstractCompile> =
tasksLoader.loadClass("org.jetbrains.kotlin.gradle.tasks.KotlinCompile") as Class<AbstractCompile>
val kotlinJSCompileTaskClass: Class<AbstractCompile> =
tasksLoader.loadClass("org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile") as Class<AbstractCompile>
val kotlinJVMOptionsClass: Class<Any> =
tasksLoader.loadClass("org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments") as Class<Any>
fun createKotlinJVMTask(project: Project, name: String): AbstractCompile {
return project.tasks.create(name, kotlinJVMCompileTaskClass).apply {
open class KotlinTasksProvider {
fun createKotlinJVMTask(project: Project, name: String): KotlinCompile {
return project.tasks.create(name, KotlinCompile::class.java).apply {
friendTaskName = taskToFriendTaskMapper[this]
}
}
fun createKotlinJSTask(project: Project, name: String): AbstractCompile {
return project.tasks.create(name, kotlinJSCompileTaskClass)
}
fun createKotlinJSTask(project: Project, name: String): Kotlin2JsCompile =
project.tasks.create(name, Kotlin2JsCompile::class.java)
protected open val taskToFriendTaskMapper: TaskToFriendTaskMapper =
RegexTaskToFriendTaskMapper.Default()
}
class AndroidTasksProvider(tasksLoader: ClassLoader) : KotlinTasksProvider(tasksLoader) {
class AndroidTasksProvider : KotlinTasksProvider() {
override val taskToFriendTaskMapper: TaskToFriendTaskMapper =
RegexTaskToFriendTaskMapper.Android()
}