fix for change signature when the order of named arguments is non-trivial
This commit is contained in:
@@ -23,6 +23,7 @@ import com.intellij.refactoring.changeSignature.ChangeInfo;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.Visibilities;
|
import org.jetbrains.jet.lang.descriptors.Visibilities;
|
||||||
import org.jetbrains.jet.lang.descriptors.Visibility;
|
import org.jetbrains.jet.lang.descriptors.Visibility;
|
||||||
import org.jetbrains.jet.lang.psi.JetFunction;
|
import org.jetbrains.jet.lang.psi.JetFunction;
|
||||||
@@ -31,7 +32,9 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
|
|||||||
import org.jetbrains.jet.lexer.JetTokens;
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
import org.jetbrains.jet.plugin.JetLanguage;
|
import org.jetbrains.jet.plugin.JetLanguage;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class JetChangeInfo implements ChangeInfo {
|
public class JetChangeInfo implements ChangeInfo {
|
||||||
private final JetFunctionPlatformDescriptor oldDescriptor;
|
private final JetFunctionPlatformDescriptor oldDescriptor;
|
||||||
@@ -43,6 +46,7 @@ public class JetChangeInfo implements ChangeInfo {
|
|||||||
private final PsiElement context;
|
private final PsiElement context;
|
||||||
private final JetGeneratedInfo generatedInfo;
|
private final JetGeneratedInfo generatedInfo;
|
||||||
private Boolean parameterNamesChanged;
|
private Boolean parameterNamesChanged;
|
||||||
|
private Map<String, Integer> oldNameToParameterIndex;
|
||||||
|
|
||||||
public JetChangeInfo(
|
public JetChangeInfo(
|
||||||
JetFunctionPlatformDescriptor oldDescriptor,
|
JetFunctionPlatformDescriptor oldDescriptor,
|
||||||
@@ -119,6 +123,22 @@ public class JetChangeInfo implements ChangeInfo {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, Integer> initOldNameToParameterIndex() {
|
||||||
|
Map<String, Integer> map = new HashMap<String, Integer>();
|
||||||
|
FunctionDescriptor descriptor = oldDescriptor.getDescriptor();
|
||||||
|
|
||||||
|
if (descriptor != null) {
|
||||||
|
List<ValueParameterDescriptor> parameters = descriptor.getValueParameters();
|
||||||
|
|
||||||
|
for (int i = 0; i < parameters.size(); i++) {
|
||||||
|
ValueParameterDescriptor oldParameter = parameters.get(i);
|
||||||
|
map.put(oldParameter.getName().getName(), i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public JetParameterInfo[] getNewParameters() {
|
public JetParameterInfo[] getNewParameters() {
|
||||||
@@ -141,6 +161,14 @@ public class JetChangeInfo implements ChangeInfo {
|
|||||||
return parameterNamesChanged;
|
return parameterNamesChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public Integer getOldParameterIndex(String oldParameterName) {
|
||||||
|
if (oldNameToParameterIndex == null)
|
||||||
|
oldNameToParameterIndex = initOldNameToParameterIndex();
|
||||||
|
|
||||||
|
return oldNameToParameterIndex.get(oldParameterName);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isParameterTypesChanged() {
|
public boolean isParameterTypesChanged() {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+2
-1
@@ -110,7 +110,8 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro
|
|||||||
for (PsiReference reference : ReferencesSearch.search(oldParam, oldParam.getUseScope())) {
|
for (PsiReference reference : ReferencesSearch.search(oldParam, oldParam.getUseScope())) {
|
||||||
PsiElement element = reference.getElement();
|
PsiElement element = reference.getElement();
|
||||||
|
|
||||||
if (element.getParent() instanceof JetSimpleNameExpression)
|
if (element.getParent() instanceof JetSimpleNameExpression &&
|
||||||
|
!(element.getParent().getParent() instanceof JetValueArgumentName)) // Usages in named arguments of the calls usage will be changed when the function call is changed
|
||||||
result.add(new JetParameterUsage((JetSimpleNameExpression) element.getParent(), parameterInfo, functionPsi, isInherited));
|
result.add(new JetParameterUsage((JetSimpleNameExpression) element.getParent(), parameterInfo, functionPsi, isInherited));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -75,6 +75,10 @@ public class JetFunctionPlatformDescriptorImpl implements JetFunctionPlatformDes
|
|||||||
parameters.remove(index);
|
parameters.remove(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearParameters() {
|
||||||
|
parameters.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getParametersCount() {
|
public int getParametersCount() {
|
||||||
return funDescriptor.getValueParameters().size();
|
return funDescriptor.getValueParameters().size();
|
||||||
|
|||||||
+97
-43
@@ -22,7 +22,9 @@ import org.jetbrains.jet.lang.psi.*;
|
|||||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeInfo;
|
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetChangeInfo;
|
||||||
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetParameterInfo;
|
import org.jetbrains.jet.plugin.refactoring.changeSignature.JetParameterInfo;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
||||||
private final PsiElement function;
|
private final PsiElement function;
|
||||||
@@ -48,51 +50,103 @@ public class JetFunctionCallUsage extends JetUsageInfo<JetCallElement> {
|
|||||||
if (arguments != null) {
|
if (arguments != null) {
|
||||||
List<JetValueArgument> oldArguments = arguments.getArguments();
|
List<JetValueArgument> oldArguments = arguments.getArguments();
|
||||||
|
|
||||||
if (changeInfo.isParameterSetOrOrderChanged()) {
|
if (changeInfo.isParameterSetOrOrderChanged())
|
||||||
StringBuilder parametersBuilder = new StringBuilder("(");
|
arguments.replace(generateNewArgumentList(changeInfo, oldArguments));
|
||||||
boolean isFirst = true;
|
else
|
||||||
|
changeArgumentNames(changeInfo, oldArguments);
|
||||||
for (JetParameterInfo parameterInfo : changeInfo.getNewParameters()) {
|
|
||||||
if (isFirst)
|
|
||||||
isFirst = false;
|
|
||||||
else
|
|
||||||
parametersBuilder.append(',');
|
|
||||||
|
|
||||||
String defaultValueText = parameterInfo.getDefaultValueText();
|
|
||||||
parametersBuilder.append(defaultValueText.isEmpty() ? '0' : defaultValueText);
|
|
||||||
}
|
|
||||||
|
|
||||||
parametersBuilder.append(')');
|
|
||||||
JetValueArgumentList newArguments = JetPsiFactory.createCallArguments(getProject(), parametersBuilder.toString());
|
|
||||||
int argIndex = 0;
|
|
||||||
|
|
||||||
for (JetValueArgument newArgument : newArguments.getArguments()) {
|
|
||||||
JetParameterInfo parameterInfo = changeInfo.getNewParameters()[argIndex++];
|
|
||||||
int oldIndex = parameterInfo.getOldIndex();
|
|
||||||
|
|
||||||
if (oldIndex >= 0 && oldIndex < oldArguments.size())
|
|
||||||
newArgument.replace(oldArguments.get(oldIndex));
|
|
||||||
else if (parameterInfo.getDefaultValueText().isEmpty())
|
|
||||||
newArgument.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
arguments.replace(newArguments);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (JetParameterInfo parameterInfo : changeInfo.getNewParameters()) {
|
|
||||||
JetValueArgument argument = parameterInfo.getOldIndex() < oldArguments.size() ? oldArguments.get(parameterInfo.getOldIndex()) : null;
|
|
||||||
JetValueArgumentName argumentName = argument != null ? argument.getArgumentName() : null;
|
|
||||||
JetSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null;
|
|
||||||
PsiElement identifier = argumentNameExpression != null ? argumentNameExpression.getIdentifier() : null;
|
|
||||||
|
|
||||||
if (identifier != null) {
|
|
||||||
String newName = parameterInfo.getInheritedName(isInherited, function, changeInfo.getFunctionDescriptor());
|
|
||||||
identifier.replace(JetPsiFactory.createIdentifier(getProject(), newName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JetValueArgumentList generateNewArgumentList(JetChangeInfo changeInfo, List<JetValueArgument> oldArguments) {
|
||||||
|
boolean isNamedCall = oldArguments.size() > 1 && oldArguments.get(0).getArgumentName() != null;
|
||||||
|
StringBuilder parametersBuilder = new StringBuilder("(");
|
||||||
|
boolean isFirst = true;
|
||||||
|
|
||||||
|
for (JetParameterInfo parameterInfo : changeInfo.getNewParameters()) {
|
||||||
|
if (isFirst)
|
||||||
|
isFirst = false;
|
||||||
|
else
|
||||||
|
parametersBuilder.append(',');
|
||||||
|
|
||||||
|
String defaultValueText = parameterInfo.getDefaultValueText();
|
||||||
|
|
||||||
|
if (isNamedCall) {
|
||||||
|
String newName = parameterInfo.getInheritedName(isInherited, function, changeInfo.getFunctionDescriptor());
|
||||||
|
parametersBuilder.append(newName).append('=');
|
||||||
|
}
|
||||||
|
|
||||||
|
parametersBuilder.append(defaultValueText.isEmpty() ? '0' : defaultValueText);
|
||||||
|
}
|
||||||
|
|
||||||
|
parametersBuilder.append(')');
|
||||||
|
JetValueArgumentList newArguments = JetPsiFactory.createCallArguments(getProject(), parametersBuilder.toString());
|
||||||
|
|
||||||
|
Map<Integer, JetValueArgument> argumentMap = getParamIndexToArgumentMap(changeInfo, oldArguments);
|
||||||
|
int argIndex = 0;
|
||||||
|
|
||||||
|
for (JetValueArgument newArgument : newArguments.getArguments()) {
|
||||||
|
JetParameterInfo parameterInfo = changeInfo.getNewParameters()[argIndex++];
|
||||||
|
JetValueArgument oldArgument = argumentMap.get(parameterInfo.getOldIndex());
|
||||||
|
|
||||||
|
if (oldArgument != null) {
|
||||||
|
JetValueArgumentName argumentName = oldArgument.getArgumentName();
|
||||||
|
JetSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null;
|
||||||
|
changeArgumentName(changeInfo, argumentNameExpression, parameterInfo);
|
||||||
|
newArgument.replace(oldArgument);
|
||||||
|
}
|
||||||
|
else if (parameterInfo.getDefaultValueText().isEmpty())
|
||||||
|
newArgument.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
return newArguments;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<Integer, JetValueArgument> getParamIndexToArgumentMap(JetChangeInfo changeInfo, List<JetValueArgument> oldArguments) {
|
||||||
|
Map<Integer, JetValueArgument> argumentMap = new HashMap<Integer, JetValueArgument>();
|
||||||
|
|
||||||
|
for (int i = 0; i < oldArguments.size(); i++) {
|
||||||
|
JetValueArgument argument = oldArguments.get(i);
|
||||||
|
JetValueArgumentName argumentName = argument.getArgumentName();
|
||||||
|
JetSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null;
|
||||||
|
String oldParameterName = argumentNameExpression != null ? argumentNameExpression.getReferencedName() : null;
|
||||||
|
|
||||||
|
if (oldParameterName != null) {
|
||||||
|
Integer oldParameterIndex = changeInfo.getOldParameterIndex(oldParameterName);
|
||||||
|
|
||||||
|
if (oldParameterIndex != null)
|
||||||
|
argumentMap.put(oldParameterIndex, argument);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
argumentMap.put(i, argument);
|
||||||
|
}
|
||||||
|
|
||||||
|
return argumentMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeArgumentNames(JetChangeInfo changeInfo, List<JetValueArgument> oldArguments) {
|
||||||
|
for (JetValueArgument argument : oldArguments) {
|
||||||
|
JetValueArgumentName argumentName = argument.getArgumentName();
|
||||||
|
JetSimpleNameExpression argumentNameExpression = argumentName != null ? argumentName.getReferenceExpression() : null;
|
||||||
|
|
||||||
|
if (argumentNameExpression != null) {
|
||||||
|
Integer oldParameterIndex = changeInfo.getOldParameterIndex(argumentNameExpression.getReferencedName());
|
||||||
|
|
||||||
|
if (oldParameterIndex != null) {
|
||||||
|
JetParameterInfo parameterInfo = changeInfo.getNewParameters()[oldParameterIndex];
|
||||||
|
changeArgumentName(changeInfo, argumentNameExpression, parameterInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeArgumentName(JetChangeInfo changeInfo, JetSimpleNameExpression argumentNameExpression, JetParameterInfo parameterInfo) {
|
||||||
|
PsiElement identifier = argumentNameExpression != null ? argumentNameExpression.getIdentifier() : null;
|
||||||
|
|
||||||
|
if (identifier != null) {
|
||||||
|
String newName = parameterInfo.getInheritedName(isInherited, function, changeInfo.getFunctionDescriptor());
|
||||||
|
identifier.replace(JetPsiFactory.createIdentifier(getProject(), newName));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ fun foo(x0: Any?,
|
|||||||
val y1 = x1;
|
val y1 = x1;
|
||||||
val y2 = x2;
|
val y2 = x2;
|
||||||
val y3 = x3;
|
val y3 = x3;
|
||||||
|
foo(x0 = null, x1 = 4, x2 = 5.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
foo(null, x1 = 2, x2 = 3.5);
|
foo(x0 = null, x1 = 2, x2 = 3.5);
|
||||||
|
foo(x0 = null, x1 = 3, x2 = 4.5);
|
||||||
|
foo(x0 = null, x1 = 4, x2 = 5.5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,11 @@ protected fun foo(x1: Int = 1, x2: Float, x3: ((Int) -> Int)?) {
|
|||||||
val y1 = x1;
|
val y1 = x1;
|
||||||
val y2 = x2;
|
val y2 = x2;
|
||||||
val y3 = x3;
|
val y3 = x3;
|
||||||
|
foo(x3 = null, x2 = 5.5, x1 = 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
foo(x1 = 2, x2 = 3.5, x3 = null);
|
foo(x1 = 2, x2 = 3.5, x3 = null);
|
||||||
|
foo(x3 = null, x1 = 3, x2 = 4.5);
|
||||||
|
foo(x3 = null, x2 = 5.5, x1 = 4);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ public fun foo(_x1: Int = 1, _x2: Float?, _x3: ((Int) -> Int)?) {
|
|||||||
val y1 = _x1;
|
val y1 = _x1;
|
||||||
val y2 = _x2;
|
val y2 = _x2;
|
||||||
val y3 = _x3;
|
val y3 = _x3;
|
||||||
|
foo(_x3 = null, _x1 = 2, _x2 = 3.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
foo(_x1 = 2, _x2 = 3.5, _x3 = null);
|
foo(_x1 = 2, _x2 = 3.5, _x3 = null);
|
||||||
|
foo(_x3 = null, _x1 = 2, _x2 = 3.5);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ fun foo(<caret>x1: Int = 1, x2: Float, x3: ((Int) -> Int)?) {
|
|||||||
val y1 = x1;
|
val y1 = x1;
|
||||||
val y2 = x2;
|
val y2 = x2;
|
||||||
val y3 = x3;
|
val y3 = x3;
|
||||||
|
foo(x3 = null, x1 = 2, x2 = 3.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bar() {
|
fun bar() {
|
||||||
foo(x1 = 2, x2 = 3.5, x3 = null);
|
foo(x1 = 2, x2 = 3.5, x3 = null);
|
||||||
|
foo(x3 = null, x1 = 2, x2 = 3.5);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user