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.callUtil.getParameterForArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.checkers.isRestrictsSuspensionReceiver
|
import org.jetbrains.kotlin.resolve.calls.checkers.isRestrictsSuspensionReceiver
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameOrNull
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
|
|
||||||
class CoroutineNonBlockingContextChecker : NonBlockingContextChecker {
|
class CoroutineNonBlockingContextChecker : NonBlockingContextChecker {
|
||||||
|
|
||||||
override fun isApplicable(file: PsiFile): Boolean {
|
override fun isApplicable(file: PsiFile): Boolean {
|
||||||
@@ -45,10 +45,11 @@ class CoroutineNonBlockingContextChecker : NonBlockingContextChecker {
|
|||||||
val callExpression = PsiTreeUtil.getParentOfType(containingArgument, KtCallExpression::class.java) ?: return false
|
val callExpression = PsiTreeUtil.getParentOfType(containingArgument, KtCallExpression::class.java) ?: return false
|
||||||
val call = callExpression.resolveToCall(BodyResolveMode.PARTIAL) ?: return false
|
val call = callExpression.resolveToCall(BodyResolveMode.PARTIAL) ?: return false
|
||||||
|
|
||||||
val hasBlockingAnnotation = call.getFirstArgument()?.resolveToCall()
|
val argumentDescriptor = call.getFirstArgument()?.resolveToCall()?.resultingDescriptor
|
||||||
?.resultingDescriptor?.annotations?.hasAnnotation(FqName(BLOCKING_CONTEXT_ANNOTATION))
|
val hasBlockingAnnotation = argumentDescriptor?.annotations?.hasAnnotation(FqName(BLOCKING_CONTEXT_ANNOTATION))
|
||||||
if (hasBlockingAnnotation == true)
|
if (hasBlockingAnnotation == true) return false
|
||||||
return false
|
val isIoDispatcherUsed = argumentDescriptor?.fqNameOrNull()?.asString() == IO_DISPATCHER_FQN
|
||||||
|
if (isIoDispatcherUsed) return false
|
||||||
|
|
||||||
val parameterForArgument = call.getParameterForArgument(containingArgument) ?: return false
|
val parameterForArgument = call.getParameterForArgument(containingArgument) ?: return false
|
||||||
val type = parameterForArgument.returnType ?: return false
|
val type = parameterForArgument.returnType ?: return false
|
||||||
@@ -69,5 +70,6 @@ class CoroutineNonBlockingContextChecker : NonBlockingContextChecker {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val BLOCKING_CONTEXT_ANNOTATION = "org.jetbrains.annotations.BlockingContext"
|
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 kotlin.coroutines.*
|
||||||
import org.jetbrains.annotations.BlockingContext
|
import org.jetbrains.annotations.BlockingContext
|
||||||
import kotlin.coroutines.experimental.buildSequence
|
|
||||||
import java.lang.Thread.sleep
|
import java.lang.Thread.sleep
|
||||||
|
|
||||||
suspend fun testFunction() {
|
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.KotlinLightCodeInsightFixtureTestCase
|
||||||
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
import org.jetbrains.kotlin.idea.test.KotlinWithJdkAndRuntimeLightProjectDescriptor
|
||||||
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
import org.jetbrains.kotlin.idea.test.PluginTestCaseBase
|
||||||
import org.jetbrains.kotlin.idea.test.configureCompilerOptions
|
|
||||||
|
|
||||||
class CoroutineNonBlockingontextDetectionTest: KotlinLightCodeInsightFixtureTestCase() {
|
class CoroutineNonBlockingContextDetectionTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||||
override fun getTestDataPath(): String
|
override fun getTestDataPath(): String = PluginTestCaseBase.getTestDataPathBase() + "/inspections/blockingCallsDetection"
|
||||||
= PluginTestCaseBase.getTestDataPathBase() + "/inspections/blockingCallsDetection"
|
|
||||||
|
|
||||||
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
override fun getProjectDescriptor(): LightProjectDescriptor = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
|
||||||
|
|
||||||
@@ -43,4 +41,9 @@ class CoroutineNonBlockingontextDetectionTest: KotlinLightCodeInsightFixtureTest
|
|||||||
myFixture.configureByFile("NestedFunctionsInsideSuspendLambda.kt")
|
myFixture.configureByFile("NestedFunctionsInsideSuspendLambda.kt")
|
||||||
myFixture.testHighlighting(true, false, false, "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