Convert lambda to reference: flexible receiver types are handled correctly #KT-13411 Fixed
(cherry picked from commit ecad1c3)
This commit is contained in:
committed by
Mikhail Glukhikh
parent
863e4afc7b
commit
a41c4b9a0f
@@ -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.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.kotlin.idea.core.isVisible
|
import org.jetbrains.kotlin.idea.core.isVisible
|
||||||
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection
|
||||||
|
import org.jetbrains.kotlin.idea.util.approximateFlexibleTypes
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStartOffsetIn
|
import org.jetbrains.kotlin.psi.psiUtil.getStartOffsetIn
|
||||||
@@ -115,7 +116,7 @@ class ConvertLambdaToReferenceIntention : SelfTargetingOffsetIndependentIntentio
|
|||||||
val receiverType = callReceiverDescriptor.type
|
val receiverType = callReceiverDescriptor.type
|
||||||
// No exotic receiver types
|
// No exotic receiver types
|
||||||
if (receiverType.isTypeParameter() || receiverType.isError || receiverType.isDynamic() ||
|
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
|
val receiverDeclarationDescriptor = receiverType.constructor.declarationDescriptor
|
||||||
if (receiverDeclarationDescriptor is ClassDescriptor) {
|
if (receiverDeclarationDescriptor is ClassDescriptor) {
|
||||||
// No references to object members
|
// No references to object members
|
||||||
@@ -224,7 +225,8 @@ class ConvertLambdaToReferenceIntention : SelfTargetingOffsetIndependentIntentio
|
|||||||
val receiver = expression.receiverExpression as? KtNameReferenceExpression ?: return null
|
val receiver = expression.receiverExpression as? KtNameReferenceExpression ?: return null
|
||||||
val context = receiver.analyze()
|
val context = receiver.analyze()
|
||||||
val receiverDescriptor = context[REFERENCE_TARGET, receiver] as? ParameterDescriptor ?: return null
|
val receiverDescriptor = context[REFERENCE_TARGET, receiver] as? ParameterDescriptor ?: return null
|
||||||
val receiverType = receiverDescriptor.type
|
val originalReceiverType = receiverDescriptor.type
|
||||||
|
val receiverType = originalReceiverType.approximateFlexibleTypes()
|
||||||
"$receiverType::$selectorReferenceName"
|
"$receiverType::$selectorReferenceName"
|
||||||
}
|
}
|
||||||
else -> null
|
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)
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class B {
|
||||||
|
public static List<List<Object>> text;
|
||||||
|
}
|
||||||
Vendored
+5
@@ -0,0 +1,5 @@
|
|||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class B {
|
||||||
|
public static List<List<Object>> text;
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
// See KT-13411
|
||||||
|
|
||||||
|
fun use() {
|
||||||
|
val text = B.text
|
||||||
|
text.map { <caret>it.toString() }
|
||||||
|
}
|
||||||
+7
@@ -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);
|
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")
|
@TestMetadata("unit.kt")
|
||||||
public void testUnit() throws Exception {
|
public void testUnit() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/unit.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertLambdaToReference/unit.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user