From a41c4b9a0ff1b44b133de217e99c9c9402febf3f Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 31 Aug 2016 14:39:13 +0300 Subject: [PATCH] Convert lambda to reference: flexible receiver types are handled correctly #KT-13411 Fixed (cherry picked from commit ecad1c3) --- .../intentions/ConvertLambdaToReferenceIntention.kt | 6 ++++-- .../convertLambdaToReference/typeFromJava.1.java | 5 +++++ .../typeFromJava.1.java.after | 5 +++++ .../convertLambdaToReference/typeFromJava.kt | 6 ++++++ .../convertLambdaToReference/typeFromJava.kt.after | 6 ++++++ .../typeFromJavaFlexibleRecursive.1.java | 5 +++++ .../typeFromJavaFlexibleRecursive.1.java.after | 5 +++++ .../typeFromJavaFlexibleRecursive.kt | 7 +++++++ .../typeFromJavaFlexibleRecursive.kt.after | 7 +++++++ .../idea/intentions/IntentionTestGenerated.java | 12 ++++++++++++ 10 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 idea/testData/intentions/convertLambdaToReference/typeFromJava.1.java create mode 100644 idea/testData/intentions/convertLambdaToReference/typeFromJava.1.java.after create mode 100644 idea/testData/intentions/convertLambdaToReference/typeFromJava.kt create mode 100644 idea/testData/intentions/convertLambdaToReference/typeFromJava.kt.after create mode 100644 idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.1.java create mode 100644 idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.1.java.after create mode 100644 idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt create mode 100644 idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt index 5a749696453..087a36b34b6 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertLambdaToReferenceIntention.kt @@ -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 diff --git a/idea/testData/intentions/convertLambdaToReference/typeFromJava.1.java b/idea/testData/intentions/convertLambdaToReference/typeFromJava.1.java new file mode 100644 index 00000000000..dc9e7c2eaef --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/typeFromJava.1.java @@ -0,0 +1,5 @@ +import java.util.List; + +class B { + public static List text; +} diff --git a/idea/testData/intentions/convertLambdaToReference/typeFromJava.1.java.after b/idea/testData/intentions/convertLambdaToReference/typeFromJava.1.java.after new file mode 100644 index 00000000000..dc9e7c2eaef --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/typeFromJava.1.java.after @@ -0,0 +1,5 @@ +import java.util.List; + +class B { + public static List text; +} diff --git a/idea/testData/intentions/convertLambdaToReference/typeFromJava.kt b/idea/testData/intentions/convertLambdaToReference/typeFromJava.kt new file mode 100644 index 00000000000..ac9e23d43e8 --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/typeFromJava.kt @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// See KT-13411 + +fun use() { + B.text.map { it.toString() } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertLambdaToReference/typeFromJava.kt.after b/idea/testData/intentions/convertLambdaToReference/typeFromJava.kt.after new file mode 100644 index 00000000000..9a7597f313b --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/typeFromJava.kt.after @@ -0,0 +1,6 @@ +// WITH_RUNTIME +// See KT-13411 + +fun use() { + B.text.map(Any?::toString) +} \ No newline at end of file diff --git a/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.1.java b/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.1.java new file mode 100644 index 00000000000..7c5996957a2 --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.1.java @@ -0,0 +1,5 @@ +import java.util.List; + +class B { + public static List> text; +} diff --git a/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.1.java.after b/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.1.java.after new file mode 100644 index 00000000000..7c5996957a2 --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.1.java.after @@ -0,0 +1,5 @@ +import java.util.List; + +class B { + public static List> text; +} diff --git a/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt b/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt new file mode 100644 index 00000000000..a73f2ca0d57 --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// See KT-13411 + +fun use() { + val text = B.text + text.map { it.toString() } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt.after b/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt.after new file mode 100644 index 00000000000..ba11e9f8d9e --- /dev/null +++ b/idea/testData/intentions/convertLambdaToReference/typeFromJavaFlexibleRecursive.kt.after @@ -0,0 +1,7 @@ +// WITH_RUNTIME +// See KT-13411 + +fun use() { + val text = B.text + text.map(MutableList?::toString) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 9c04782c906..c8b7b6e41ea 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -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");