KT-14370 Completion inserts fully qualified name for any Java interface with single abstract method (SAM-interface)

#KT-14370 Fixed
This commit is contained in:
Valentin Kipyatkov
2016-11-07 20:43:58 +03:00
parent b8981ec546
commit 9b55ad82a0
8 changed files with 55 additions and 2 deletions
@@ -0,0 +1,5 @@
fun f() {
Cal<caret>
}
// ELEMENT: "Callable"
@@ -0,0 +1,7 @@
import java.util.concurrent.Callable
fun f() {
Callable<caret>
}
// ELEMENT: "Callable"
@@ -113,6 +113,12 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion
doTest(fileName);
}
@TestMetadata("JavaSAM.kt")
public void testJavaSAM() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/JavaSAM.kt");
doTest(fileName);
}
@TestMetadata("KT11633.kt")
public void testKT11633() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/idea-completion/testData/handlers/basic/KT11633.kt");
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.idea.util.ImportInsertHelper
import org.jetbrains.kotlin.idea.util.getResolutionScope
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getQualifiedExpressionForReceiver
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.resolve.BindingContext
@@ -432,8 +433,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
val varAsFunResolvedCall = callee.getResolvedCall(bindingContext) as? VariableAsFunctionResolvedCall
if (targets.isEmpty()) return Skip
val selectorCopy = selector.copy() as KtReferenceExpression
val newContext = selectorCopy.analyzeAsReplacement(element, bindingContext, resolutionFacade)
val (newContext, selectorCopy) = copyAndAnalyzeSelector(element, bindingContext)
val newCallee = selectorCopy.getCalleeExpressionIfAny() as KtReferenceExpression
val targetsWhenShort = newCallee.targets(newContext)
val varAsFunResolvedCallWhenShort = newCallee.getResolvedCall(newContext) as? VariableAsFunctionResolvedCall
@@ -465,6 +465,22 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
}
}
private fun copyAndAnalyzeSelector(element: KtDotQualifiedExpression, bindingContext: BindingContext): Pair<BindingContext, KtExpression> {
val selector = element.selectorExpression!!
val qualifiedAbove = element.getQualifiedExpressionForReceiver()
if (qualifiedAbove == null) {
val copied = selector.copied()
val newBindingContext = copied.analyzeAsReplacement(element, bindingContext, resolutionFacade)
return newBindingContext to copied
}
else {
val qualifiedAboveCopy = qualifiedAbove.copied()
qualifiedAboveCopy.receiverExpression.replace(selector)
val newBindingContext = qualifiedAboveCopy.analyzeAsReplacement(qualifiedAbove, bindingContext, resolutionFacade)
return newBindingContext to qualifiedAboveCopy.receiverExpression
}
}
private fun targetsMatch(targets1: Collection<DeclarationDescriptor>, targets2: Collection<DeclarationDescriptor>): Boolean {
if (targets1.size != targets2.size) return false
if (targets1.size == 1) {
+5
View File
@@ -0,0 +1,5 @@
package dependency
interface PseudoSAM
fun PseudoSAM(p: Int): PseudoSAM = TODO()
+3
View File
@@ -0,0 +1,3 @@
fun foo() {
<selection>dependency.PseudoSAM</selection>.xxx
}
+5
View File
@@ -0,0 +1,5 @@
import dependency.PseudoSAM
fun foo() {
PseudoSAM.xxx
}
@@ -89,6 +89,12 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest {
doTest(fileName);
}
@TestMetadata("kt14370.kt")
public void testKt14370() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/shortenRefs/kt14370.kt");
doTest(fileName);
}
@TestMetadata("noShortening.kt")
public void testNoShortening() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/shortenRefs/noShortening.kt");