Convert lambda to reference: flexible receiver types are handled correctly #KT-13411 Fixed

(cherry picked from commit ecad1c3)
This commit is contained in:
Mikhail Glukhikh
2016-08-31 14:39:13 +03:00
committed by Mikhail Glukhikh
parent 863e4afc7b
commit a41c4b9a0f
10 changed files with 62 additions and 2 deletions
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.core.isVisible
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.psi.psiUtil.getStartOffsetIn
@@ -115,7 +116,7 @@ class ConvertLambdaToReferenceIntention : SelfTargetingOffsetIndependentIntentio
val receiverType = callReceiverDescriptor.type
// No exotic receiver types
if (receiverType.isTypeParameter() || receiverType.isError || receiverType.isDynamic() ||
receiverType.isFlexibleRecursive() || !receiverType.constructor.isDenotable || receiverType.isFunctionType) return false
!receiverType.constructor.isDenotable || receiverType.isFunctionType) return false
val receiverDeclarationDescriptor = receiverType.constructor.declarationDescriptor
if (receiverDeclarationDescriptor is ClassDescriptor) {
// No references to object members
@@ -224,7 +225,8 @@ class ConvertLambdaToReferenceIntention : SelfTargetingOffsetIndependentIntentio
val receiver = expression.receiverExpression as? KtNameReferenceExpression ?: return null
val context = receiver.analyze()
val receiverDescriptor = context[REFERENCE_TARGET, receiver] as? ParameterDescriptor ?: return null
val receiverType = receiverDescriptor.type
val originalReceiverType = receiverDescriptor.type
val receiverType = originalReceiverType.approximateFlexibleTypes()
"$receiverType::$selectorReferenceName"
}
else -> null
@@ -0,0 +1,5 @@
import java.util.List;
class B {
public static List<Object> text;
}
@@ -0,0 +1,5 @@
import java.util.List;
class B {
public static List<Object> text;
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
// See KT-13411
fun use() {
B.text.map { <caret>it.toString() }
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
// See KT-13411
fun use() {
B.text.map(Any?::toString)
}
@@ -0,0 +1,5 @@
import java.util.List;
class B {
public static List<List<Object>> text;
}
@@ -0,0 +1,5 @@
import java.util.List;
class B {
public static List<List<Object>> text;
}
@@ -0,0 +1,7 @@
// WITH_RUNTIME
// See KT-13411
fun use() {
val text = B.text
text.map { <caret>it.toString() }
}
@@ -0,0 +1,7 @@
// WITH_RUNTIME
// See KT-13411
fun use() {
val text = B.text
text.map(MutableList<Any>?::toString)
}
@@ -4051,6 +4051,18 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("typeFromJava.kt")
public void testTypeFromJava() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/typeFromJava.kt");
doTest(fileName);
}
@TestMetadata("typeFromJavaFlexibleRecursive.kt")
public void testTypeFromJavaFlexibleRecursive() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt");
doTest(fileName);
}
@TestMetadata("unit.kt")
public void testUnit() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/unit.kt");