"Convert reference to lambda" intention: handle extension function reference with extension function call
#KT-35558 Fixed
This commit is contained in:
committed by
igoriakovlev
parent
9ff7539ff0
commit
b1e8238ea2
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET
|
|||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||||
|
import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
import org.jetbrains.kotlin.types.expressions.DoubleColonLHS
|
||||||
|
|
||||||
@@ -42,6 +43,7 @@ class ConvertReferenceToLambdaIntention : SelfTargetingOffsetIndependentIntentio
|
|||||||
val resolvedCall = callGrandParent?.getResolvedCall(context)
|
val resolvedCall = callGrandParent?.getResolvedCall(context)
|
||||||
val matchingParameterType = resolvedCall?.getParameterForArgument(valueArgumentParent)?.type
|
val matchingParameterType = resolvedCall?.getParameterForArgument(valueArgumentParent)?.type
|
||||||
val matchingParameterIsExtension = matchingParameterType?.isExtensionFunctionType ?: false
|
val matchingParameterIsExtension = matchingParameterType?.isExtensionFunctionType ?: false
|
||||||
|
val firstArgumentIsThis = matchingParameterIsExtension && resolvedCall?.resultingDescriptor?.isExtension == true
|
||||||
|
|
||||||
val receiverExpression = element.receiverExpression
|
val receiverExpression = element.receiverExpression
|
||||||
val receiverType = receiverExpression?.let {
|
val receiverType = receiverExpression?.let {
|
||||||
@@ -87,23 +89,29 @@ class ConvertReferenceToLambdaIntention : SelfTargetingOffsetIndependentIntentio
|
|||||||
if (targetDescriptor is PropertyDescriptor) "it.$targetName"
|
if (targetDescriptor is PropertyDescriptor) "it.$targetName"
|
||||||
else "it.$targetName()"
|
else "it.$targetName()"
|
||||||
else ->
|
else ->
|
||||||
"$receiverPrefix$targetName(it)"
|
"$receiverPrefix$targetName(${if (firstArgumentIsThis) "this" else "it"})"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
|
val (lambdaParams, args) = if (firstArgumentIsThis) {
|
||||||
|
val thisArgument = if (parameterNamesAndTypes.isNotEmpty()) listOf("this") else emptyList()
|
||||||
|
lambdaParameterNamesAndTypes.drop(1) to (thisArgument + parameterNamesAndTypes.drop(1).map { it.first })
|
||||||
|
} else {
|
||||||
|
lambdaParameterNamesAndTypes to parameterNamesAndTypes.map { it.first }
|
||||||
|
}
|
||||||
factory.createLambdaExpression(
|
factory.createLambdaExpression(
|
||||||
parameters = lambdaParameterNamesAndTypes.joinToString(separator = ", ") {
|
parameters = lambdaParams.joinToString(separator = ", ") {
|
||||||
if (valueArgumentParent != null) it.first
|
if (valueArgumentParent != null) it.first
|
||||||
else it.first + ": " + SOURCE_RENDERER.renderType(it.second)
|
else it.first + ": " + SOURCE_RENDERER.renderType(it.second)
|
||||||
},
|
},
|
||||||
body = if (targetDescriptor is PropertyDescriptor) {
|
body = if (targetDescriptor is PropertyDescriptor) {
|
||||||
"$receiverPrefix$targetName"
|
"$receiverPrefix$targetName"
|
||||||
} else {
|
} else {
|
||||||
parameterNamesAndTypes.joinToString(
|
args.joinToString(
|
||||||
prefix = "$receiverPrefix$targetName(",
|
prefix = "$receiverPrefix$targetName(",
|
||||||
separator = ", ",
|
separator = ", ",
|
||||||
postfix = ")"
|
postfix = ")"
|
||||||
) { it.first }
|
)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
fun func(a: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Int.foo(block: (Int) -> Unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
42.foo(::func<caret>)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
fun func(a: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Int.foo(block: (Int) -> Unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
42.foo { func(it) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
fun func(a: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Int.foo(block: Int.() -> Unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
42.foo(::func<caret>)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
fun func(a: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Int.foo(block: Int.() -> Unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
42.foo { func(this) }
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
fun func2(a: Int, b: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Int.foo(block: Int.(Int) -> Unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
42.foo(::func2<caret>)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
fun func2(a: Int, b: Int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Int.foo(block: Int.(Int) -> Unit) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main() {
|
||||||
|
42.foo { b -> func2(this, b) }
|
||||||
|
}
|
||||||
@@ -6455,6 +6455,21 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
runTest("idea/testData/intentions/convertReferenceToLambda/extensionFunctionalType.kt");
|
runTest("idea/testData/intentions/convertReferenceToLambda/extensionFunctionalType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionFunctionalType2.kt")
|
||||||
|
public void testExtensionFunctionalType2() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertReferenceToLambda/extensionFunctionalType2.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionFunctionalType3.kt")
|
||||||
|
public void testExtensionFunctionalType3() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertReferenceToLambda/extensionFunctionalType3.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("extensionFunctionalType4.kt")
|
||||||
|
public void testExtensionFunctionalType4() throws Exception {
|
||||||
|
runTest("idea/testData/intentions/convertReferenceToLambda/extensionFunctionalType4.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("extensionProperty.kt")
|
@TestMetadata("extensionProperty.kt")
|
||||||
public void testExtensionProperty() throws Exception {
|
public void testExtensionProperty() throws Exception {
|
||||||
runTest("idea/testData/intentions/convertReferenceToLambda/extensionProperty.kt");
|
runTest("idea/testData/intentions/convertReferenceToLambda/extensionProperty.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user