diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReferenceToLambdaIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReferenceToLambdaIntention.kt index d6b2b4c0434..d5331fd88a3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReferenceToLambdaIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ConvertReferenceToLambdaIntention.kt @@ -18,8 +18,10 @@ package org.jetbrains.kotlin.idea.intentions import com.intellij.openapi.editor.Editor import org.jetbrains.kotlin.KtNodeTypes +import org.jetbrains.kotlin.builtins.KOTLIN_REFLECT_FQ_NAME import org.jetbrains.kotlin.builtins.isExtensionFunctionType import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor +import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.idea.core.KotlinNameSuggester @@ -29,10 +31,12 @@ import org.jetbrains.kotlin.idea.inspections.IntentionBasedInspection import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext.DOUBLE_COLON_LHS import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.expressions.DoubleColonLHS @@ -41,7 +45,6 @@ class ConvertReferenceToLambdaInspection : IntentionBasedInspection( KtCallableReferenceExpression::class.java, "Convert reference to lambda" ) { - private val SOURCE_RENDERER = IdeDescriptorRenderers.SOURCE_CODE override fun applyTo(element: KtCallableReferenceExpression, editor: Editor?) { val context = element.analyze(BodyResolveMode.PARTIAL) @@ -127,5 +130,15 @@ class ConvertReferenceToLambdaIntention : SelfTargetingOffsetIndependentIntentio } } - override fun isApplicableTo(element: KtCallableReferenceExpression) = true + override fun isApplicableTo(element: KtCallableReferenceExpression): Boolean { + val context = element.analyze(BodyResolveMode.PARTIAL) + val expectedType = context[BindingContext.EXPECTED_EXPRESSION_TYPE, element] ?: return true + val expectedTypeDescriptor = expectedType.constructor.declarationDescriptor as? ClassDescriptor ?: return true + val expectedTypeFqName = expectedTypeDescriptor.fqNameSafe + return expectedTypeFqName.parent() == KOTLIN_REFLECT_FQ_NAME + } + + companion object { + private val SOURCE_RENDERER = IdeDescriptorRenderers.SOURCE_CODE + } } \ No newline at end of file diff --git a/idea/testData/intentions/convertReferenceToLambda/kfunction.kt b/idea/testData/intentions/convertReferenceToLambda/kfunction.kt new file mode 100644 index 00000000000..35f94e90b90 --- /dev/null +++ b/idea/testData/intentions/convertReferenceToLambda/kfunction.kt @@ -0,0 +1,12 @@ +// IS_APPLICABLE: false + +import kotlin.reflect.KFunction + +fun

p(p: KFunction

) {} + +class B { + fun getS(): String = "" + init { + p(this::getS) + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertReferenceToLambda/kproperty.kt b/idea/testData/intentions/convertReferenceToLambda/kproperty.kt new file mode 100644 index 00000000000..01b9dd34548 --- /dev/null +++ b/idea/testData/intentions/convertReferenceToLambda/kproperty.kt @@ -0,0 +1,12 @@ +// IS_APPLICABLE: false + +import kotlin.reflect.KProperty + +fun

p(p: KProperty

) {} + +class B { + val s: String = "" + init { + p(this::s) + } +} \ No newline at end of file diff --git a/idea/testData/intentions/convertReferenceToLambda/kproperty0.kt b/idea/testData/intentions/convertReferenceToLambda/kproperty0.kt new file mode 100644 index 00000000000..ee59a73e4c4 --- /dev/null +++ b/idea/testData/intentions/convertReferenceToLambda/kproperty0.kt @@ -0,0 +1,12 @@ +// IS_APPLICABLE: false + +import kotlin.reflect.KProperty0 + +fun

p(p: KProperty0

) {} + +class B { + val s: String = "" + init { + p(this::s) + } +} \ 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 552ea1a1055..2d62f443406 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -5471,6 +5471,24 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("kfunction.kt") + public void testKfunction() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertReferenceToLambda/kfunction.kt"); + doTest(fileName); + } + + @TestMetadata("kproperty.kt") + public void testKproperty() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertReferenceToLambda/kproperty.kt"); + doTest(fileName); + } + + @TestMetadata("kproperty0.kt") + public void testKproperty0() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertReferenceToLambda/kproperty0.kt"); + doTest(fileName); + } + @TestMetadata("length.kt") public void testLength() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/convertReferenceToLambda/length.kt");