Specify lambda signature: handle special parameters correctly
So #KT-17372 Fixed
This commit is contained in:
+11
-2
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.intentions
|
|||||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.psi.PsiWhiteSpace
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
|
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
@@ -44,13 +45,21 @@ class SpecifyExplicitLambdaSignatureIntention : SelfTargetingIntention<KtLambdaE
|
|||||||
return functionDescriptor.valueParameters.none { it.type.isError }
|
return functionDescriptor.valueParameters.none { it.type.isError }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ValueParameterDescriptor.render(psiName: String?): String = IdeDescriptorRenderers.SOURCE_CODE.let {
|
||||||
|
"${psiName ?: it.renderName(name)}: ${it.renderType(type)}"
|
||||||
|
}
|
||||||
|
|
||||||
override fun applyTo(element: KtLambdaExpression, editor: Editor?) {
|
override fun applyTo(element: KtLambdaExpression, editor: Editor?) {
|
||||||
val functionLiteral = element.functionLiteral
|
val functionLiteral = element.functionLiteral
|
||||||
val functionDescriptor = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.FUNCTION, functionLiteral]!!
|
val functionDescriptor = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.FUNCTION, functionLiteral]!!
|
||||||
|
|
||||||
val parameterString = functionDescriptor.valueParameters
|
val parameterString = functionDescriptor.valueParameters
|
||||||
.map { "${it.name}: ${IdeDescriptorRenderers.SOURCE_CODE.renderType(it.type)}" }
|
.mapIndexed { index, parameterDescriptor ->
|
||||||
.joinToString(", ")
|
parameterDescriptor.render(psiName = functionLiteral.valueParameters.getOrNull(index)?.let {
|
||||||
|
it.name ?: it.destructuringDeclaration?.text
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
.joinToString()
|
||||||
applyWithParameters(element, parameterString)
|
applyWithParameters(element, parameterString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class Declaration {
|
||||||
|
fun lambdaType(p: Int, f: (Int) -> Int) = f(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun call(declaration: Declaration) {
|
||||||
|
declaration.lambdaType(10) {<caret> _ -> 11 }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class Declaration {
|
||||||
|
fun lambdaType(p: Int, f: (Int) -> Int) = f(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun call(declaration: Declaration) {
|
||||||
|
declaration.lambdaType(10) { _: Int -> 11 }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
data class Declaration(val x: Int, val y: Int) {
|
||||||
|
fun lambdaType(p: Declaration, f: (Declaration) -> Int) = f(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun call(declaration: Declaration) {
|
||||||
|
declaration.lambdaType(declaration) {<caret> (x, y) -> 11 }
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
data class Declaration(val x: Int, val y: Int) {
|
||||||
|
fun lambdaType(p: Declaration, f: (Declaration) -> Int) = f(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun call(declaration: Declaration) {
|
||||||
|
declaration.lambdaType(declaration) { (x, y): Declaration -> 11 }
|
||||||
|
}
|
||||||
@@ -14407,6 +14407,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/specifyExplicitLambdaSignature"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/specifyExplicitLambdaSignature"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("anonymous.kt")
|
||||||
|
public void testAnonymous() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/anonymous.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("coercionToUnit.kt")
|
@TestMetadata("coercionToUnit.kt")
|
||||||
public void testCoercionToUnit() throws Exception {
|
public void testCoercionToUnit() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/coercionToUnit.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/coercionToUnit.kt");
|
||||||
@@ -14419,6 +14425,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("destructuring.kt")
|
||||||
|
public void testDestructuring() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/destructuring.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("emptyParamListWithBrackets.kt")
|
@TestMetadata("emptyParamListWithBrackets.kt")
|
||||||
public void testEmptyParamListWithBrackets() throws Exception {
|
public void testEmptyParamListWithBrackets() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/emptyParamListWithBrackets.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/specifyExplicitLambdaSignature/emptyParamListWithBrackets.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user