Change Signature: Do not move lambda out of parentheses if it neither wasn't out

before nor corresponds to the last parameter after the refactoring
 #KT-9763 Fixed
This commit is contained in:
Alexey Sedunov
2015-11-02 14:58:16 +03:00
parent f5e9d3e58f
commit 2476393754
4 changed files with 36 additions and 9 deletions
@@ -24,6 +24,7 @@ import com.intellij.usageView.UsageInfo;
import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.ContainerUtil;
import gnu.trove.TIntArrayList; import gnu.trove.TIntArrayList;
import gnu.trove.TIntProcedure; import gnu.trove.TIntProcedure;
import kotlin.ArraysKt;
import kotlin.CollectionsKt; import kotlin.CollectionsKt;
import kotlin.Pair; import kotlin.Pair;
import kotlin.Unit; import kotlin.Unit;
@@ -370,7 +371,7 @@ public class JetFunctionCallUsage extends JetUsageInfo<KtCallElement> {
parametersBuilder.append(')'); parametersBuilder.append(')');
KtValueArgumentList newArgumentList = KtPsiFactoryKt.KtPsiFactory(getProject()).createCallArguments(parametersBuilder.toString()); KtValueArgumentList newArgumentList = KtPsiFactoryKt.KtPsiFactory(getProject()).createCallArguments(parametersBuilder.toString());
Map<Integer, ? extends ValueArgument> argumentMap = getParamIndexToArgumentMap(changeInfo, oldArguments); Map<Integer, ValueArgument> argumentMap = getParamIndexToArgumentMap(changeInfo, oldArguments);
JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo(); JetParameterInfo newReceiverInfo = changeInfo.getReceiverParameterInfo();
JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver(); JetParameterInfo originalReceiverInfo = changeInfo.getMethodDescriptor().getReceiver();
@@ -410,9 +411,12 @@ public class JetFunctionCallUsage extends JetUsageInfo<KtCallElement> {
KtSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null; KtSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null;
changeArgumentName(argumentNameExpression, parameterInfo); changeArgumentName(argumentNameExpression, parameterInfo);
//noinspection ConstantConditions //noinspection ConstantConditions
newArgument.replace(oldArgument instanceof KtFunctionLiteralArgument ValueArgument argumentReplacement = (ValueArgument) newArgument.replace(
? psiFactory.createArgument(oldArgument.getArgumentExpression(), null, false) oldArgument instanceof KtFunctionLiteralArgument
: oldArgument.asElement()); ? psiFactory.createArgument(oldArgument.getArgumentExpression(), null, false)
: oldArgument.asElement()
);
argumentMap.put(parameterInfo.getOldIndex(), argumentReplacement);
} }
// TODO: process default arguments in the middle // TODO: process default arguments in the middle
else if (parameterInfo.getDefaultValueForCall() == null) { else if (parameterInfo.getDefaultValueForCall() == null) {
@@ -429,14 +433,25 @@ public class JetFunctionCallUsage extends JetUsageInfo<KtCallElement> {
} }
List<KtFunctionLiteralArgument> lambdaArguments = element.getFunctionLiteralArguments(); List<KtFunctionLiteralArgument> lambdaArguments = element.getFunctionLiteralArguments();
if (!lambdaArguments.isEmpty()) { boolean hasLambdaArgumentsBefore = !lambdaArguments.isEmpty();
if (hasLambdaArgumentsBefore) {
element.deleteChildRange(CollectionsKt.first(lambdaArguments), CollectionsKt.last(lambdaArguments)); element.deleteChildRange(CollectionsKt.first(lambdaArguments), CollectionsKt.last(lambdaArguments));
} }
//TODO: this is not correct!
KtValueArgument lastArgument = CollectionsKt.lastOrNull(newArgumentList.getArguments()); KtValueArgument lastArgument = CollectionsKt.lastOrNull(newArgumentList.getArguments());
KtFunctionLiteralExpression lastLambdaExpr =
lastArgument != null ? KtFunctionLiteralArgumentKt.unpackFunctionLiteral(lastArgument.getArgumentExpression()) : null;
JetParameterInfo lastNewParam = ArraysKt.lastOrNull(changeInfo.getNewParameters());
boolean hasTrailingLambdaInArgumentListAfter = boolean hasTrailingLambdaInArgumentListAfter =
lastArgument != null && KtFunctionLiteralArgumentKt.unpackFunctionLiteral(lastArgument.getArgumentExpression()) != null; lastLambdaExpr != null && lastNewParam != null && argumentMap.get(lastNewParam.getOldIndex()) == lastArgument;
boolean newLambdaWithDefaultValueWasAdded =
lastNewParam != null
&& lastNewParam.isNewParameter()
&& lastNewParam.getDefaultValueForCall() instanceof KtFunctionLiteralExpression
&& lastArgument != null
&& !lastArgument.isNamed();
boolean shouldMoveLambdaOut =
hasTrailingLambdaInArgumentListAfter && hasLambdaArgumentsBefore || newLambdaWithDefaultValueWasAdded;
arguments = (KtValueArgumentList) arguments.replace(newArgumentList); arguments = (KtValueArgumentList) arguments.replace(newArgumentList);
@@ -477,7 +492,7 @@ public class JetFunctionCallUsage extends JetUsageInfo<KtCallElement> {
newElement = (KtElement) elementToReplace.replace(replacingElement); newElement = (KtElement) elementToReplace.replace(replacingElement);
} }
if (hasTrailingLambdaInArgumentListAfter) { if (shouldMoveLambdaOut) {
KtCallExpression newCallExpression = KtCallExpression newCallExpression =
(KtCallExpression) (newElement instanceof KtQualifiedExpression (KtCallExpression) (newElement instanceof KtQualifiedExpression
? ((KtQualifiedExpression) newElement).getSelectorExpression() ? ((KtQualifiedExpression) newElement).getSelectorExpression()
@@ -531,7 +546,7 @@ public class JetFunctionCallUsage extends JetUsageInfo<KtCallElement> {
return null; return null;
} }
private static Map<Integer, ? extends ValueArgument> getParamIndexToArgumentMap(JetChangeInfo changeInfo, List<? extends ValueArgument> oldArguments) { private static Map<Integer, ValueArgument> getParamIndexToArgumentMap(JetChangeInfo changeInfo, List<? extends ValueArgument> oldArguments) {
Map<Integer, ValueArgument> argumentMap = new HashMap<Integer, ValueArgument>(); Map<Integer, ValueArgument> argumentMap = new HashMap<Integer, ValueArgument>();
for (int i = 0; i < oldArguments.size(); i++) { for (int i = 0; i < oldArguments.size(); i++) {
@@ -0,0 +1,5 @@
fun <caret>foo(p2: Int, p1: Int, filter: (Int) -> Boolean, p3: Int = 0){}
fun bar() {
foo(2, 1, { true })
}
@@ -0,0 +1,5 @@
fun <caret>foo(p1: Int, p2: Int, filter: (Int) -> Boolean, p3: Int = 0){}
fun bar() {
foo(1, 2, { true })
}
@@ -833,4 +833,6 @@ class JetChangeSignatureTest : KotlinCodeInsightTestCase() {
fun testJvmOverloadedRemoveNonDefault3() = doTest { removeParameter(getNewParametersCount() - 1) } fun testJvmOverloadedRemoveNonDefault3() = doTest { removeParameter(getNewParametersCount() - 1) }
fun testJvmOverloadedConstructorSwapParams() = doTest { swapParameters(1, 2) } fun testJvmOverloadedConstructorSwapParams() = doTest { swapParameters(1, 2) }
fun testDefaultAfterLambda() = doTest { swapParameters(0, 1) }
} }