Fix "if to safe access" false positive for check on incorrect type

So #KT-21881 Fixed
This commit is contained in:
Toshiaki Kameyama
2018-01-12 11:46:43 +03:00
committed by Mikhail Glukhikh
parent 5798595206
commit fad7818bf0
4 changed files with 29 additions and 3 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
import org.jetbrains.kotlin.resolve.calls.callUtil.getType
class IfThenToSafeAccessInspection : AbstractApplicabilityBasedInspection<KtIfExpression>(KtIfExpression::class.java) {
@@ -84,6 +85,6 @@ class IfThenToSafeAccessInspection : AbstractApplicabilityBasedInspection<KtIfEx
negatedClause == null && baseClause.isUsedAsExpression(context) -> false
negatedClause != null && !negatedClause.isNullExpression() -> false
else -> baseClause.evaluatesTo(receiverExpression) || baseClause.hasFirstReceiverOf(receiverExpression) ||
receiverExpression is KtThisExpression && hasImplicitReceiver()
receiverExpression is KtThisExpression && getImplicitReceiver()?.let { it.type == receiverExpression.getType(context) } == true
}
}
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getType
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactory
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.utils.addToStdlib.constant
@@ -190,8 +191,9 @@ data class IfThenToSelectData(
}
}
internal fun hasImplicitReceiver(): Boolean =
baseClause.getResolvedCall(context)?.getImplicitReceiverValue() != null
internal fun getImplicitReceiver(): ImplicitReceiver? = baseClause.getResolvedCall(context)?.getImplicitReceiverValue()
internal fun hasImplicitReceiver(): Boolean = getImplicitReceiver() != null
}
internal fun KtIfExpression.buildSelectTransformationData(): IfThenToSelectData? {
@@ -0,0 +1,17 @@
// PROBLEM: none
// WITH_RUNTIME
class Foo
class Test {
fun foo(): Any = ""
fun bar() {}
fun test(a: Any) {
foo().apply {
<caret>if (this is Foo) {
bar()
}
}
}
}
@@ -140,6 +140,12 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
doTest(fileName);
}
@TestMetadata("implicitReceiverInApply.kt")
public void testImplicitReceiverInApply() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/branched/ifThenToSafeAccess/implicitReceiverInApply.kt");
doTest(fileName);
}
@TestMetadata("isCheckSimple.kt")
public void testIsCheckSimple() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/branched/ifThenToSafeAccess/isCheckSimple.kt");