mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-8174 Always use actual arguments as default values for new parameters
even if names referenced in them are not available at the places of some usages and the definition. It's user responsibility to review them and ensure that refactoring won't cause any errors. This approach follows the one used for Java.
This commit is contained in:
+8
-11
@@ -76,20 +76,14 @@ public class PyChangeSignatureQuickFix extends LocalQuickFixOnPsiElement {
|
||||
final Set<String> usedParamNames = new HashSet<>();
|
||||
for (PyExpression arg : mapping.getUnmappedArguments()) {
|
||||
if (arg instanceof PyKeywordArgument) {
|
||||
final String defaultValueText;
|
||||
final PyExpression value = ((PyKeywordArgument)arg).getValueExpression();
|
||||
if (value != null && PyRefactoringUtil.isSimpleExpression(value) && !value.textContains('\n')) {
|
||||
defaultValueText = value.getText();
|
||||
}
|
||||
else {
|
||||
defaultValueText = ApplicationManager.getApplication().isUnitTestMode() ? "None" : "";
|
||||
}
|
||||
final String valueText = value != null ? value.getText() : "";
|
||||
newParameters.add(Pair.create(parameters.length - 1,
|
||||
new PyParameterInfo(-1, ((PyKeywordArgument)arg).getKeyword(), defaultValueText, true)));
|
||||
new PyParameterInfo(-1, ((PyKeywordArgument)arg).getKeyword(), valueText, true)));
|
||||
}
|
||||
else {
|
||||
final String paramName = generateParameterName(arg, function, usedParamNames, context);
|
||||
newParameters.add(Pair.create(positionalParamAnchor, new PyParameterInfo(-1, paramName, "", false)));
|
||||
newParameters.add(Pair.create(positionalParamAnchor, new PyParameterInfo(-1, paramName, arg.getText(), false)));
|
||||
usedParamNames.add(paramName);
|
||||
}
|
||||
}
|
||||
@@ -109,12 +103,15 @@ public class PyChangeSignatureQuickFix extends LocalQuickFixOnPsiElement {
|
||||
}
|
||||
return new PyChangeSignatureQuickFix(function, extraParams, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private final List<Pair<Integer, PyParameterInfo>> myExtraParameters;
|
||||
private final SmartPsiElementPointer<PyCallExpression> myOriginalCallExpression;
|
||||
|
||||
|
||||
/**
|
||||
* @param extraParameters new parameters anchored by indexes of the existing parameters they should be inserted <em>after</em>
|
||||
* (-1 in case they should precede the first parameter)
|
||||
*/
|
||||
public PyChangeSignatureQuickFix(@NotNull PyFunction function,
|
||||
@NotNull List<Pair<Integer, PyParameterInfo>> extraParameters,
|
||||
@Nullable PyCallExpression expression) {
|
||||
|
||||
@@ -17,7 +17,6 @@ package com.jetbrains.python.refactoring;
|
||||
|
||||
import com.intellij.codeInsight.PsiEquivalenceUtil;
|
||||
import com.intellij.find.findUsages.FindUsagesHandler;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
@@ -29,7 +28,6 @@ import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.findUsages.PyFindUsagesHandlerFactory;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.refactoring.introduce.IntroduceValidator;
|
||||
@@ -399,16 +397,4 @@ public class PyRefactoringUtil {
|
||||
public static boolean isValidNewName(@NotNull String name, @NotNull PsiElement scopeAnchor) {
|
||||
return !(IntroduceValidator.isDefinedInScope(name, scopeAnchor) || PyNames.isReserved(name));
|
||||
}
|
||||
|
||||
public static boolean isSimpleExpression(@NotNull PyExpression value) {
|
||||
if (value instanceof PyLiteralExpression) {
|
||||
final ASTNode node = value.getNode();
|
||||
// Check that string literal doesn't contain multiple glued nodes
|
||||
return node.getChildren(null).length == 1 && PyTokenTypes.SCALAR_LITERALS.contains(node.getFirstChildNode().getElementType());
|
||||
}
|
||||
else if (value instanceof PyReferenceExpression) {
|
||||
return PyUtil.isPy2ReservedWord((PyReferenceExpression)value);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
def func():
|
||||
pass
|
||||
|
||||
|
||||
func<warning descr="Unexpected argument(s)">(<caret><warning descr="Unexpected argument">42</warning>, <warning descr="Unexpected argument">foo='spam'</warning>)</warning>
|
||||
func()
|
||||
@@ -0,0 +1,6 @@
|
||||
def func(i, foo='spam'):
|
||||
pass
|
||||
|
||||
|
||||
func(42, foo='spam')
|
||||
func(42)
|
||||
@@ -657,6 +657,11 @@ public class PyQuickFixTest extends PyTestCase {
|
||||
doInspectionTest(PyArgumentListInspection.class, "<html>Change signature of", true, true);
|
||||
}
|
||||
|
||||
// PY-8174
|
||||
public void testAddParameterDefaultValues() {
|
||||
doInspectionTest(PyArgumentListInspection.class, "<html>Change signature of", true, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNls
|
||||
protected String getTestDataPath() {
|
||||
|
||||
Reference in New Issue
Block a user