Dispatchers IO is now considered non-blocking context
See BlockingMethodInNonBlockingContextInspection
This commit is contained in:
committed by
Mikhail Glukhikh
parent
3b33d3e58d
commit
297054037c
+7
-5
@@ -24,9 +24,9 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.isRestrictsSuspensionReceiver
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
|
||||
class CoroutineNonBlockingContextChecker : NonBlockingContextChecker {
|
||||
|
||||
override fun isApplicable(file: PsiFile): Boolean {
|
||||
@@ -45,10 +45,11 @@ class CoroutineNonBlockingContextChecker : NonBlockingContextChecker {
|
||||
val callExpression = PsiTreeUtil.getParentOfType(containingArgument, KtCallExpression::class.java) ?: return false
|
||||
val call = callExpression.resolveToCall(BodyResolveMode.PARTIAL) ?: return false
|
||||
|
||||
val hasBlockingAnnotation = call.getFirstArgument()?.resolveToCall()
|
||||
?.resultingDescriptor?.annotations?.hasAnnotation(FqName(BLOCKING_CONTEXT_ANNOTATION))
|
||||
if (hasBlockingAnnotation == true)
|
||||
return false
|
||||
val argumentDescriptor = call.getFirstArgument()?.resolveToCall()?.resultingDescriptor
|
||||
val hasBlockingAnnotation = argumentDescriptor?.annotations?.hasAnnotation(FqName(BLOCKING_CONTEXT_ANNOTATION))
|
||||
if (hasBlockingAnnotation == true) return false
|
||||
val isIoDispatcherUsed = argumentDescriptor?.fqNameOrNull()?.asString() == IO_DISPATCHER_FQN
|
||||
if (isIoDispatcherUsed) return false
|
||||
|
||||
val parameterForArgument = call.getParameterForArgument(containingArgument) ?: return false
|
||||
val type = parameterForArgument.returnType ?: return false
|
||||
@@ -69,5 +70,6 @@ class CoroutineNonBlockingContextChecker : NonBlockingContextChecker {
|
||||
|
||||
companion object {
|
||||
private const val BLOCKING_CONTEXT_ANNOTATION = "org.jetbrains.annotations.BlockingContext"
|
||||
private const val IO_DISPATCHER_FQN = "kotlinx.coroutines.Dispatchers.IO"
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import kotlin.coroutines.*
|
||||
import org.jetbrains.annotations.BlockingContext
|
||||
import kotlin.coroutines.experimental.buildSequence
|
||||
import java.lang.Thread.sleep
|
||||
|
||||
suspend fun testFunction() {
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
@file:Suppress("UNUSED_PARAMETER")
|
||||
package kotlinx.coroutines
|
||||
|
||||
import java.lang.Thread.sleep
|
||||
|
||||
suspend fun withIoDispatcher() {
|
||||
withContext(Dispatchers.IO) {
|
||||
//no warning since IO dispatcher type used
|
||||
Thread.sleep(42)
|
||||
}
|
||||
|
||||
withContext(Dispatchers.Default) {
|
||||
Thread.<warning descr="Inappropriate blocking method call">sleep</warning>(1)
|
||||
}
|
||||
}
|
||||
|
||||
class CoroutineDispatcher()
|
||||
object Dispatchers {
|
||||
val IO: kotlinx.coroutines.CoroutineDispatcher = TODO()
|
||||
val Default: kotlinx.coroutines.CoroutineDispatcher = TODO()
|
||||
}
|
||||
|
||||
suspend fun <T> withContext(
|
||||
context: CoroutineDispatcher,
|
||||
f: suspend () -> T
|
||||
) {
|
||||
TODO()
|
||||
}
|
||||
+7
-4
@@ -10,11 +10,9 @@ import com.intellij.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||
import org.jetbrains.kotlin.idea.test.configureCompilerOptions
|
||||
|
||||
class CoroutineNonBlockingontextDetectionTest: KotlinLightCodeInsightFixtureTestCase() {
|
||||
override fun getTestDataPath(): String
|
||||
= PluginTestCaseBase.getTestDataPathBase() + "/inspections/blockingCallsDetection"
|
||||
class CoroutineNonBlockingContextDetectionTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + "/inspections/blockingCallsDetection"
|
||||
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||
|
||||
@@ -43,4 +41,9 @@ class CoroutineNonBlockingontextDetectionTest: KotlinLightCodeInsightFixtureTest
|
||||
myFixture.configureByFile("NestedFunctionsInsideSuspendLambda.kt")
|
||||
myFixture.testHighlighting(true, false, false, "NestedFunctionsInsideSuspendLambda.kt")
|
||||
}
|
||||
|
||||
fun testDispatchersTypeDetection() {
|
||||
myFixture.configureByFile("DispatchersTypeCheck.kt")
|
||||
myFixture.testHighlighting(true, false, false, "DispatchersTypeCheck.kt")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user