Refactor and apply optimization to KaptModelBuilderService logic

This commit is contained in:
Yaroslav Chernyshev
2021-02-19 17:45:21 +03:00
parent 7ef136d142
commit c571c5c441
4 changed files with 59 additions and 54 deletions
@@ -9,7 +9,6 @@ import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ProjectDependency
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder.Companion.getTargets
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
import java.io.File
@@ -124,7 +123,7 @@ class KotlinGradleModelBuilder : AbstractKotlinGradleModelBuilder() {
@Suppress("UNCHECKED_CAST")
private fun Task.getCompilerArguments(methodName: String): List<String>? {
return try {
javaClass.getDeclaredMethod(methodName).invoke(this) as List<String>
this[methodName] as? List<String>
} catch (e: Exception) {
// No argument accessor method is available
null
@@ -166,9 +165,9 @@ class KotlinGradleModelBuilder : AbstractKotlinGradleModelBuilder() {
override fun buildAll(modelName: String?, project: Project): KotlinGradleModelImpl? {
val kotlinPluginId = kotlinPluginIds.singleOrNull { project.plugins.findPlugin(it) != null }
val platformPluginId = platformPluginIds.singleOrNull { project.plugins.findPlugin(it) != null }
val targets = project.getTargets(includeSinglePlatform = true)
val target = project.getTarget()
if (kotlinPluginId == null && platformPluginId == null && targets == null) {
if (kotlinPluginId == null && platformPluginId == null && target == null) {
return null
}
@@ -176,12 +175,9 @@ class KotlinGradleModelBuilder : AbstractKotlinGradleModelBuilder() {
val extraProperties = HashMap<String, KotlinTaskProperties>()
val kotlinCompileTasks = if (targets != null) {
targets.flatMap { target -> KotlinMPPGradleModelBuilder.getCompilations(target) ?: emptyList() }
.mapNotNull { compilation -> KotlinMPPGradleModelBuilder.getCompileKotlinTaskName(project, compilation) }
} else {
project.getAllTasks(false)[project]?.filter { it.javaClass.name in kotlinCompileTaskClasses } ?: emptyList()
}
val kotlinCompileTasks = target?.let { it.compilations ?: emptyList() }
?.mapNotNull { compilation -> compilation.getCompileKotlinTaskName(project) }
?: (project.getAllTasks(false)[project]?.filter { it.javaClass.name in kotlinCompileTaskClasses } ?: emptyList())
kotlinCompileTasks.forEach { compileTask ->
if (compileTask.javaClass.name !in kotlinCompileTaskClasses) return@forEach
@@ -256,15 +256,6 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
return projectTargets.mapNotNull { buildTarget(importingContext, it, dependencyResolver, dependencyMapper) }
}
private operator fun Any?.get(methodName: String, vararg params: Any): Any? {
return this[methodName, params.map { it.javaClass }, params.toList()]
}
private operator fun Any?.get(methodName: String, paramTypes: List<Class<*>>, params: List<Any?>): Any? {
if (this == null) return null
return this::class.java.getMethodOrNull(methodName, *paramTypes.toTypedArray())?.invoke(this, *params.toTypedArray())
}
private fun buildArtifact(
executableName: String,
linkTask: Task,
@@ -334,7 +325,7 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
"${e::class.java.name}:${e.message}"
}
val gradleCompilations = getCompilations(gradleTarget) ?: return null
val gradleCompilations = gradleTarget.compilations ?: return null
val compilations = gradleCompilations.mapNotNull {
val compilation = buildCompilation(importingContext, it, disambiguationClassifier, dependencyResolver, dependencyMapper)
if (compilation == null || platform != KotlinPlatform.ANDROID) {
@@ -510,7 +501,7 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
@Suppress("UNCHECKED_CAST")
val kotlinGradleSourceSets = (getKotlinSourceSets(gradleCompilation) as? Collection<Named>) ?: return null
val kotlinSourceSets = kotlinGradleSourceSets.mapNotNull { importingContext.sourceSetByName(it.name) }
val compileKotlinTask = getCompileKotlinTaskName(importingContext.project, gradleCompilation) ?: return null
val compileKotlinTask = gradleCompilation.getCompileKotlinTaskName(importingContext.project) ?: return null
val output = buildCompilationOutput(gradleCompilation, compileKotlinTask) ?: return null
val arguments = buildCompilationArguments(compileKotlinTask)
val dependencyClasspath = buildDependencyClasspath(compileKotlinTask)
@@ -918,33 +909,6 @@ class KotlinMPPGradleModelBuilder : ModelBuilderService {
it.check(this@collectDiagnostics, this, importingContext)
}
}
fun Project.getTargets(includeSinglePlatform: Boolean = false): Collection<Named>? {
val kotlinExt = project.extensions.findByName("kotlin") ?: return null
val getTargets = kotlinExt.javaClass.getMethodOrNull("getTargets")
if (getTargets == null && includeSinglePlatform) {
val getTarget = kotlinExt.javaClass.getMethodOrNull("getTarget")
val target = getTarget?.invoke(kotlinExt) as? Named
return if (target == null) emptyList() else listOf(target)
}
@Suppress("UNCHECKED_CAST")
return (getTargets?.invoke(kotlinExt) as? NamedDomainObjectContainer<Named>)?.asMap?.values ?: emptyList()
}
fun getCompilations(target: Named): Collection<Named>? {
val getCompilationsMethod = target.javaClass.getMethodOrNull("getCompilations") ?: return null
@Suppress("UNCHECKED_CAST")
return (getCompilationsMethod.invoke(target) as? NamedDomainObjectContainer<Named>)?.asMap?.values ?: emptyList()
}
fun getCompileKotlinTaskName(project: Project, compilation: Named): Task? {
val compilationClass = compilation.javaClass
val getCompileKotlinTaskName = compilationClass.getMethodOrNull("getCompileKotlinTaskName") ?: return null
@Suppress("UNCHECKED_CAST")
val compileKotlinTaskName = (getCompileKotlinTaskName(compilation) as? String) ?: return null
return project.tasks.findByName(compileKotlinTaskName)
}
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* 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
import org.gradle.api.Named
import org.gradle.api.NamedDomainObjectContainer
import org.gradle.api.Project
import org.gradle.api.Task
private val kotlinSingleTargetExtensionClassNames = listOf(
"org.jetbrains.kotlin.gradle.dsl.KotlinAndroidProjectExtension_Decorated",
"org.jetbrains.kotlin.gradle.dsl.KotlinJsProjectExtension_Decorated",
"org.jetbrains.kotlin.gradle.dsl.KotlinCommonProjectExtension_Decorated",
"org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension_Decorated",
"org.jetbrains.kotlin.gradle.dsl.Kotlin2JsProjectExtension_Decorated",
)
operator fun Any?.get(methodName: String, vararg params: Any): Any? {
return this[methodName, params.map { it.javaClass }, params.toList()]
}
operator fun Any?.get(methodName: String, paramTypes: List<Class<*>>, params: List<Any?>): Any? {
if (this == null) return null
return this::class.java.getMethodOrNull(methodName, *paramTypes.toTypedArray())?.invoke(this, *params.toTypedArray())
}
fun Project.getTarget(): Named? = project.extensions.findByName("kotlin")?.let { kotlinExt ->
if (kotlinExt.javaClass.name in kotlinSingleTargetExtensionClassNames) kotlinExt["getTarget"] as? Named
else null
}
fun Project.getTargets(): Collection<Named>? = project.extensions.findByName("kotlin")?.let { kotlinExt ->
@Suppress("UNCHECKED_CAST")
(kotlinExt["getTargets"] as? NamedDomainObjectContainer<Named>)?.asMap?.values
}
@Suppress("UNCHECKED_CAST")
val Named.compilations: Collection<Named>?
get() = (this["getCompilations"] as? NamedDomainObjectContainer<Named>)?.asMap?.values
fun Named.getCompileKotlinTaskName(project: Project): Task? = (this["getCompileKotlinTaskName"] as? String)?.let { project.tasks.findByName(it) }
@@ -9,9 +9,7 @@ import org.gradle.api.Named
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.Task
import org.jetbrains.kotlin.gradle.AbstractKotlinGradleModelBuilder
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder
import org.jetbrains.kotlin.gradle.KotlinMPPGradleModelBuilder.Companion.getTargets
import org.jetbrains.kotlin.gradle.*
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
import java.io.File
import java.io.Serializable
@@ -90,15 +88,17 @@ class KaptModelBuilderService : AbstractKotlinGradleModelBuilder() {
continue
}
val compilations = KotlinMPPGradleModelBuilder.getCompilations(target) ?: continue
val compilations = target.compilations ?: continue
for (compilation in compilations) {
val compileTask = KotlinMPPGradleModelBuilder.getCompileKotlinTaskName(project, compilation) ?: continue
val compileTask = compilation.getCompileKotlinTaskName(project) ?: continue
val moduleName = target.name + compilation.name.capitalize()
handleCompileTask(moduleName, compileTask)
}
}
} else {
project.getAllTasks(false)[project]?.forEach { compileTask ->
val compileTasks = project.getTarget()?.compilations?.map { compilation -> compilation.getCompileKotlinTaskName(project) }
?: project.getAllTasks(false)[project]
compileTasks?.forEach{ compileTask ->
val sourceSetName = compileTask.getSourceSetName()
handleCompileTask(sourceSetName, compileTask)
}