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