Fix class run configuration applicability (KT-33787)
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.
This commit is contained in:
+1
-1
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -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")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +175,11 @@
|
||||
defaultValue="true"
|
||||
restartRequired="false"/>
|
||||
|
||||
<registryKey key="kotlin.ultra.light.classes.empty.text.range"
|
||||
description="Return 'null' text range as in old light class implementation"
|
||||
defaultValue="true"
|
||||
restartRequired="false"/>
|
||||
|
||||
<registryKey key="kotlin.uast.force.uinjectionhost"
|
||||
description="Whether to convert `KtStringTemplateExpression` to `KotlinStringTemplateUPolyadicExpression` in all cases"
|
||||
defaultValue="true"
|
||||
|
||||
@@ -43,7 +43,7 @@ class LightClassFromTextTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
val classC = classes[0]
|
||||
assertEquals("C", classC.qualifiedName)
|
||||
assertEquals("class C", classC.text)
|
||||
assertEquals(TextRange(17, 24), classC.textRange)
|
||||
assertEquals(null, classC.textRange)
|
||||
assertEquals(23, classC.textOffset)
|
||||
assertEquals(17, classC.startOffsetInParent)
|
||||
assertTrue(classC.isWritable)
|
||||
|
||||
@@ -44,20 +44,20 @@ class KotlinJUnitRunConfigurationTest : AbstractRunConfigurationTest() {
|
||||
val kotlinFile = testDir.findChild("MyKotlinTest.kt")!!
|
||||
|
||||
val javaClassConfiguration = getConfiguration(javaFile, project, "MyTest")
|
||||
javaClassConfiguration.isProducedBy(TestInClassConfigurationProducer::class.java)
|
||||
assert(javaClassConfiguration.configuration !is KotlinJUnitConfiguration)
|
||||
assert(javaClassConfiguration.isProducedBy(TestInClassConfigurationProducer::class.java))
|
||||
assert(javaClassConfiguration.configuration.name == "MyJavaTest")
|
||||
|
||||
val javaMethodConfiguration = getConfiguration(javaFile, project, "testA")
|
||||
javaMethodConfiguration.isProducedBy(TestInClassConfigurationProducer::class.java)
|
||||
assert(javaMethodConfiguration.configuration !is KotlinJUnitConfiguration)
|
||||
assert(javaMethodConfiguration.isProducedBy(TestInClassConfigurationProducer::class.java))
|
||||
assert(javaMethodConfiguration.configuration.name == "MyJavaTest.testA")
|
||||
|
||||
val kotlinClassConfiguration = getConfiguration(kotlinFile, project, "MyKotlinTest")
|
||||
kotlinClassConfiguration.isProducedBy(KotlinJUnitRunConfigurationProducer::class.java)
|
||||
assert(kotlinClassConfiguration.configuration is KotlinJUnitConfiguration)
|
||||
assert(kotlinClassConfiguration.isProducedBy(KotlinJUnitRunConfigurationProducer::class.java))
|
||||
assert(kotlinClassConfiguration.configuration.name == "MyKotlinTest")
|
||||
|
||||
val kotlinFunctionConfiguration = getConfiguration(kotlinFile, project, "testA")
|
||||
kotlinFunctionConfiguration.isProducedBy(KotlinJUnitRunConfigurationProducer::class.java)
|
||||
assert(kotlinFunctionConfiguration.configuration is KotlinJUnitConfiguration)
|
||||
assert(kotlinFunctionConfiguration.isProducedBy(KotlinJUnitRunConfigurationProducer::class.java))
|
||||
assert(kotlinFunctionConfiguration.configuration.name == "MyKotlinTest.testA")
|
||||
} finally {
|
||||
detachJUnitLibrary()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user