Shorten References: Compare resolved calls when shortening receiver of qualified call expression

#KT-13660 Fixed
This commit is contained in:
Alexey Sedunov
2016-08-31 17:27:39 +03:00
parent c1296e2134
commit cf28dd04c8
5 changed files with 32 additions and 1 deletions
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
@@ -428,13 +429,17 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
val selector = element.selectorExpression ?: return Skip
val callee = selector.getCalleeExpressionIfAny() as? KtReferenceExpression ?: return Skip
val targets = callee.targets(bindingContext)
val varAsFunResolvedCall = callee.getResolvedCall(bindingContext) as? VariableAsFunctionResolvedCall
if (targets.isEmpty()) return Skip
val scope = element.getResolutionScope(bindingContext, resolutionFacade)
val selectorCopy = selector.copy() as KtReferenceExpression
val newContext = selectorCopy.analyzeInContext(scope, selector)
val targetsWhenShort = (selectorCopy.getCalleeExpressionIfAny() as KtReferenceExpression).targets(newContext)
val newCallee = selectorCopy.getCalleeExpressionIfAny() as KtReferenceExpression
val targetsWhenShort = newCallee.targets(newContext)
val varAsFunResolvedCallWhenShort = newCallee.getResolvedCall(newContext) as? VariableAsFunctionResolvedCall
val targetsMatch = targetsMatch(targets, targetsWhenShort)
&& (varAsFunResolvedCall == null || resolvedCallsMatch(varAsFunResolvedCall, varAsFunResolvedCallWhenShort))
if (receiver is KtThisExpression) {
if (!targetsMatch) return Skip
@@ -471,6 +476,11 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
}
}
private fun resolvedCallsMatch(rc1: VariableAsFunctionResolvedCall?, rc2: VariableAsFunctionResolvedCall?): Boolean {
return rc1?.variableCall?.candidateDescriptor?.asString() == rc2?.variableCall?.candidateDescriptor?.asString() &&
rc1?.functionCall?.candidateDescriptor?.asString() == rc2?.functionCall?.candidateDescriptor?.asString()
}
override fun shortenElement(element: KtDotQualifiedExpression): KtElement {
return element.replace(element.selectorExpression!!) as KtElement
}
@@ -0,0 +1,7 @@
object X{ }
<selection>class Y {
fun f(op: X.()->Unit) {
X.op()
}
}</selection>
@@ -0,0 +1,7 @@
object X{ }
class Y {
fun f(op: X.()->Unit) {
X.op()
}
}
@@ -59,6 +59,12 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
doTest(fileName);
}
@TestMetadata("extensionFunctionVarInvokedWithQualifier.kt")
public void testExtensionFunctionVarInvokedWithQualifier() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/shortenRefs/extensionFunctionVarInvokedWithQualifier.kt");
doTest(fileName);
}
@TestMetadata("InterfaceInExpression.kt")
public void testInterfaceInExpression() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/shortenRefs/InterfaceInExpression.kt");