KT-17503 add check whether callable reference is acceptable in lambda
This commit is contained in:
+19
@@ -21,12 +21,18 @@ import com.intellij.codeInspection.LocalInspectionToolSession
|
||||
import com.intellij.codeInspection.ProblemHighlightType
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.builtins.getReturnTypeFromFunctionType
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.builtins.isBuiltinFunctionalTypeOrSubtype
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.intentions.ConvertLambdaToReferenceIntention
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtCallableReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.psi.KtVisitorVoid
|
||||
import org.jetbrains.kotlin.psi.ValueArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParentResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
|
||||
class MoveSuspiciousCallableReferenceIntoParenthesesInspection : AbstractKotlinInspection() {
|
||||
@@ -35,6 +41,19 @@ class MoveSuspiciousCallableReferenceIntoParenthesesInspection : AbstractKotlinI
|
||||
override fun visitLambdaExpression(lambdaExpression: KtLambdaExpression) {
|
||||
val callableReference = lambdaExpression.bodyExpression?.statements?.singleOrNull() as? KtCallableReferenceExpression
|
||||
if (callableReference != null) {
|
||||
val context = lambdaExpression.analyze()
|
||||
val parentResolvedCall = lambdaExpression.getParentResolvedCall(context)
|
||||
if (parentResolvedCall != null) {
|
||||
val originalParameterDescriptor =
|
||||
parentResolvedCall.getParameterForArgument(lambdaExpression.parent as? ValueArgument)?.original
|
||||
if (originalParameterDescriptor != null) {
|
||||
val expectedType = originalParameterDescriptor.type
|
||||
if (expectedType.isBuiltinFunctionalType) {
|
||||
val returnType = expectedType.getReturnTypeFromFunctionType()
|
||||
if (returnType.isBuiltinFunctionalTypeOrSubtype) return
|
||||
}
|
||||
}
|
||||
}
|
||||
holder.registerProblem(
|
||||
lambdaExpression,
|
||||
"Suspicious callable reference as the only lambda element",
|
||||
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
// WITH_RUNTIME
|
||||
// PROBLEM: none
|
||||
|
||||
fun foo(arg: Int) = arg.toString()
|
||||
|
||||
fun bar(f: () -> (Int) -> String) {}
|
||||
|
||||
val someFun = bar { <caret>::foo }
|
||||
@@ -50,6 +50,12 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("expectedFunction.kt")
|
||||
public void testExpectedFunction() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/moveSuspiciousCallableReferenceIntoParentheses/expectedFunction.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("it.kt")
|
||||
public void testIt() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/moveSuspiciousCallableReferenceIntoParentheses/it.kt");
|
||||
|
||||
Reference in New Issue
Block a user