diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitConditionUtil.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitConditionUtil.java index fb287a6fd602..344a808c8442 100644 --- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitConditionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SplitConditionUtil.java @@ -6,8 +6,10 @@ import com.intellij.psi.*; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; +import com.siyeh.ig.psiutils.BoolUtils; import com.siyeh.ig.psiutils.CommentTracker; import com.siyeh.ig.psiutils.ControlFlowUtils; +import com.siyeh.ig.psiutils.EquivalenceChecker; import com.siyeh.ipp.psiutils.ErrorUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -117,10 +119,21 @@ public class SplitConditionUtil { if (nextIf == null) break; PsiExpression nextCondition = PsiUtil.skipParenthesizedExprDown(nextIf.getCondition()); if (nextCondition == null) break; - if (PsiEquivalenceUtil.areElementsEquivalent(extract, nextCondition) && nextIf.getThenBranch() != null) { + EquivalenceChecker equivalence = EquivalenceChecker.getCanonicalPsiEquivalence(); + if (nextIf.getThenBranch() == null) break; + if (equivalence.expressionsAreEquivalent(extract, nextCondition)) { elseChain.add(tracker.text(nextIf.getThenBranch())); chainFinished = true; } + else if (nextIf.getElseBranch() == null && equivalence.expressionsAreEquivalent( + extract, factory.createExpressionFromText(BoolUtils.getNegatedExpressionText(nextCondition), nextCondition))) { + // skip duplicating else branch in cases like + // if(foo && bar) {1} else if (!foo) {2} => + // if(foo) { if(bar) {1} } else {2} + elseBranch = nextIf.getThenBranch(); + chainFinished = true; + break; + } else { if (!(nextCondition instanceof PsiPolyadicExpression)) break; PsiPolyadicExpression nextPolyadic = (PsiPolyadicExpression)nextCondition; @@ -150,6 +163,9 @@ public class SplitConditionUtil { String thenString; if (elseChain.isEmpty()) { thenString = createIfString(leave, thenBranch, (String)null, tracker); + if (elseBranch != null) { + thenString = "{" + thenString + "}"; + } } else { thenString = "{" + createIfString(leave, thenBranch, String.join("\nelse ", elseChain), tracker) + "\n}"; diff --git a/java/java-tests/testData/codeInsight/splitIfAction/afterCommentBeforeElse2.java b/java/java-tests/testData/codeInsight/splitIfAction/afterCommentBeforeElse2.java index 5082a18572d7..b3955fb31b77 100644 --- a/java/java-tests/testData/codeInsight/splitIfAction/afterCommentBeforeElse2.java +++ b/java/java-tests/testData/codeInsight/splitIfAction/afterCommentBeforeElse2.java @@ -1,5 +1,5 @@ class C { - void foo() { + void foo(boolean a, boolean b, boolean c) { if (a) { if (b) { call(); diff --git a/java/java-tests/testData/codeInsight/splitIfAction/afterIncomplete2.java b/java/java-tests/testData/codeInsight/splitIfAction/afterIncomplete2.java new file mode 100644 index 000000000000..e27ac32d2f2a --- /dev/null +++ b/java/java-tests/testData/codeInsight/splitIfAction/afterIncomplete2.java @@ -0,0 +1,8 @@ +public class SplitCondition { + void test(int x) { + if (x > 0) { + if (x < 10) { + } else if (x > 0 && x > 50) + } else if (x > 0 && x > 50) + } +} diff --git a/java/java-tests/testData/codeInsight/splitIfAction/afterRedundantChainedCondition.java b/java/java-tests/testData/codeInsight/splitIfAction/afterRedundantChainedCondition.java new file mode 100644 index 000000000000..2cbc8032d94a --- /dev/null +++ b/java/java-tests/testData/codeInsight/splitIfAction/afterRedundantChainedCondition.java @@ -0,0 +1,11 @@ +public class SplitCondition { + private static void appendString(String phrase) { + if (phrase != null) { + if (phrase.contains("abc")) { + System.out.println("abc!"); + } + } else { + System.out.println("null"); + } + } +} diff --git a/java/java-tests/testData/codeInsight/splitIfAction/beforeCommentBeforeElse2.java b/java/java-tests/testData/codeInsight/splitIfAction/beforeCommentBeforeElse2.java index 4790a09d436a..872a28565172 100644 --- a/java/java-tests/testData/codeInsight/splitIfAction/beforeCommentBeforeElse2.java +++ b/java/java-tests/testData/codeInsight/splitIfAction/beforeCommentBeforeElse2.java @@ -1,5 +1,5 @@ class C { - void foo() { + void foo(boolean a, boolean b, boolean c) { if (a && b) { call(); } // foo diff --git a/java/java-tests/testData/codeInsight/splitIfAction/beforeIncomplete2.java b/java/java-tests/testData/codeInsight/splitIfAction/beforeIncomplete2.java new file mode 100644 index 000000000000..fcbab6e19f96 --- /dev/null +++ b/java/java-tests/testData/codeInsight/splitIfAction/beforeIncomplete2.java @@ -0,0 +1,6 @@ +public class SplitCondition { + void test(int x) { + if(x > 0 && x < 10) {} + else if(x > 0 && x > 50) + } +} diff --git a/java/java-tests/testData/codeInsight/splitIfAction/beforeRedundantChainedCondition.java b/java/java-tests/testData/codeInsight/splitIfAction/beforeRedundantChainedCondition.java new file mode 100644 index 000000000000..3e4ce5cead87 --- /dev/null +++ b/java/java-tests/testData/codeInsight/splitIfAction/beforeRedundantChainedCondition.java @@ -0,0 +1,10 @@ +public class SplitCondition { + private static void appendString(String phrase) { + if (phrase != null && phrase.contains("abc")) { + System.out.println("abc!"); + } + else if (phrase == null) { + System.out.println("null"); + } + } +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/SplitIfActionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/SplitIfActionTest.java index ebda3bc1345e..85dffae80221 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/SplitIfActionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/intention/SplitIfActionTest.java @@ -76,13 +76,21 @@ public class SplitIfActionTest extends LightJavaCodeInsightTestCase { public void testWithoutSpaces() { doTest(); } - + + public void testRedundantChainedCondition() { + doTest(); + } + public void testIncomplete() { configureByFile("/codeInsight/splitIfAction/before" + getTestName(false) + ".java"); SplitIfAction action = new SplitIfAction(); assertFalse(action.isAvailable(getProject(), getEditor(), getFile())); } + public void testIncomplete2() { + doTest(); + } + private void doTest() { configureByFile("/codeInsight/splitIfAction/before" + getTestName(false)+ ".java"); CommonCodeStyleSettings settings = CodeStyle.getSettings(getFile()).getCommonSettings(JavaLanguage.INSTANCE);