From c571c5c441e62f034f6c7c4e8e5deb7824b6c908 Mon Sep 17 00:00:00 2001 From: Yaroslav Chernyshev Date: Fri, 19 Feb 2021 17:45:21 +0300 Subject: [PATCH] Refactor and apply optimization to KaptModelBuilderService logic --- .../src/KotlinGradleModelBuilder.kt | 16 +++---- .../src/KotlinMPPGradleModelBuilder.kt | 40 +---------------- .../src/modelBuilderUtils.kt | 45 +++++++++++++++++++ .../kapt/idea/KaptModelBuilderService.kt | 12 ++--- 4 files changed, 59 insertions(+), 54 deletions(-) create mode 100644 idea/kotlin-gradle-tooling/src/modelBuilderUtils.kt diff --git a/idea/kotlin-gradle-tooling/src/KotlinGradleModelBuilder.kt b/idea/kotlin-gradle-tooling/src/KotlinGradleModelBuilder.kt index ca051efb907..70f6b1f00f7 100644 --- a/idea/kotlin-gradle-tooling/src/KotlinGradleModelBuilder.kt +++ b/idea/kotlin-gradle-tooling/src/KotlinGradleModelBuilder.kt @@ -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? { return try { - javaClass.getDeclaredMethod(methodName).invoke(this) as List + this[methodName] as? List } 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() - 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 diff --git a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt index f9922037032..14385dd789d 100644 --- a/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt +++ b/idea/kotlin-gradle-tooling/src/KotlinMPPGradleModelBuilder.kt @@ -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>, params: List): 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) ?: 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? { - 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)?.asMap?.values ?: emptyList() - } - - fun getCompilations(target: Named): Collection? { - val getCompilationsMethod = target.javaClass.getMethodOrNull("getCompilations") ?: return null - @Suppress("UNCHECKED_CAST") - return (getCompilationsMethod.invoke(target) as? NamedDomainObjectContainer)?.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) - } } } diff --git a/idea/kotlin-gradle-tooling/src/modelBuilderUtils.kt b/idea/kotlin-gradle-tooling/src/modelBuilderUtils.kt new file mode 100644 index 00000000000..36dc8419782 --- /dev/null +++ b/idea/kotlin-gradle-tooling/src/modelBuilderUtils.kt @@ -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>, params: List): 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? = project.extensions.findByName("kotlin")?.let { kotlinExt -> + @Suppress("UNCHECKED_CAST") + (kotlinExt["getTargets"] as? NamedDomainObjectContainer)?.asMap?.values +} + +@Suppress("UNCHECKED_CAST") +val Named.compilations: Collection? + get() = (this["getCompilations"] as? NamedDomainObjectContainer)?.asMap?.values + +fun Named.getCompileKotlinTaskName(project: Project): Task? = (this["getCompileKotlinTaskName"] as? String)?.let { project.tasks.findByName(it) } + diff --git a/idea/kotlin-gradle-tooling/src/org/jetbrains/kotlin/kapt/idea/KaptModelBuilderService.kt b/idea/kotlin-gradle-tooling/src/org/jetbrains/kotlin/kapt/idea/KaptModelBuilderService.kt index 91af2737213..27b527ce6e9 100644 --- a/idea/kotlin-gradle-tooling/src/org/jetbrains/kotlin/kapt/idea/KaptModelBuilderService.kt +++ b/idea/kotlin-gradle-tooling/src/org/jetbrains/kotlin/kapt/idea/KaptModelBuilderService.kt @@ -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) }