Shorten References: Compare resolved calls when shortening receiver of qualified call expression
#KT-13660 Fixed
This commit is contained in:
@@ -124,6 +124,7 @@ These artifacts include extensions for the types available in the latter JDKs, s
|
|||||||
- [`KT-13553`](https://youtrack.jetbrains.com/issue/KT-13553) Move: Do not show directory selection dialog if target directory is already specified by drag-and-drop
|
- [`KT-13553`](https://youtrack.jetbrains.com/issue/KT-13553) Move: Do not show directory selection dialog if target directory is already specified by drag-and-drop
|
||||||
- [`KT-8867`](https://youtrack.jetbrains.com/issue/KT-8867) Rename: Rename all overridden members if user chooses to refactor base declaration(s)
|
- [`KT-8867`](https://youtrack.jetbrains.com/issue/KT-8867) Rename: Rename all overridden members if user chooses to refactor base declaration(s)
|
||||||
- Pull Up: Drop 'override' modifier if moved member doesn't override anything
|
- Pull Up: Drop 'override' modifier if moved member doesn't override anything
|
||||||
|
- [`KT-13660`](https://youtrack.jetbrains.com/issue/KT-13660) Move: Do not drop object receivers when calling variable of extension functional type
|
||||||
|
|
||||||
##### New features
|
##### New features
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
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.calls.tasks.ExplicitReceiverKind
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
|
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 selector = element.selectorExpression ?: return Skip
|
||||||
val callee = selector.getCalleeExpressionIfAny() as? KtReferenceExpression ?: return Skip
|
val callee = selector.getCalleeExpressionIfAny() as? KtReferenceExpression ?: return Skip
|
||||||
val targets = callee.targets(bindingContext)
|
val targets = callee.targets(bindingContext)
|
||||||
|
val varAsFunResolvedCall = callee.getResolvedCall(bindingContext) as? VariableAsFunctionResolvedCall
|
||||||
if (targets.isEmpty()) return Skip
|
if (targets.isEmpty()) return Skip
|
||||||
|
|
||||||
val scope = element.getResolutionScope(bindingContext, resolutionFacade)
|
val scope = element.getResolutionScope(bindingContext, resolutionFacade)
|
||||||
val selectorCopy = selector.copy() as KtReferenceExpression
|
val selectorCopy = selector.copy() as KtReferenceExpression
|
||||||
val newContext = selectorCopy.analyzeInContext(scope, selector)
|
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)
|
val targetsMatch = targetsMatch(targets, targetsWhenShort)
|
||||||
|
&& (varAsFunResolvedCall == null || resolvedCallsMatch(varAsFunResolvedCall, varAsFunResolvedCallWhenShort))
|
||||||
|
|
||||||
if (receiver is KtThisExpression) {
|
if (receiver is KtThisExpression) {
|
||||||
if (!targetsMatch) return Skip
|
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 {
|
override fun shortenElement(element: KtDotQualifiedExpression): KtElement {
|
||||||
return element.replace(element.selectorExpression!!) as 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);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionFunctionVarInvokedWithQualifier.kt")
|
||||||
|
public void testExtensionFunctionVarInvokedWithQualifier() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/shortenRefs/extensionFunctionVarInvokedWithQualifier.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("InterfaceInExpression.kt")
|
@TestMetadata("InterfaceInExpression.kt")
|
||||||
public void testInterfaceInExpression() throws Exception {
|
public void testInterfaceInExpression() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/shortenRefs/InterfaceInExpression.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/shortenRefs/InterfaceInExpression.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user