Make "Specify explicit lambda signature" available on whole lambda

So #KT-22492 Fixed
This commit is contained in:
Toshiaki Kameyama
2018-02-09 09:48:21 +03:00
committed by Mikhail Glukhikh
parent 059a797e10
commit 5499078fcc
6 changed files with 25 additions and 29 deletions
@@ -25,23 +25,15 @@ import org.jetbrains.kotlin.idea.core.ShortenReferences
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.psiUtil.endOffset
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.isError
class SpecifyExplicitLambdaSignatureIntention : SelfTargetingIntention<KtLambdaExpression>(KtLambdaExpression::class.java, "Specify explicit lambda signature"), LowPriorityAction {
class SpecifyExplicitLambdaSignatureIntention :
SelfTargetingIntention<KtLambdaExpression>(KtLambdaExpression::class.java, "Specify explicit lambda signature"), LowPriorityAction {
override fun isApplicableTo(element: KtLambdaExpression, caretOffset: Int): Boolean {
val arrow = element.functionLiteral.arrow
if (arrow != null) {
if (caretOffset > arrow.endOffset) return false
if (element.valueParameters.all { it.typeReference != null }) return false
}
else {
if (!element.leftCurlyBrace.textRange.containsOffset(caretOffset)) return false
}
if (element.functionLiteral.arrow != null && element.valueParameters.all { it.typeReference != null }) return false
val functionDescriptor = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.FUNCTION, element.functionLiteral] ?: return false
return functionDescriptor.valueParameters.none { it.type.isError }
}
@@ -55,12 +47,12 @@ class SpecifyExplicitLambdaSignatureIntention : SelfTargetingIntention<KtLambdaE
val functionDescriptor = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.FUNCTION, functionLiteral]!!
val parameterString = functionDescriptor.valueParameters
.mapIndexed { index, parameterDescriptor ->
parameterDescriptor.render(psiName = functionLiteral.valueParameters.getOrNull(index)?.let {
it.name ?: it.destructuringDeclaration?.text
} )
}
.joinToString()
.mapIndexed { index, parameterDescriptor ->
parameterDescriptor.render(psiName = functionLiteral.valueParameters.getOrNull(index)?.let {
it.name ?: it.destructuringDeclaration?.text
})
}
.joinToString()
applyWithParameters(element, parameterString)
}
@@ -72,8 +64,7 @@ class SpecifyExplicitLambdaSignatureIntention : SelfTargetingIntention<KtLambdaE
val oldParameterList = functionLiteral.valueParameterList
if (oldParameterList != null && newParameterList != null) {
oldParameterList.replace(newParameterList)
}
else {
} else {
val openBraceElement = functionLiteral.lBrace
val nextSibling = openBraceElement.nextSibling
val addNewline = nextSibling is PsiWhiteSpace && nextSibling.text?.contains("\n") ?: false
@@ -0,0 +1,4 @@
fun foo(f: (String) -> Int) {}
fun test() {
foo { it.length <caret>}
}
@@ -0,0 +1,4 @@
fun foo(f: (String) -> Int) {}
fun test() {
foo { it: String -> it.length <caret>}
}
@@ -1,4 +0,0 @@
// IS_APPLICABLE: false
fun main() {
val sum : (Int, Int) -> Int = { x, y -> <caret>x + y }
}
@@ -4,6 +4,7 @@
// ACTION: Introduce local variable
// ACTION: Move lambda argument into parentheses
// ACTION: Replace with safe (this?.) call
// ACTION: Specify explicit lambda signature
// ERROR: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
fun String?.foo(a: String?) {
@@ -14682,6 +14682,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("cursorOnRightBrace.kt")
public void testCursorOnRightBrace() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/cursorOnRightBrace.kt");
doTest(fileName);
}
@TestMetadata("delegate.kt")
public void testDelegate() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/delegate.kt");
@@ -14718,12 +14724,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName);
}
@TestMetadata("invalidCursorPosition.kt")
public void testInvalidCursorPosition() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/invalidCursorPosition.kt");
doTest(fileName);
}
@TestMetadata("lambdaWithLambdaAsParam.kt")
public void testLambdaWithLambdaAsParam() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/lambdaWithLambdaAsParam.kt");