Convert lambda to reference: fix it works correctly for labeled expression

#KT-37214 Fixed
This commit is contained in:
Toshiaki Kameyama
2020-05-27 20:52:05 +09:00
committed by Yan Zhulanow
parent 2a36a8acac
commit b9fab1123d
4 changed files with 39 additions and 2 deletions
@@ -172,7 +172,7 @@ open class ConvertLambdaToReferenceIntention(textGetter: () -> String) : SelfTar
override fun applyTo(element: KtLambdaExpression, editor: Editor?) {
val referenceName = buildReferenceText(element) ?: return
val factory = KtPsiFactory(element)
val lambdaArgument = element.parent as? KtLambdaArgument
val lambdaArgument = element.parentValueArgument() as? KtLambdaArgument
if (lambdaArgument == null) {
// Without lambda argument syntax, just replace lambda with reference
val callableReferenceExpr = factory.createCallableReferenceExpression(referenceName) ?: return
@@ -220,13 +220,21 @@ open class ConvertLambdaToReferenceIntention(textGetter: () -> String) : SelfTar
companion object {
private fun KtLambdaExpression.lambdaParameterType(context: BindingContext? = null): KotlinType? {
val argument = parent as? KtValueArgument ?: return null
val argument = parentValueArgument() ?: return null
val callExpression = argument.getStrictParentOfType<KtCallExpression>() ?: return null
return callExpression
.getResolvedCall(context ?: analyze(BodyResolveMode.PARTIAL))
?.getParameterForArgument(argument)?.type
}
private fun KtLambdaExpression.parentValueArgument(): KtValueArgument? {
return if (parent is KtLabeledExpression) {
parent.parent
} else {
parent
} as? KtValueArgument
}
private fun buildReferenceText(lambdaExpression: KtLambdaExpression, shortTypes: Boolean): String? {
val lambdaParameterType = lambdaExpression.lambdaParameterType()
return when (val singleStatement = lambdaExpression.singleStatementOrNull()) {
@@ -0,0 +1,13 @@
class A {
fun f1() {}
}
fun myA(func: A.() -> Unit) {
A().func()
}
fun main() {
myA foo@{
<caret>this@foo.f1()
}
}
@@ -0,0 +1,11 @@
class A {
fun f1() {}
}
fun myA(func: A.() -> Unit) {
A().func()
}
fun main() {
myA(A::f1)
}
@@ -5065,6 +5065,11 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
runTest("idea/testData/intentions/convertLambdaToReference/inner.kt");
}
@TestMetadata("labeledThis.kt")
public void testLabeledThis() throws Exception {
runTest("idea/testData/intentions/convertLambdaToReference/labeledThis.kt");
}
@TestMetadata("mapTo.kt")
public void testMapTo() throws Exception {
runTest("idea/testData/intentions/convertLambdaToReference/mapTo.kt");