mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
[jvm] KTIJ-22044 Improve Kotlin suspending function error message
GitOrigin-RevId: bde403e6f3fe15712426b4394651160bd5494a09
This commit is contained in:
committed by
intellij-monorepo-bot
parent
13ad5f166a
commit
f56c9230cb
@@ -39,6 +39,9 @@ The following problems are reported by this inspection:
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
Note that in Kotlin, suspending functions do have arguments and a non-void return type. Therefore, they also will not be executed by the
|
||||
JUnit test runner. This inspection will also report about this problem.
|
||||
|
||||
<p><b>Malformed <code>@Before</code> method example (Java):</b></p>
|
||||
<pre><code>@Before private int foo(int arg) { ... } </code></pre>
|
||||
<p>After the quick-fix is applied:</p>
|
||||
|
||||
@@ -130,9 +130,11 @@ jvm.inspections.junit.malformed.annotated.method.single.param.double.descriptor=
|
||||
jvm.inspections.junit.malformed.annotated.method.double.param.double.descriptor=Method <code>#ref</code> annotated with ''@{0}'' should be {1}, {2} and not declare parameters ''{3}'' and ''{4}''
|
||||
jvm.inspections.junit.malformed.annotated.method.single.typed.param.double.descriptor=Method <code>#ref</code> annotated with ''@{0}'' should be {1}, of type ''{2}'' and not declare parameters {3} and ''{4}''
|
||||
jvm.inspections.junit.malformed.annotated.method.double.typed.param.double.descriptor=Method <code>#ref</code> annotated with ''@{0}'' should be {1}, {2}, of type ''{3}'' and not declare parameters {4} and ''{5}''
|
||||
jvm.inspections.junit.malformed.annotated.suspend.function.descriptor=Method <code>#ref</code> annotated with ''@{0}'' should not be a suspending function
|
||||
jvm.inspections.junit.malformed.suspend.function.descriptor=Method <code>#ref</code> should not be a suspending function
|
||||
jvm.inspections.junit.malformed.test.combination.descriptor=Suspicious combination of {0} and ''@{1}''
|
||||
jvm.inspections.junit.malformed.repetition.number.descriptor=The number of repetitions must be greater than zero
|
||||
jvm.inspections.junit.malformed.nested.class.descriptor=Only non-static nested classes can serve as '@Nested' test classes.
|
||||
jvm.inspections.junit.malformed.nested.class.descriptor=Only non-static nested classes can serve as '@Nested' test classes
|
||||
jvm.inspections.junit.malformed.extension.registration.descriptor=''{0}'' should implement ''{1}''
|
||||
jvm.inspections.junit.malformed.extension.class.level.descriptor={0} should be registered at the class level
|
||||
jvm.inspections.junit.malformed.param.method.source.unresolved.descriptor=Cannot resolve target method source: ''{0}''
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.intellij.codeInspection.*
|
||||
import com.intellij.codeInspection.test.junit.references.MethodSourceReference
|
||||
import com.intellij.codeInspection.util.InspectionMessage
|
||||
import com.intellij.codeInspection.util.SpecialAnnotationsUtil
|
||||
import com.intellij.lang.Language
|
||||
import com.intellij.lang.jvm.JvmMethod
|
||||
import com.intellij.lang.jvm.JvmModifier
|
||||
import com.intellij.lang.jvm.JvmModifiersOwner
|
||||
@@ -240,6 +241,14 @@ private class JUnitMalformedSignatureVisitor(
|
||||
param.javaPsi?.castSafelyTo<PsiParameter>()?.let { AnnotationUtil.isAnnotated(it, ignorableAnnotations, 0) } == true
|
||||
}
|
||||
|
||||
private fun checkSuspendFunction(method: UMethod): Boolean {
|
||||
return if (method.lang == Language.findLanguageByID("kotlin") && method.javaPsi.modifierList.text.contains("suspend")) {
|
||||
val message = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.suspend.function.descriptor")
|
||||
holder.registerUProblem(method, message)
|
||||
true
|
||||
} else false
|
||||
}
|
||||
|
||||
private fun checkJUnit3Test(method: UMethod) {
|
||||
val sourcePsi = method.sourcePsi ?: return
|
||||
val alternatives = UastFacade.convertToAlternatives(sourcePsi, arrayOf(UMethod::class.java))
|
||||
@@ -248,8 +257,9 @@ private class JUnitMalformedSignatureVisitor(
|
||||
if (!TestUtils.isJUnit3TestMethod(javaMethod.javaPsi)) return
|
||||
val containingClass = method.javaPsi.containingClass ?: return
|
||||
if (AnnotationUtil.isAnnotated(containingClass, TestUtils.RUN_WITH, AnnotationUtil.CHECK_HIERARCHY)) return
|
||||
val message = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.method.no.arg.void.descriptor", "public", "non-static")
|
||||
if (checkSuspendFunction(method)) return
|
||||
if (PsiType.VOID != method.returnType || method.visibility != UastVisibility.PUBLIC || javaMethod.isStatic || !method.isNoArg()) {
|
||||
val message = JvmAnalysisBundle.message("jvm.inspections.junit.malformed.method.no.arg.void.descriptor", "public", "non-static")
|
||||
return holder.registerUProblem(method, message, MethodSignatureQuickfix(method.name, false, newVisibility = JvmModifier.PUBLIC))
|
||||
}
|
||||
}
|
||||
@@ -258,6 +268,7 @@ private class JUnitMalformedSignatureVisitor(
|
||||
if ("setUp" != method.name && "tearDown" != method.name) return
|
||||
if (!InheritanceUtil.isInheritor(method.javaPsi.containingClass, JUNIT_FRAMEWORK_TEST_CASE)) return
|
||||
val sourcePsi = method.sourcePsi ?: return
|
||||
if (checkSuspendFunction(method)) return
|
||||
val alternatives = UastFacade.convertToAlternatives(sourcePsi, arrayOf(UMethod::class.java))
|
||||
val javaMethod = alternatives.firstOrNull { it.isStatic } ?: alternatives.firstOrNull() ?: return
|
||||
if (PsiType.VOID != method.returnType || method.visibility == UastVisibility.PRIVATE || javaMethod.isStatic || !method.isNoArg()) {
|
||||
@@ -273,6 +284,7 @@ private class JUnitMalformedSignatureVisitor(
|
||||
if ("suite" != method.name) return
|
||||
if (!InheritanceUtil.isInheritor(method.javaPsi.containingClass, JUNIT_FRAMEWORK_TEST_CASE)) return
|
||||
val sourcePsi = method.sourcePsi ?: return
|
||||
if (checkSuspendFunction(method)) return
|
||||
val alternatives = UastFacade.convertToAlternatives(sourcePsi, arrayOf(UMethod::class.java))
|
||||
val javaMethod = alternatives.firstOrNull { it.isStatic } ?: alternatives.firstOrNull() ?: return
|
||||
if (method.visibility == UastVisibility.PRIVATE || !javaMethod.isStatic || !method.isNoArg()) {
|
||||
@@ -796,6 +808,13 @@ private class JUnitMalformedSignatureVisitor(
|
||||
val problems = modifierProblems(
|
||||
visibility, element.visibility, elementIsStatic, javaPsi.containingClass?.let { cls -> TestUtils.testInstancePerClass(cls) } == true
|
||||
)
|
||||
if (element.lang == Language.findLanguageByID("kotlin") && element.javaPsi.modifierList.text.contains("suspend")) {
|
||||
val message = JvmAnalysisBundle.message(
|
||||
"jvm.inspections.junit.malformed.annotated.suspend.function.descriptor",
|
||||
annotation.substringAfterLast('.')
|
||||
)
|
||||
return holder.registerUProblem(element, message)
|
||||
}
|
||||
if (params != null && params.size != element.uastParameters.size) {
|
||||
if (shouldBeVoidType == true && element.returnType != PsiType.VOID) {
|
||||
return holder.methodParameterTypeProblem(element, visibility, annotation, problems, PsiType.VOID.name, params)
|
||||
|
||||
@@ -37,7 +37,7 @@ class JavaJUnitMalformedDeclarationInspectionTest : JUnitMalformedDeclarationIns
|
||||
myFixture.testHighlighting(ULanguage.JAVA, """
|
||||
class A {
|
||||
@org.junit.jupiter.api.Nested
|
||||
static class <warning descr="Only non-static nested classes can serve as '@Nested' test classes.">B</warning> { }
|
||||
static class <warning descr="Only non-static nested classes can serve as '@Nested' test classes">B</warning> { }
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ class KotlinJUnitMalformedDeclarationInspectionTest : JUnitMalformedDeclarationI
|
||||
myFixture.testHighlighting(ULanguage.KOTLIN, """
|
||||
class A {
|
||||
@org.junit.jupiter.api.Nested
|
||||
class <warning descr="Only non-static nested classes can serve as '@Nested' test classes.">B</warning> { }
|
||||
class <warning descr="Only non-static nested classes can serve as '@Nested' test classes">B</warning> { }
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
@@ -1086,4 +1086,29 @@ class KotlinJUnitMalformedDeclarationInspectionTest : JUnitMalformedDeclarationI
|
||||
}
|
||||
""".trimIndent(), "Fix 'suite' method signature")
|
||||
}
|
||||
|
||||
/* Suspending test function */
|
||||
fun `test malformed suspending test JUnit 3 function`() {
|
||||
myFixture.testHighlighting(ULanguage.KOTLIN, """
|
||||
class JUnit3Test : junit.framework.TestCase() {
|
||||
suspend fun <warning descr="Method 'testFoo' should not be a suspending function">testFoo</warning>() { }
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
fun `test malformed suspending test JUnit 4 function`() {
|
||||
myFixture.testHighlighting(ULanguage.KOTLIN, """
|
||||
class JUnit4Test {
|
||||
@org.junit.Test
|
||||
suspend fun <warning descr="Method 'testFoo' annotated with '@Test' should not be a suspending function">testFoo</warning>() { }
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
fun `test malformed suspending test JUnit 5 function`() {
|
||||
myFixture.testHighlighting(ULanguage.KOTLIN, """
|
||||
class JUnit5Test {
|
||||
@org.junit.jupiter.api.Test
|
||||
suspend fun <warning descr="Method 'testFoo' annotated with '@Test' should not be a suspending function">testFoo</warning>() { }
|
||||
}
|
||||
""".trimIndent())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user