Convert lambda to reference: fix it works correctly for labeled expression
#KT-37214 Fixed
This commit is contained in:
committed by
Yan Zhulanow
parent
2a36a8acac
commit
b9fab1123d
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user