From 390d062721e763324312993e3e8e47c8fa3e715f Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Fri, 14 Feb 2020 17:51:42 +0900 Subject: [PATCH] Fix class run configuration applicability (KT-33787) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bug appeared when we turned “ultra light classes” on by default. The difference with the old implementation is that PsiClass.getTextRange() returns the correct non-null value. This triggers JavaExecutionUtil#stepIntoSingleClass() to return a light class instead of the original location (of a PsiIdentifier). So AbstractJavaTestConfigurationProducer#isConfigurationFromContext() returns true, and the wrong configuration is reused instead of creating the new one. By the way, for Java it also returns an identifier because of the PsiTreeUtil.getParentOfType(element, PsiClass.class) != null check. The proper fix should land in the newer versions of IDEA, however this (hopefully, temporary) hack will fix test method gutters for all platform versions. --- .../classes/KtLightClassForSourceDeclaration.kt | 2 +- .../kotlin/asJava/classes/ultraLightClass.kt | 10 ++++++++++ .../GradleTestRunConfigurationCustomTest.kt | 16 ++++++++-------- idea/resources/META-INF/jvm.xml | 5 +++++ .../kotlin/asJava/LightClassFromTextTest.kt | 2 +- .../idea/run/KotlinJUnitRunConfigurationTest.kt | 16 ++++++++-------- 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt index bab5800861c..ef8364eca42 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/KtLightClassForSourceDeclaration.kt @@ -81,7 +81,7 @@ abstract class KtLightClassForSourceDeclaration( override fun getText() = kotlinOrigin.text ?: "" - override fun getTextRange(): TextRange = kotlinOrigin.textRange ?: TextRange.EMPTY_RANGE + override fun getTextRange(): TextRange? = kotlinOrigin.textRange ?: TextRange.EMPTY_RANGE override fun getTextOffset() = kotlinOrigin.textOffset diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt index e7163eb2b61..30788e3807a 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/classes/ultraLightClass.kt @@ -5,6 +5,8 @@ package org.jetbrains.kotlin.asJava.classes +import com.intellij.openapi.util.TextRange +import com.intellij.openapi.util.registry.Registry import com.intellij.psi.* import com.intellij.psi.impl.InheritanceImplUtil import com.intellij.psi.impl.PsiClassImplUtil @@ -475,4 +477,12 @@ open class KtUltraLightClass(classOrObject: KtClassOrObject, internal val suppor override fun isDeprecated(): Boolean = _deprecated override fun copy(): KtLightClassImpl = KtUltraLightClass(classOrObject.copy() as KtClassOrObject, support) + + override fun getTextRange(): TextRange? { + if (Registry.`is`("kotlin.ultra.light.classes.empty.text.range", true)) { + return null + } + + return super.getTextRange() + } } \ No newline at end of file diff --git a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleTestRunConfigurationCustomTest.kt b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleTestRunConfigurationCustomTest.kt index add1fc371bc..3020960fd8b 100644 --- a/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleTestRunConfigurationCustomTest.kt +++ b/idea/idea-gradle/tests/org/jetbrains/kotlin/idea/codeInsight/gradle/GradleTestRunConfigurationCustomTest.kt @@ -34,20 +34,20 @@ class GradleTestRunConfigurationCustomTest : GradleImportingTestCase() { val kotlinFile = files.first { it.name == "MyKotlinTest.kt" } val javaClassConfiguration = getConfiguration(javaFile, myProject, "MyTest") - javaClassConfiguration.isProducedBy(TestClassGradleConfigurationProducer::class.java) - assert(javaClassConfiguration.configuration !is KotlinGradleRunConfiguration) + assert(javaClassConfiguration.isProducedBy(TestClassGradleConfigurationProducer::class.java)) + assert(javaClassConfiguration.configuration.name == "MyTest") val javaMethodConfiguration = getConfiguration(javaFile, myProject, "testA") - javaMethodConfiguration.isProducedBy(TestMethodGradleConfigurationProducer::class.java) - assert(javaMethodConfiguration.configuration !is KotlinGradleRunConfiguration) + assert(javaMethodConfiguration.isProducedBy(TestMethodGradleConfigurationProducer::class.java)) + assert(javaMethodConfiguration.configuration.name == "MyTest.testA") val kotlinClassConfiguration = getConfiguration(kotlinFile, myProject, "MyKotlinTest") - kotlinClassConfiguration.isProducedBy(KotlinJvmTestClassGradleConfigurationProducer::class.java) - assert(kotlinClassConfiguration.configuration is KotlinGradleRunConfiguration) + assert(kotlinClassConfiguration.isProducedBy(KotlinJvmTestClassGradleConfigurationProducer::class.java)) + assert(kotlinClassConfiguration.configuration.name == "MyKotlinTest") val kotlinFunctionConfiguration = getConfiguration(kotlinFile, myProject, "testA") - kotlinFunctionConfiguration.isProducedBy(KotlinJvmTestMethodGradleConfigurationProducer::class.java) - assert(kotlinFunctionConfiguration.configuration is KotlinGradleRunConfiguration) + assert(kotlinFunctionConfiguration.isProducedBy(KotlinJvmTestMethodGradleConfigurationProducer::class.java)) + assert(kotlinFunctionConfiguration.configuration.name == "MyKotlinTest.testA") } } } diff --git a/idea/resources/META-INF/jvm.xml b/idea/resources/META-INF/jvm.xml index 2095194e196..2f357e7b0a4 100644 --- a/idea/resources/META-INF/jvm.xml +++ b/idea/resources/META-INF/jvm.xml @@ -175,6 +175,11 @@ defaultValue="true" restartRequired="false"/> + +