Convert lambda to reference: support generic function call

#KT-14578 Fixed
#KT-14395 Fixed
This commit is contained in:
Toshiaki Kameyama
2020-06-23 11:58:01 +09:00
committed by Roman Golyshev
parent 2137a4b1e5
commit 7ea1700b78
8 changed files with 61 additions and 2 deletions
@@ -88,7 +88,7 @@ open class ConvertLambdaToReferenceIntention(textGetter: () -> String) : SelfTar
) return false
// No references with type parameters
if (calleeDescriptor.typeParameters.isNotEmpty()) return false
if (calleeDescriptor.typeParameters.isNotEmpty() && lambdaExpression.parentValueArgument() == null) return false
// No references to Java synthetic properties
if (calleeDescriptor is SyntheticJavaPropertyDescriptor) return false
@@ -237,6 +237,12 @@ open class ConvertLambdaToReferenceIntention(textGetter: () -> String) : SelfTar
}
lambdaArgument.delete()
}
outerCallExpression.typeArgumentList?.let {
if (RemoveExplicitTypeArgumentsIntention.isApplicableTo(it, approximateFlexible = false)) {
it.delete()
}
}
}
}
@@ -257,7 +263,9 @@ open class ConvertLambdaToReferenceIntention(textGetter: () -> String) : SelfTar
val calledFunctionInLambda = lambda.singleStatementOrNull()
?.getResolvedCall(context)?.resultingDescriptor as? FunctionDescriptor ?: return
val overloadedFunctions = calledFunctionInLambda.overloadedFunctions()
if (overloadedFunctions.count { it.valueParameters.size == calledFunctionInLambda.valueParameters.size } < 2) return
if (overloadedFunctions.count { it.valueParameters.size == calledFunctionInLambda.valueParameters.size } < 2
&& calledFunctionInLambda.typeParameters.isEmpty()
) return
if (InsertExplicitTypeArgumentsIntention.isApplicableTo(this, context)) {
InsertExplicitTypeArgumentsIntention.applyTo(this)
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun <T> foo(i: Int): T? = null
fun test(list: List<Int>) {
list.mapNotNull <caret>{ foo<String>(it) }
}
@@ -0,0 +1,6 @@
// WITH_RUNTIME
fun <T> foo(i: Int): T? = null
fun test(list: List<Int>) {
list.mapNotNull<Int, String>(::foo)
}
@@ -0,0 +1,8 @@
// WITH_RUNTIME
interface CD
fun <D : CD> D.foo(): D? = null
fun test(x: List<CD>) {
x.mapNotNull <caret>{ it.foo() }
}
@@ -0,0 +1,8 @@
// WITH_RUNTIME
interface CD
fun <D : CD> D.foo(): D? = null
fun test(x: List<CD>) {
x.mapNotNull(CD::foo)
}
@@ -0,0 +1,4 @@
// WITH_RUNTIME
fun test() {
listOf(listOf(1)).filter <caret>{ it.isNotEmpty() }
}
@@ -0,0 +1,4 @@
// WITH_RUNTIME
fun test() {
listOf(listOf(1)).filter(List<Int>::isNotEmpty)
}
@@ -5095,6 +5095,21 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
runTest("idea/testData/intentions/convertLambdaToReference/generic.kt");
}
@TestMetadata("generic2.kt")
public void testGeneric2() throws Exception {
runTest("idea/testData/intentions/convertLambdaToReference/generic2.kt");
}
@TestMetadata("generic3.kt")
public void testGeneric3() throws Exception {
runTest("idea/testData/intentions/convertLambdaToReference/generic3.kt");
}
@TestMetadata("generic4.kt")
public void testGeneric4() throws Exception {
runTest("idea/testData/intentions/convertLambdaToReference/generic4.kt");
}
@TestMetadata("globalProperty.kt")
public void testGlobalProperty() throws Exception {
runTest("idea/testData/intentions/convertLambdaToReference/globalProperty.kt");