Change Signature: Fix implicit receiver ->argument convertion in recusrive calls

#KT-8744 In Progress
This commit is contained in:
Alexey Sedunov
2016-02-04 18:07:07 +03:00
parent d8c0671d94
commit b3801ffac7
5 changed files with 31 additions and 1 deletions
@@ -30,6 +30,8 @@ import com.intellij.refactoring.rename.UnresolvableCollisionUsageInfo
import com.intellij.usageView.UsageInfo
import com.intellij.usageView.UsageViewDescriptor
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinFunctionCallUsage
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinImplicitReceiverUsage
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinUsageInfo
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinWrapperForJavaUsageInfos
import java.util.*
@@ -87,6 +89,8 @@ class KotlinChangeSignatureProcessor(project: Project,
val usageArray = usagesSet.toTypedArray()
Arrays.sort(usageArray) { u1, u2 ->
if (u1 is KotlinImplicitReceiverUsage && u2 is KotlinFunctionCallUsage) return@sort -1
if (u2 is KotlinImplicitReceiverUsage && u1 is KotlinFunctionCallUsage) return@sort 1
val element1 = u1.element
val element2 = u2.element
val rank1 = if (element1 != null) element1.textOffset else -1
@@ -298,6 +298,12 @@ class KotlinFunctionCallUsage(
}
}
private fun ExpressionReceiver.wrapInvalidated(element: KtCallElement): ExpressionReceiver {
return object: ExpressionReceiver by this {
override val expression = element.getQualifiedExpressionForSelector()!!.receiverExpression
}
}
private fun updateArgumentsAndReceiver(changeInfo: KotlinChangeInfo, element: KtCallElement, allUsages: Array<out UsageInfo>) {
if (isPropertyJavaUsage) return updateJavaPropertyCall(changeInfo, element)
@@ -321,7 +327,12 @@ class KotlinFunctionCallUsage(
val (index, param) = it
val oldIndex = param.oldIndex
val resolvedArgument = if (oldIndex >= 0) getResolvedValueArgument(oldIndex) else null
val receiverValue = if (param == originalReceiverInfo) extensionReceiver else null
var receiverValue = if (param == originalReceiverInfo) extensionReceiver else null
// Workaround for recursive calls where implicit extension receiver is transformed into ordinary value argument
// Receiver expression retained in the original resolved call is no longer valid at this point
if (receiverValue is ExpressionReceiver && !receiverValue.expression.isValid) {
receiverValue = receiverValue.wrapInvalidated(element)
}
ArgumentInfo(param, index, resolvedArgument, receiverValue as? ReceiverValue)
}
@@ -0,0 +1,5 @@
interface A {
val parent: A
}
fun ext(a: A): Int = 1 + ext(a.parent)
@@ -0,0 +1,5 @@
interface A {
val parent: A
}
fun A.<caret>ext(): Int = 1 + parent.ext()
@@ -944,4 +944,9 @@ class KotlinChangeSignatureTest : KotlinCodeInsightTestCase() {
psiFactory.createExpression("5"),
KotlinValVar.Val))
}
fun testImplicitReceiverInRecursiveCall() = doTest {
receiverParameterInfo = null
newParameters[0].name = "a"
}
}