From 87d3106a1ac83862825706c021572a9d184f21f9 Mon Sep 17 00:00:00 2001 From: "Anna.Kozlova" Date: Fri, 12 Jan 2018 15:24:09 +0100 Subject: [PATCH] invert boolean: invert assignment if used as expression (IDEA-152284) --- .../JavaInvertBooleanDelegate.java | 18 ++++++---- .../refactoring/invertBoolean/assignment.java | 10 ++++++ .../invertBoolean/assignmentLocal.java | 6 ++++ .../invertBoolean/assignmentLocal_after.java | 6 ++++ .../invertBoolean/assignment_after.java | 10 ++++++ .../invertBoolean/InvertBooleanDelegate.java | 35 +++++++++++++++++-- .../PyInvertBooleanDelegate.java | 9 ++--- 7 files changed, 78 insertions(+), 16 deletions(-) create mode 100644 java/java-tests/testData/refactoring/invertBoolean/assignment.java create mode 100644 java/java-tests/testData/refactoring/invertBoolean/assignmentLocal.java create mode 100644 java/java-tests/testData/refactoring/invertBoolean/assignmentLocal_after.java create mode 100644 java/java-tests/testData/refactoring/invertBoolean/assignment_after.java diff --git a/java/java-impl/src/com/intellij/refactoring/invertBoolean/JavaInvertBooleanDelegate.java b/java/java-impl/src/com/intellij/refactoring/invertBoolean/JavaInvertBooleanDelegate.java index d0e92a00e54b..1aa0a0d72946 100644 --- a/java/java-impl/src/com/intellij/refactoring/invertBoolean/JavaInvertBooleanDelegate.java +++ b/java/java-impl/src/com/intellij/refactoring/invertBoolean/JavaInvertBooleanDelegate.java @@ -110,16 +110,22 @@ public class JavaInvertBooleanDelegate extends InvertBooleanDelegate { for (PsiReference ref : refs) { final PsiElement element = ref.getElement(); - PsiElement refElement = getElementToInvert(namedElement, element); - if (refElement == null) { - refElement = getForeignElementToInvert(namedElement, element, JavaLanguage.INSTANCE); - } - if (refElement != null) { - elementsToInvert.add(refElement); + if (!collectElementsToInvert(namedElement, element, elementsToInvert)) { + collectForeignElementsToInvert(namedElement, element, JavaLanguage.INSTANCE, elementsToInvert); } } } + @Override + public boolean collectElementsToInvert(PsiElement namedElement, PsiElement expression, Collection elementsToInvert) { + boolean toInvert = super.collectElementsToInvert(namedElement, expression, elementsToInvert); + PsiElement parent = expression.getParent(); + if (parent instanceof PsiAssignmentExpression && !(parent.getParent() instanceof PsiExpressionStatement)) { + elementsToInvert.add(parent); + } + return toInvert; + } + public PsiElement getElementToInvert(PsiElement namedElement, PsiElement element) { if (element instanceof PsiReferenceExpression) { final PsiReferenceExpression refExpr = (PsiReferenceExpression)element; diff --git a/java/java-tests/testData/refactoring/invertBoolean/assignment.java b/java/java-tests/testData/refactoring/invertBoolean/assignment.java new file mode 100644 index 000000000000..bcd19d76c1dd --- /dev/null +++ b/java/java-tests/testData/refactoring/invertBoolean/assignment.java @@ -0,0 +1,10 @@ +class C { + boolean foo() { + return false; + } + + void bar() { + boolean a, b; + a = b = foo(); + } +} diff --git a/java/java-tests/testData/refactoring/invertBoolean/assignmentLocal.java b/java/java-tests/testData/refactoring/invertBoolean/assignmentLocal.java new file mode 100644 index 000000000000..e4d73683889a --- /dev/null +++ b/java/java-tests/testData/refactoring/invertBoolean/assignmentLocal.java @@ -0,0 +1,6 @@ +class C { + void bar() { + boolean a, b; + a = b = false; + } +} diff --git a/java/java-tests/testData/refactoring/invertBoolean/assignmentLocal_after.java b/java/java-tests/testData/refactoring/invertBoolean/assignmentLocal_after.java new file mode 100644 index 000000000000..49e241724d34 --- /dev/null +++ b/java/java-tests/testData/refactoring/invertBoolean/assignmentLocal_after.java @@ -0,0 +1,6 @@ +class C { + void bar() { + boolean a, bInverted; + a = !(bInverted = true); + } +} diff --git a/java/java-tests/testData/refactoring/invertBoolean/assignment_after.java b/java/java-tests/testData/refactoring/invertBoolean/assignment_after.java new file mode 100644 index 000000000000..f3ff6e942b69 --- /dev/null +++ b/java/java-tests/testData/refactoring/invertBoolean/assignment_after.java @@ -0,0 +1,10 @@ +class C { + boolean fooInverted() { + return true; + } + + void bar() { + boolean a, b; + a = b = !fooInverted(); + } +} diff --git a/platform/lang-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDelegate.java b/platform/lang-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDelegate.java index 5fdc05ff7175..c8339c56203e 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDelegate.java +++ b/platform/lang-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDelegate.java @@ -74,16 +74,29 @@ public abstract class InvertBooleanDelegate { Collection elementsToInvert); /** - * Invoked from {@link #getForeignElementToInvert(PsiElement, PsiElement, Language)}; + * Invoked from {@link #collectForeignElementsToInvert(PsiElement, PsiElement, Language, Collection)} * should be used to reject usages for elements from foreign language to be refactored * @return null, if reference should not be reverted */ public abstract PsiElement getElementToInvert(PsiElement namedElement, PsiElement expression); /** - * Should be called from {@link #collectRefElements(PsiElement, RenameProcessor, String, Collection)} - * to process found usages in foreign languages + * @return true, if element was found in current language */ + public boolean collectElementsToInvert(PsiElement namedElement, PsiElement expression, Collection elementsToInvert) { + PsiElement elementToInvert = getElementToInvert(namedElement, expression); + if (elementToInvert != null) { + elementsToInvert.add(elementToInvert); + return true; + } + return false; + } + + /** + * Use {@link #collectForeignElementsToInvert(PsiElement, PsiElement, Language, Collection)} instead + * To be removed in 2018.3 + */ + @Deprecated protected static PsiElement getForeignElementToInvert(PsiElement namedElement, PsiElement expression, Language language) { @@ -96,6 +109,22 @@ public abstract class InvertBooleanDelegate { return null; } + /** + * Should be called from {@link #collectRefElements(PsiElement, RenameProcessor, String, Collection)} + * to process found usages in foreign languages + */ + protected static void collectForeignElementsToInvert(PsiElement namedElement, + PsiElement expression, + Language language, + Collection elementsToInvert) { + if (!expression.getLanguage().is(language)){ + final InvertBooleanDelegate delegate = findInvertBooleanDelegate(expression); + if (delegate != null) { + delegate.collectElementsToInvert(namedElement, expression, elementsToInvert); + } + } + } + /** * Replace expression with created negation * @param expression to be inverted, found in {@link #collectRefElements(PsiElement, RenameProcessor, String, Collection)} diff --git a/python/src/com/jetbrains/python/refactoring/invertBoolean/PyInvertBooleanDelegate.java b/python/src/com/jetbrains/python/refactoring/invertBoolean/PyInvertBooleanDelegate.java index 783f9345cdc3..a47d14bf11f7 100644 --- a/python/src/com/jetbrains/python/refactoring/invertBoolean/PyInvertBooleanDelegate.java +++ b/python/src/com/jetbrains/python/refactoring/invertBoolean/PyInvertBooleanDelegate.java @@ -27,7 +27,6 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.refactoring.invertBoolean.InvertBooleanDelegate; import com.intellij.refactoring.rename.RenameProcessor; -import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.PyNames; import com.jetbrains.python.PyTokenTypes; import com.jetbrains.python.PythonLanguage; @@ -94,12 +93,8 @@ public class PyInvertBooleanDelegate extends InvertBooleanDelegate { for (PsiReference ref : refs) { final PsiElement refElement = ref.getElement(); - final PsiElement elementToInvert = getElementToInvert(psiElement, refElement); - if (elementToInvert != null) { - elementsToInvert.add(elementToInvert); - } - else { - ContainerUtil.addIfNotNull(elementsToInvert, getForeignElementToInvert(psiElement, refElement, PythonLanguage.getInstance())); + if (!collectElementsToInvert(psiElement, refElement, elementsToInvert)) { + collectForeignElementsToInvert(psiElement, refElement, PythonLanguage.getInstance(), elementsToInvert); } } }