Use smartcast info that related to call in change signature quick fix

There is an inconsistency on how we record smartcasts in old and new
 inference, but we definitely should use all possible information about
 smartcasts in quick-fixes

 #KT-25144 Fixed
This commit is contained in:
Mikhail Zarechenskiy
2018-06-27 16:20:45 +03:00
parent 698096f13e
commit dc7678a700
4 changed files with 37 additions and 1 deletions
@@ -31,6 +31,7 @@ import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.ValueArgument import org.jetbrains.kotlin.psi.ValueArgument
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getCall
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
@@ -89,6 +90,7 @@ class AddFunctionParametersFix(
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor { override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
return originalDescriptor.modify { return originalDescriptor.modify {
val callElement = callElement ?: return@modify val callElement = callElement ?: return@modify
val call = callElement.getCall(callElement.analyze()) ?: return@modify
val parameters = functionDescriptor.valueParameters val parameters = functionDescriptor.valueParameters
val arguments = callElement.valueArguments val arguments = callElement.valueArguments
val validator = CollectingNameValidator() val validator = CollectingNameValidator()
@@ -101,7 +103,8 @@ class AddFunctionParametersFix(
validator.addName(parameters[i].name.asString()) validator.addName(parameters[i].name.asString())
val argumentType = expression?.let { val argumentType = expression?.let {
val bindingContext = it.analyze() val bindingContext = it.analyze()
bindingContext[BindingContext.SMARTCAST, it]?.defaultType ?: bindingContext.getType(it) val smartCasts = bindingContext[BindingContext.SMARTCAST, it]
smartCasts?.defaultType ?: smartCasts?.type(call) ?: bindingContext.getType(it)
} }
val parameterType = parameters[i].type val parameterType = parameters[i].type
@@ -0,0 +1,14 @@
// "Change the signature of function 'doSmthWithChild'" "true"
// DISABLE-ERRORS
// COMPILER_ARGUMENTS: -XXLanguage:+NewInference
interface Parent
interface Child : Parent
fun doSmthWithChild(a: Child) {}
fun foobar(parent: Parent) {
if (parent is Child) {
doSmthWithChild(parent, <caret>123)
}
}
@@ -0,0 +1,14 @@
// "Change the signature of function 'doSmthWithChild'" "true"
// DISABLE-ERRORS
// COMPILER_ARGUMENTS: -XXLanguage:+NewInference
interface Parent
interface Child : Parent
fun doSmthWithChild(a: Child, i: Int) {}
fun foobar(parent: Parent) {
if (parent is Child) {
doSmthWithChild(parent, <caret>123)
}
}
@@ -1537,6 +1537,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
runTest("idea/testData/quickfix/changeSignature/addFunctionParameterWithSmartCast.kt"); runTest("idea/testData/quickfix/changeSignature/addFunctionParameterWithSmartCast.kt");
} }
@TestMetadata("addFunctionParameterWithSmartcastedArgument.kt")
public void testAddFunctionParameterWithSmartcastedArgument() throws Exception {
runTest("idea/testData/quickfix/changeSignature/addFunctionParameterWithSmartcastedArgument.kt");
}
@TestMetadata("addNothingReturnType.kt") @TestMetadata("addNothingReturnType.kt")
public void testAddNothingReturnType() throws Exception { public void testAddNothingReturnType() throws Exception {
runTest("idea/testData/quickfix/changeSignature/addNothingReturnType.kt"); runTest("idea/testData/quickfix/changeSignature/addNothingReturnType.kt");