Do not suggest "convert ref to lambda" for reflect types #KT-19283 Fixed

This commit is contained in:
Mikhail Glukhikh
2017-12-21 18:45:36 +03:00
parent fc93e7a727
commit 3f00592443
5 changed files with 69 additions and 2 deletions
@@ -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<KtCallableRe
class ConvertReferenceToLambdaIntention : SelfTargetingOffsetIndependentIntention<KtCallableReferenceExpression>(
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
}
}
@@ -0,0 +1,12 @@
// IS_APPLICABLE: false
import kotlin.reflect.KFunction
fun <P : Any> p(p: KFunction<P>) {}
class B {
fun getS(): String = ""
init {
p(<caret>this::getS)
}
}
@@ -0,0 +1,12 @@
// IS_APPLICABLE: false
import kotlin.reflect.KProperty
fun <P : Any> p(p: KProperty<P>) {}
class B {
val s: String = ""
init {
p(<caret>this::s)
}
}
@@ -0,0 +1,12 @@
// IS_APPLICABLE: false
import kotlin.reflect.KProperty0
fun <P : Any> p(p: KProperty0<P>) {}
class B {
val s: String = ""
init {
p(<caret>this::s)
}
}
@@ -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");