From 9738e552e77da45fc650e8212b6d967f711e8b86 Mon Sep 17 00:00:00 2001 From: Karima Ichou Date: Fri, 28 Jun 2024 13:59:33 +0100 Subject: [PATCH] KTIJ-30051 Add extension for Common modules RCS producers This change will allow for multiple producers that apply for common modules to be showns in the menu when trying to run tests closes https://github.com/JetBrains/intellij-community/pull/2798 GitOrigin-RevId: 85af3b15d604e488437b3beaaab9e3f8994aa73c --- .../actions/ConfigurationFromContext.java | 4 ++++ .../resources/kotlin.gradle.gradle-java.xml | 12 ++++++++++++ ...linMultiplatformCommonProducersProvider.kt | 19 +++++++++++++++++++ .../idea/gradleJava/run/jvmTestClassUtils.kt | 8 ++++++++ ...formAllInDirectoryConfigurationProducer.kt | 12 ++++++++++-- ...atformAllInPackageConfigurationProducer.kt | 15 ++++++++++++--- ...monTestClassGradleConfigurationProducer.kt | 18 +++++++++++++++++- ...onTestMethodGradleConfigurationProducer.kt | 18 +++++++++++++++++- 8 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/extensions/KotlinMultiplatformCommonProducersProvider.kt diff --git a/platform/lang-api/src/com/intellij/execution/actions/ConfigurationFromContext.java b/platform/lang-api/src/com/intellij/execution/actions/ConfigurationFromContext.java index 60a03a8edc84..3e5444ced855 100644 --- a/platform/lang-api/src/com/intellij/execution/actions/ConfigurationFromContext.java +++ b/platform/lang-api/src/com/intellij/execution/actions/ConfigurationFromContext.java @@ -142,6 +142,10 @@ public abstract class ConfigurationFromContext { if (PsiTreeUtil.isAncestor(configuration2.getSourceElement(), configuration1.getSourceElement(), true)) { return -1; } + // If neither configuration1 nor configuration2 are preferred to each other, then these are considered equal. + if (!configuration1.isPreferredTo(configuration2) && !configuration2.isPreferredTo(configuration1)) { + return 0; + } if (!configuration1.isPreferredTo(configuration2)) { return 1; } diff --git a/plugins/kotlin/gradle/gradle-java/resources/kotlin.gradle.gradle-java.xml b/plugins/kotlin/gradle/gradle-java/resources/kotlin.gradle.gradle-java.xml index 302d2a448ab5..22c7f865bfbb 100644 --- a/plugins/kotlin/gradle/gradle-java/resources/kotlin.gradle.gradle-java.xml +++ b/plugins/kotlin/gradle/gradle-java/resources/kotlin.gradle.gradle-java.xml @@ -24,6 +24,11 @@ qualifiedName="org.jetbrains.kotlin.mppProjectResolve" interface="org.jetbrains.kotlin.idea.gradleJava.configuration.mpp.KotlinMppGradleProjectResolverExtension" dynamic="true"/> + + @@ -143,6 +148,13 @@ + + + + + + + diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/extensions/KotlinMultiplatformCommonProducersProvider.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/extensions/KotlinMultiplatformCommonProducersProvider.kt new file mode 100644 index 000000000000..730cc729740a --- /dev/null +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/extensions/KotlinMultiplatformCommonProducersProvider.kt @@ -0,0 +1,19 @@ +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +package org.jetbrains.kotlin.idea.gradleJava.extensions + +import com.intellij.execution.actions.ConfigurationFromContext +import com.intellij.openapi.extensions.ExtensionPointName + +/** + * Common interface for Run configurations producers that apply to multiplatform modules. + * This interface must be implemented by every producer that apply to multiplatform modules. + */ +interface KotlinMultiplatformCommonProducersProvider { + companion object { + val EP_NAME: ExtensionPointName = + ExtensionPointName.create("org.jetbrains.kotlin.idea.gradleJava.kotlinMultiplatformProducersProvider") + } + + fun isProducedByCommonProducer(configuration: ConfigurationFromContext): Boolean + +} \ No newline at end of file diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/run/jvmTestClassUtils.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/run/jvmTestClassUtils.kt index 4acdcd68f9ce..8b5c01f9a10a 100644 --- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/run/jvmTestClassUtils.kt +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/run/jvmTestClassUtils.kt @@ -9,6 +9,7 @@ import com.intellij.psi.PsiClass import com.intellij.psi.PsiMethod import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.idea.extensions.KotlinTestFrameworkProvider +import org.jetbrains.kotlin.idea.gradleJava.extensions.KotlinMultiplatformCommonProducersProvider internal fun ConfigurationFromContext.isJpsJunitConfiguration(): Boolean { for (extension in KotlinTestFrameworkProvider.EP_NAME.extensionList) { @@ -21,6 +22,13 @@ internal fun ConfigurationFromContext.isJpsJunitConfiguration(): Boolean { return isProducedBy(AbstractPatternBasedConfigurationProducer::class.java) } +fun ConfigurationFromContext.isProvidedByMultiplatformProducer(): Boolean { + for (extension in KotlinMultiplatformCommonProducersProvider.EP_NAME.extensionList) { + if (extension.isProducedByCommonProducer(this)) return true + } + return false +} + internal fun canRunJvmTests(): Boolean { return KotlinTestFrameworkProvider.EP_NAME.extensionList.any { it.canRunJvmTests } } diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/KotlinMultiplatformAllInDirectoryConfigurationProducer.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/KotlinMultiplatformAllInDirectoryConfigurationProducer.kt index 76da3b37588e..3ef049f39b2d 100644 --- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/KotlinMultiplatformAllInDirectoryConfigurationProducer.kt +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/KotlinMultiplatformAllInDirectoryConfigurationProducer.kt @@ -8,22 +8,26 @@ import com.intellij.openapi.project.modules import com.intellij.psi.PsiElement import org.jetbrains.kotlin.idea.base.facet.isMultiPlatformModule import org.jetbrains.kotlin.idea.base.facet.platform.platform +import org.jetbrains.kotlin.idea.gradleJava.extensions.KotlinMultiplatformCommonProducersProvider import org.jetbrains.kotlin.idea.gradleJava.run.MultiplatformTestTasksChooser +import org.jetbrains.kotlin.idea.gradleJava.run.isProvidedByMultiplatformProducer import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.plugins.gradle.execution.test.runner.AllInDirectoryGradleConfigurationProducer import org.jetbrains.plugins.gradle.util.createTestWildcardFilter class KotlinMultiplatformAllInDirectoryConfigurationProducer - : AllInDirectoryGradleConfigurationProducer() { + : AllInDirectoryGradleConfigurationProducer(), KotlinMultiplatformCommonProducersProvider { private val mppTestTasksChooser = MultiplatformTestTasksChooser() override fun isPreferredConfiguration(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean { return !other.isProducedBy(KotlinMultiplatformAllInPackageConfigurationProducer::class.java) && super.isPreferredConfiguration(self, other) + && !other.isProvidedByMultiplatformProducer() } override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean { - return !other.isProducedBy(KotlinMultiplatformAllInPackageConfigurationProducer::class.java) && super.shouldReplace(self, other) + return !other.isProducedBy(KotlinMultiplatformAllInPackageConfigurationProducer::class.java) && super.shouldReplace(self, other) && + !other.isProvidedByMultiplatformProducer() } override fun findExistingConfiguration(context: ConfigurationContext): RunnerAndConfigurationSettings? { @@ -55,4 +59,8 @@ class KotlinMultiplatformAllInDirectoryConfigurationProducer return tasks.map { TestTasksToRun(it, wildcardFilter) } } + + override fun isProducedByCommonProducer(configuration: ConfigurationFromContext): Boolean { + return configuration.isProducedBy(this.javaClass) + } } \ No newline at end of file diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/KotlinMultiplatformAllInPackageConfigurationProducer.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/KotlinMultiplatformAllInPackageConfigurationProducer.kt index bd261755e4f3..5ff362cbc9fc 100644 --- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/KotlinMultiplatformAllInPackageConfigurationProducer.kt +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/KotlinMultiplatformAllInPackageConfigurationProducer.kt @@ -6,20 +6,25 @@ import com.intellij.execution.actions.ConfigurationFromContext import com.intellij.openapi.project.modules import com.intellij.psi.PsiPackage import org.jetbrains.kotlin.idea.base.facet.isMultiPlatformModule +import org.jetbrains.kotlin.idea.gradleJava.extensions.KotlinMultiplatformCommonProducersProvider import org.jetbrains.kotlin.idea.gradleJava.run.MultiplatformTestTasksChooser +import org.jetbrains.kotlin.idea.gradleJava.run.isProvidedByMultiplatformProducer import org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer import org.jetbrains.plugins.gradle.util.createTestFilterFrom -class KotlinMultiplatformAllInPackageConfigurationProducer: AllInPackageGradleConfigurationProducer() { +class KotlinMultiplatformAllInPackageConfigurationProducer: AllInPackageGradleConfigurationProducer(), + KotlinMultiplatformCommonProducersProvider { private val mppTestTasksChooser = MultiplatformTestTasksChooser() override fun isPreferredConfiguration(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean { - return other.isProducedBy(KotlinMultiplatformAllInDirectoryConfigurationProducer::class.java) || super.isPreferredConfiguration(self, other) + return other.isProducedBy(KotlinMultiplatformAllInDirectoryConfigurationProducer::class.java) || + super.isPreferredConfiguration(self, other) && !other.isProvidedByMultiplatformProducer() } override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean { - return other.isProducedBy(KotlinMultiplatformAllInDirectoryConfigurationProducer::class.java) || super.shouldReplace(self, other) + return other.isProducedBy(KotlinMultiplatformAllInDirectoryConfigurationProducer::class.java) || + super.shouldReplace(self, other) && !other.isProvidedByMultiplatformProducer() } override fun getAllTestsTaskToRun( @@ -38,4 +43,8 @@ class KotlinMultiplatformAllInPackageConfigurationProducer: AllInPackageGradleCo return tasks.map { TestTasksToRun(it, wildcardFilter) } } + + override fun isProducedByCommonProducer(configuration: ConfigurationFromContext): Boolean { + return configuration.isProducedBy(this.javaClass) + } } \ No newline at end of file diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/common/KotlinMultiplatformCommonTestClassGradleConfigurationProducer.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/common/KotlinMultiplatformCommonTestClassGradleConfigurationProducer.kt index 95a97afb742a..2501a8efeaff 100644 --- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/common/KotlinMultiplatformCommonTestClassGradleConfigurationProducer.kt +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/common/KotlinMultiplatformCommonTestClassGradleConfigurationProducer.kt @@ -4,14 +4,30 @@ package org.jetbrains.kotlin.idea.gradleJava.testing.common import com.intellij.execution.RunnerAndConfigurationSettings import com.intellij.execution.actions.ConfigurationContext +import com.intellij.execution.actions.ConfigurationFromContext import com.intellij.openapi.module.Module import org.jetbrains.kotlin.idea.gradleJava.run.AbstractKotlinMultiplatformTestClassGradleConfigurationProducer +import org.jetbrains.kotlin.idea.gradleJava.extensions.KotlinMultiplatformCommonProducersProvider +import org.jetbrains.kotlin.idea.gradleJava.run.isProvidedByMultiplatformProducer import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.platform.jvm.isJvm -class KotlinMultiplatformCommonTestClassGradleConfigurationProducer : AbstractKotlinMultiplatformTestClassGradleConfigurationProducer() { +class KotlinMultiplatformCommonTestClassGradleConfigurationProducer : AbstractKotlinMultiplatformTestClassGradleConfigurationProducer(), + KotlinMultiplatformCommonProducersProvider { override fun isApplicable(module: Module, platform: TargetPlatform) = platform.isCommon() || platform.isJvm() + override fun isPreferredConfiguration(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean { + return !other.isProvidedByMultiplatformProducer() || super.isPreferredConfiguration(self, other) + } + + override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean { + return !other.isProvidedByMultiplatformProducer() || super.shouldReplace(self, other) + } + override fun findExistingConfiguration(context: ConfigurationContext): RunnerAndConfigurationSettings? = null + + override fun isProducedByCommonProducer(configuration: ConfigurationFromContext): Boolean { + return configuration.isProducedBy(this.javaClass) + } } \ No newline at end of file diff --git a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/common/KotlinMultiplatformCommonTestMethodGradleConfigurationProducer.kt b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/common/KotlinMultiplatformCommonTestMethodGradleConfigurationProducer.kt index 5117043a7b48..37141f6b2b1b 100644 --- a/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/common/KotlinMultiplatformCommonTestMethodGradleConfigurationProducer.kt +++ b/plugins/kotlin/gradle/gradle-java/src/org/jetbrains/kotlin/idea/gradleJava/testing/common/KotlinMultiplatformCommonTestMethodGradleConfigurationProducer.kt @@ -4,13 +4,29 @@ package org.jetbrains.kotlin.idea.gradleJava.testing.common import com.intellij.execution.RunnerAndConfigurationSettings import com.intellij.execution.actions.ConfigurationContext +import com.intellij.execution.actions.ConfigurationFromContext import com.intellij.openapi.module.Module import org.jetbrains.kotlin.idea.gradleJava.run.AbstractKotlinMultiplatformTestMethodGradleConfigurationProducer +import org.jetbrains.kotlin.idea.gradleJava.extensions.KotlinMultiplatformCommonProducersProvider +import org.jetbrains.kotlin.idea.gradleJava.run.isProvidedByMultiplatformProducer import org.jetbrains.kotlin.platform.TargetPlatform import org.jetbrains.kotlin.platform.isCommon import org.jetbrains.kotlin.platform.jvm.isJvm -class KotlinMultiplatformCommonTestMethodGradleConfigurationProducer : AbstractKotlinMultiplatformTestMethodGradleConfigurationProducer() { +class KotlinMultiplatformCommonTestMethodGradleConfigurationProducer : AbstractKotlinMultiplatformTestMethodGradleConfigurationProducer(), + KotlinMultiplatformCommonProducersProvider { override fun isApplicable(module: Module, platform: TargetPlatform) = platform.isCommon() || platform.isJvm() override fun findExistingConfiguration(context: ConfigurationContext): RunnerAndConfigurationSettings? = null + + override fun isPreferredConfiguration(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean { + return !other.isProvidedByMultiplatformProducer() || super.isPreferredConfiguration(self, other) + } + + override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean { + return !other.isProvidedByMultiplatformProducer() || super.shouldReplace(self, other) + } + + override fun isProducedByCommonProducer(configuration: ConfigurationFromContext): Boolean { + return configuration.isProducedBy(this.javaClass) + } } \ No newline at end of file