Take coroutineContext into account in RedundantSuspendModifierInspection

#KT-22651: Fixed
This commit is contained in:
Ilmir Usmanov
2018-02-07 15:24:40 +03:00
parent e19ed1e001
commit 87bbac9d43
8 changed files with 33 additions and 11 deletions
@@ -13,6 +13,7 @@ import com.intellij.openapi.editor.markup.GutterIconRenderer
import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.descriptors.accessors
import org.jetbrains.kotlin.idea.KotlinIcons
@@ -22,6 +23,7 @@ import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext.*
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.checkers.isBuiltInCoroutineContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
@@ -68,7 +70,7 @@ class KotlinSuspendCallLineMarkerProvider : LineMarkerProvider {
}
private fun KtExpression.isValidCandidateExpression(): Boolean {
if (this is KtOperationReferenceExpression || this is KtForExpression || this is KtProperty) return true
if (this is KtOperationReferenceExpression || this is KtForExpression || this is KtProperty || this is KtNameReferenceExpression) return true
val parent = parent
if (parent is KtCallExpression && parent.calleeExpression == this) return true
return false
@@ -94,14 +96,14 @@ fun KtExpression.hasSuspendCalls(bindingContext: BindingContext = analyze(BodyRe
val delegatedFunctionDescriptor = bindingContext[DELEGATED_PROPERTY_RESOLVED_CALL, accessor]?.resultingDescriptor
delegatedFunctionDescriptor?.isSuspend == true
}
}
else {
} else {
false
}
}
else -> {
val resolvedCall = getResolvedCall(bindingContext)
(resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.isSuspend == true
(resolvedCall?.resultingDescriptor as? FunctionDescriptor)?.isSuspend == true ||
(resolvedCall?.resultingDescriptor as? PropertyDescriptor)?.isBuiltInCoroutineContext() == true
}
}
}
@@ -0,0 +1,8 @@
// PROBLEM: none
// WITH_RUNTIME
import kotlin.coroutines.experimental.coroutineContext
<caret>suspend fun test() {
coroutineContext
}
@@ -2961,6 +2961,12 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/redundantSuspend"), Pattern.compile("^([\\w\\-_]+)\\.(kt|kts)$"), TargetBackend.ANY, true);
}
@TestMetadata("coroutineContext.kt")
public void testCoroutineContext() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantSuspend/coroutineContext.kt");
doTest(fileName);
}
@TestMetadata("getterDelegate.kt")
public void testGetterDelegate() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/redundantSuspend/getterDelegate.kt");