"Convert anonymous function to lambda expression" intention: add necessary lambda type parameter
#KT-37748 Fixed
This commit is contained in:
committed by
igoriakovlev
parent
d27c7ce86f
commit
46ab338ea6
@@ -9,7 +9,9 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||
import org.jetbrains.kotlin.idea.core.getLastLambdaExpression
|
||||
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParenthesesIfPossible
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
@@ -17,8 +19,10 @@ import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.contentRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getParameterForArgument
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
|
||||
class AnonymousFunctionToLambdaIntention : SelfTargetingRangeIntention<KtNamedFunction>(
|
||||
@@ -40,6 +44,14 @@ class AnonymousFunctionToLambdaIntention : SelfTargetingRangeIntention<KtNamedFu
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtNamedFunction, editor: Editor?) {
|
||||
val argument = element.getStrictParentOfType<KtValueArgument>() ?: return
|
||||
val callElement = argument.getStrictParentOfType<KtCallElement>() ?: return
|
||||
val functionParameterTypes = if (callElement.typeArgumentList == null) {
|
||||
callElement.resolveToCall()?.getParameterForArgument(argument)?.original?.type?.arguments.orEmpty()
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
val commentSaver = CommentSaver(element)
|
||||
val returnSaver = ReturnSaver(element)
|
||||
|
||||
@@ -58,6 +70,13 @@ class AnonymousFunctionToLambdaIntention : SelfTargetingRangeIntention<KtNamedFu
|
||||
appendFixedText(",")
|
||||
}
|
||||
appendName(parameter.nameAsSafeName)
|
||||
val needParameterType =
|
||||
functionParameterTypes.getOrNull(index)?.type?.constructor?.declarationDescriptor is TypeParameterDescriptor
|
||||
val typeReference = parameter.typeReference
|
||||
if (needParameterType && typeReference != null) {
|
||||
appendFixedText(": ")
|
||||
appendTypeReference(typeReference)
|
||||
}
|
||||
}
|
||||
|
||||
appendFixedText("->")
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo(p: String) {}
|
||||
|
||||
fun <T> bar(fn: (T) -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
bar(<caret>fun(x: String) {
|
||||
foo(x)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo(p: String) {}
|
||||
|
||||
fun <T> bar(fn: (T) -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
bar { x: String -> foo(x) }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo(p: String, q: Int, r: Long) {}
|
||||
|
||||
fun <T, U> bar(fn: (T, Int, U) -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
bar(<caret>fun(x: String, y: Int, z: Long) {
|
||||
foo(x, y, z)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo(p: String, q: Int, r: Long) {}
|
||||
|
||||
fun <T, U> bar(fn: (T, Int, U) -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
bar { x: String, y, z: Long -> foo(x, y, z) }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
fun foo(p: String) {}
|
||||
|
||||
fun <T> bar(fn: (T) -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
bar<String>(<caret>fun(x: String) {
|
||||
foo(x)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fun foo(p: String) {}
|
||||
|
||||
fun <T> bar(fn: (T) -> Unit) {}
|
||||
|
||||
fun test() {
|
||||
bar<String> { x -> foo(x) }
|
||||
}
|
||||
@@ -2100,6 +2100,21 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
public void testSimple() throws Exception {
|
||||
runTest("idea/testData/intentions/anonymousFunctionToLambda/simple.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameter.kt")
|
||||
public void testTypeParameter() throws Exception {
|
||||
runTest("idea/testData/intentions/anonymousFunctionToLambda/typeParameter.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameter2.kt")
|
||||
public void testTypeParameter2() throws Exception {
|
||||
runTest("idea/testData/intentions/anonymousFunctionToLambda/typeParameter2.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("typeParameter3.kt")
|
||||
public void testTypeParameter3() throws Exception {
|
||||
runTest("idea/testData/intentions/anonymousFunctionToLambda/typeParameter3.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/branched")
|
||||
|
||||
@@ -12,7 +12,7 @@ class TestJava {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
val x = ArrayList<String>()
|
||||
x.filter { o -> o == "a" }
|
||||
x.filter { o: String -> o == "a" }
|
||||
val lazy = lazy(LazyThreadSafetyMode.NONE) { "aaa" }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user