Use isReferenceTo(keywordContainer) instead of name matching (PY-26285)

This commit is contained in:
Semyon Proshev
2017-11-29 21:37:36 +03:00
parent 2650bf2d41
commit 787e678baa
6 changed files with 51 additions and 20 deletions

View File

@@ -180,11 +180,10 @@ public class ConvertVariadicParamIntention extends PyBaseIntentionAction {
@NotNull @NotNull
private static <T> List<T> findKeywordContainerUsages(@NotNull PyFunction function, private static <T> List<T> findKeywordContainerUsages(@NotNull PyFunction function,
@NotNull BiPredicate<PsiElement, String> usagePredicate) { @NotNull BiPredicate<PsiElement, PyParameter> usagePredicate) {
final PyParameter keywordContainer = getKeywordContainer(function.getParameterList()); final PyParameter keywordContainer = getKeywordContainer(function.getParameterList());
final String keywordContainerName = keywordContainer == null ? null : keywordContainer.getName();
if (keywordContainerName != null) { if (keywordContainer != null) {
final List<T> result = new ArrayList<>(); final List<T> result = new ArrayList<>();
final Stack<PsiElement> stack = new Stack<>(); final Stack<PsiElement> stack = new Stack<>();
@@ -194,7 +193,7 @@ public class ConvertVariadicParamIntention extends PyBaseIntentionAction {
while (!stack.isEmpty()) { while (!stack.isEmpty()) {
final PsiElement element = stack.pop(); final PsiElement element = stack.pop();
if (usagePredicate.test(element, keywordContainerName)) { if (usagePredicate.test(element, keywordContainer)) {
//noinspection unchecked //noinspection unchecked
result.add((T)element); result.add((T)element);
} }
@@ -212,25 +211,31 @@ public class ConvertVariadicParamIntention extends PyBaseIntentionAction {
return Collections.emptyList(); return Collections.emptyList();
} }
private static boolean isKeywordContainerSubscription(@Nullable PsiElement element, @NotNull String keywordContainerName) { private static boolean isKeywordContainerSubscription(@Nullable PsiElement element, @NotNull PyParameter keywordContainer) {
return element instanceof PySubscriptionExpression && if (element instanceof PySubscriptionExpression) {
keywordContainerName.equals(((PySubscriptionExpression)element).getOperand().getText()); final PyExpression operand = ((PySubscriptionExpression)element).getOperand();
if (operand instanceof PyReferenceExpression) {
return ((PyReferenceExpression)operand).getReference().isReferenceTo(keywordContainer);
}
} }
private static boolean isKeywordContainerCall(@Nullable PsiElement element, @NotNull String keywordContainerName) { return false;
return Optional
.ofNullable(PyUtil.as(element, PyCallExpression.class))
.map(PyCallExpression::getCallee)
.map(callee -> PyUtil.as(callee, PyQualifiedExpression.class))
.filter(
callee -> {
final PyExpression qualifier = callee.getQualifier();
return qualifier != null &&
qualifier.getText().equals(keywordContainerName) &&
ArrayUtil.contains(callee.getReferencedName(), "get", "pop", PyNames.GETITEM);
} }
)
.isPresent(); private static boolean isKeywordContainerCall(@Nullable PsiElement element, @NotNull PyParameter keywordContainer) {
if (element instanceof PyCallExpression) {
final PyExpression callee = ((PyCallExpression)element).getCallee();
if (callee instanceof PyQualifiedExpression) {
final PyQualifiedExpression qualifiedCallee = (PyQualifiedExpression)callee;
final PyExpression qualifier = qualifiedCallee.getQualifier();
if (qualifier instanceof PyReferenceExpression) {
return ((PyReferenceExpression)qualifier).getReference().isReferenceTo(keywordContainer) &&
ArrayUtil.contains(qualifiedCallee.getReferencedName(), "get", "pop", PyNames.GETITEM);
}
}
}
return false;
} }
private static void insertParameter(@NotNull PyParameterList parameterList, private static void insertParameter(@NotNull PyParameterList parameterList,

View File

@@ -0,0 +1,4 @@
def outer(<caret>**kwargs):
def nested():
print(kwargs['foo'])
return kwargs.get('bar')

View File

@@ -0,0 +1,4 @@
def outer(foo, bar=None, **kwargs):
def nested():
print(foo)
return bar

View File

@@ -0,0 +1,4 @@
def outer(<caret>**kwargs):
def nested(**kwargs):
print(kwargs['foo'])
return kwargs.get('bar')

View File

@@ -0,0 +1,4 @@
def outer(bar=None, **kwargs):
def nested(**kwargs):
print(kwargs['foo'])
return bar

View File

@@ -244,6 +244,16 @@ public class PyIntentionTest extends PyTestCase {
doTest(PyBundle.message("INTN.convert.variadic.param")); doTest(PyBundle.message("INTN.convert.variadic.param"));
} }
// PY-26285
public void testConvertVariadicParamOverriddenInNested() {
doTest(PyBundle.message("INTN.convert.variadic.param"));
}
// PY-26285
public void testConvertVariadicParamNotOverriddenInNested() {
doTest(PyBundle.message("INTN.convert.variadic.param"));
}
public void testConvertTripleQuotedString() { //PY-2697 public void testConvertTripleQuotedString() { //PY-2697
doTest(PyBundle.message("INTN.triple.quoted.string")); doTest(PyBundle.message("INTN.triple.quoted.string"));
} }