Extract Function: Fix call replacement for the case of lambda extraction
This commit is contained in:
+23
-1
@@ -71,6 +71,7 @@ import kotlin.properties.Delegates
|
|||||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.traverse
|
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.traverse
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder
|
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder
|
||||||
import org.jetbrains.jet.lang.resolve.bindingContextUtil.getTargetFunctionDescriptor
|
import org.jetbrains.jet.lang.resolve.bindingContextUtil.getTargetFunctionDescriptor
|
||||||
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
|
|
||||||
private val DEFAULT_FUNCTION_NAME = "myFun"
|
private val DEFAULT_FUNCTION_NAME = "myFun"
|
||||||
private val DEFAULT_RETURN_TYPE = KotlinBuiltIns.getInstance().getUnitType()
|
private val DEFAULT_RETURN_TYPE = KotlinBuiltIns.getInstance().getUnitType()
|
||||||
@@ -811,6 +812,27 @@ fun ExtractionDescriptor.generateFunction(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun insertCall(anchor: PsiElement, wrappedCall: JetExpression) {
|
||||||
|
val firstExpression = extractionData.getExpressions().firstOrNull()
|
||||||
|
val enclosingCall = firstExpression?.getParent() as? JetCallExpression
|
||||||
|
if (enclosingCall == null || firstExpression !in enclosingCall.getFunctionLiteralArguments()) {
|
||||||
|
anchor.replace(wrappedCall)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val argumentListExt = JetPsiFactory.createCallArguments(project, "(${wrappedCall.getText()})")
|
||||||
|
val argumentList = enclosingCall.getValueArgumentList()
|
||||||
|
if (argumentList == null) {
|
||||||
|
(anchor.getPrevSibling() as? PsiWhiteSpace)?.let { it.delete() }
|
||||||
|
anchor.replace(argumentListExt)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val newArgText = (argumentList.getArguments() + argumentListExt.getArguments()).map { it.getText() }.joinToString(", ", "(", ")")
|
||||||
|
argumentList.replace(JetPsiFactory.createCallArguments(project, newArgText))
|
||||||
|
anchor.delete()
|
||||||
|
}
|
||||||
|
|
||||||
fun makeCall(function: JetNamedFunction): JetNamedFunction {
|
fun makeCall(function: JetNamedFunction): JetNamedFunction {
|
||||||
val anchor = extractionData.originalElements.first
|
val anchor = extractionData.originalElements.first
|
||||||
if (anchor == null) return function
|
if (anchor == null) return function
|
||||||
@@ -849,7 +871,7 @@ fun ExtractionDescriptor.generateFunction(
|
|||||||
else ->
|
else ->
|
||||||
JetPsiFactory.createExpression(project, callText)
|
JetPsiFactory.createExpression(project, callText)
|
||||||
}
|
}
|
||||||
anchor.replace(wrappedCall)
|
insertCall(anchor, wrappedCall)
|
||||||
|
|
||||||
return function
|
return function
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun <T> Array<T>.check(f: (T) -> Boolean): Boolean = false
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(t: Array<Int>) {
|
||||||
|
t.check() <selection>{ it + 1 > 1 }</selection>
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun <T> Array<T>.check(f: (T) -> Boolean): Boolean = false
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(t: Array<Int>) {
|
||||||
|
t.check(function())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun function(): (Int) -> Boolean {
|
||||||
|
return { it + 1 > 1 }
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun <T> Array<T>.check(f: (T) -> Boolean): Boolean = false
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(t: Array<Int>) {
|
||||||
|
t.check <selection>{ it + 1 > 1 }</selection>
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun <T> Array<T>.check(f: (T) -> Boolean): Boolean = false
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(t: Array<Int>) {
|
||||||
|
t.check(function())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun function(): (Int) -> Boolean {
|
||||||
|
return { it + 1 > 1 }
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
fun <T> Array<T>.check(a: Int, b: Int f: (T) -> Boolean): Boolean = false
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(t: Array<Int>) {
|
||||||
|
t.check(1, 2) <selection>{ it + 1 > 1 }</selection>
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
fun <T> Array<T>.check(a: Int, b: Int f: (T) -> Boolean): Boolean = false
|
||||||
|
|
||||||
|
// SIBLING:
|
||||||
|
fun foo(t: Array<Int>) {
|
||||||
|
t.check(1, 2, function())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun function(): (Int) -> Boolean {
|
||||||
|
return { it + 1 > 1 }
|
||||||
|
}
|
||||||
+15
@@ -447,6 +447,21 @@ public class JetExtractionTestGenerated extends AbstractJetExtractionTest {
|
|||||||
doExtractFunctionTest("idea/testData/refactoring/extractFunction/controlFlow/evaluateExpression/simpleEvalExpr.kt");
|
doExtractFunctionTest("idea/testData/refactoring/extractFunction/controlFlow/evaluateExpression/simpleEvalExpr.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("trailingLambdaEmptyArgList.kt")
|
||||||
|
public void testTrailingLambdaEmptyArgList() throws Exception {
|
||||||
|
doExtractFunctionTest("idea/testData/refactoring/extractFunction/controlFlow/evaluateExpression/trailingLambdaEmptyArgList.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("trailingLambdaNoArgList.kt")
|
||||||
|
public void testTrailingLambdaNoArgList() throws Exception {
|
||||||
|
doExtractFunctionTest("idea/testData/refactoring/extractFunction/controlFlow/evaluateExpression/trailingLambdaNoArgList.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("trailingLambdaNonEmptyArgList.kt")
|
||||||
|
public void testTrailingLambdaNonEmptyArgList() throws Exception {
|
||||||
|
doExtractFunctionTest("idea/testData/refactoring/extractFunction/controlFlow/evaluateExpression/trailingLambdaNonEmptyArgList.kt");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("idea/testData/refactoring/extractFunction/controlFlow/outputValues")
|
@TestMetadata("idea/testData/refactoring/extractFunction/controlFlow/outputValues")
|
||||||
|
|||||||
Reference in New Issue
Block a user