Cast to type quick-fix: handle case with qualified elements correctly

Same fix for 'add !!' fix
So #KT-18368 Fixed
This commit is contained in:
Mikhail Glukhikh
2017-07-20 16:43:00 +03:00
parent e6872c52a3
commit a08f55cf99
6 changed files with 74 additions and 2 deletions
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.idea.core.quickfix.QuickFixUtil
import org.jetbrains.kotlin.idea.util.approximateWithResolvableType
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForSelectorOrThis
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
import org.jetbrains.kotlin.resolve.bindingContextUtil.getTargetFunction
@@ -115,15 +116,24 @@ class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() {
expressionTypeDeclaration?.let { actions.add(LetImplementInterfaceFix(it, expectedType, expressionType)) }
}
fun KtExpression.getTopMostQualifiedForSelectorIfAny(): KtExpression {
var qualifiedOrThis = this
do {
val element = qualifiedOrThis
qualifiedOrThis = element.getQualifiedExpressionForSelectorOrThis()
} while (qualifiedOrThis !== element)
return qualifiedOrThis
}
// We don't want to cast a cast or type-asserted expression:
if (diagnosticElement !is KtBinaryExpressionWithTypeRHS && diagnosticElement.parent !is KtBinaryExpressionWithTypeRHS) {
actions.add(CastExpressionFix(diagnosticElement, expectedType))
actions.add(CastExpressionFix(diagnosticElement.getTopMostQualifiedForSelectorIfAny(), expectedType))
}
if (!expectedType.isMarkedNullable && org.jetbrains.kotlin.types.TypeUtils.isNullableType(expressionType)) {
val nullableExpected = expectedType.makeNullable()
if (expressionType.isSubtypeOf(nullableExpected)) {
actions.add(AddExclExclCallFix(diagnosticElement))
actions.add(AddExclExclCallFix(diagnosticElement.getTopMostQualifiedForSelectorIfAny()))
}
}
@@ -0,0 +1,13 @@
// "Add non-null asserted (!!) call" "true"
// WITH_RUNTIME
class A {
fun foo(): List<Int?> = listOf()
fun bar(i : Int, s: String) = Unit
fun use() {
val a = A()
a.bar(a.foo().<caret>single(), "Asd")
}
}
@@ -0,0 +1,13 @@
// "Add non-null asserted (!!) call" "true"
// WITH_RUNTIME
class A {
fun foo(): List<Int?> = listOf()
fun bar(i : Int, s: String) = Unit
fun use() {
val a = A()
a.bar(a.foo().single()!!, "Asd")
}
}
@@ -0,0 +1,12 @@
// "Cast expression 'a.foo().single()' to 'Int'" "true"
// WITH_RUNTIME
class A {
fun foo(): List<Any> = listOf()
fun bar(i : Int, s: String) = Unit
fun use() {
val a = A()
a.bar(a.foo().single<caret>(), "Asd")
}
}
@@ -0,0 +1,12 @@
// "Cast expression 'a.foo().single()' to 'Int'" "true"
// WITH_RUNTIME
class A {
fun foo(): List<Any> = listOf()
fun bar(i : Int, s: String) = Unit
fun use() {
val a = A()
a.bar(a.foo().single() as Int, "Asd")
}
}
@@ -10375,6 +10375,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("addExclExclToQualifiedArgument.kt")
public void testAddExclExclToQualifiedArgument() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/addExclExclToQualifiedArgument.kt");
doTest(fileName);
}
@TestMetadata("addExclExclToRemoveNullability.kt")
public void testAddExclExclToRemoveNullability() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/addExclExclToRemoveNullability.kt");
@@ -10741,6 +10747,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/quickfix/typeMismatch/casts"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
}
@TestMetadata("castQualifiedArgument.kt")
public void testCastQualifiedArgument() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/casts/castQualifiedArgument.kt");
doTest(fileName);
}
@TestMetadata("castToFunctionType.kt")
public void testCastToFunctionType() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/typeMismatch/casts/castToFunctionType.kt");