IPP: care for labels and blocks when replacing for loop with while (IDEA-163267)
authorBas Leijdekkers <basleijdekkers@gmail.com>
Tue, 1 Nov 2016 07:59:53 +0000 (08:59 +0100)
committerBas Leijdekkers <basleijdekkers@gmail.com>
Tue, 1 Nov 2016 08:29:01 +0000 (09:29 +0100)
plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntention.java
plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces_after.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop_after.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock_after.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch.java [new file with mode: 0644]
plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch_after.java [new file with mode: 0644]
plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntentionTest.java [new file with mode: 0644]

index ace7955d1ab8449ecfb0031b2923c1f907c0d81a..1f7e34fe3924ba64269ca3a39496f32a098a4604 100644 (file)
@@ -34,11 +34,7 @@ public class ReplaceForLoopWithWhileLoopIntention extends Intention {
     if (forStatement == null) {
       return;
     }
-    final PsiStatement initialization = forStatement.getInitialization();
-    if (initialization != null && !(initialization instanceof PsiEmptyStatement)) {
-      final PsiElement parent = forStatement.getParent();
-      parent.addBefore(initialization, forStatement);
-    }
+    PsiStatement initialization = forStatement.getInitialization();
     final PsiElementFactory factory = JavaPsiFacade.getElementFactory(element.getProject());
     final PsiWhileStatement whileStatement = (PsiWhileStatement)factory.createStatementFromText("while(true) {}", element);
     final PsiExpression forCondition = forStatement.getCondition();
@@ -87,7 +83,26 @@ public class ReplaceForLoopWithWhileLoopIntention extends Intention {
         newBody.addBefore(updateStatement, newBody.getLastChild());
       }
     }
-    forStatement.replace(whileStatement);
+    if (initialization == null || initialization instanceof PsiEmptyStatement) {
+      return;
+    }
+    initialization = (PsiStatement)initialization.copy();
+    PsiElement newElement = forStatement.replace(whileStatement);
+    PsiElement parent = newElement.getParent();
+    while (parent instanceof PsiLabeledStatement) {
+      newElement = parent;
+      parent = newElement.getParent();
+    }
+    if (parent instanceof PsiCodeBlock) {
+      parent.addBefore(initialization, newElement);
+    }
+    else {
+      final PsiStatement newBlockStatement = factory.createStatementFromText("{}", newElement);
+      final PsiElement codeBlock = newBlockStatement.getFirstChild();
+      codeBlock.add(initialization);
+      codeBlock.add(newElement);
+      newElement.replace(newBlockStatement);
+    }
   }
 
   private static class UpdateInserter extends JavaRecursiveElementWalkingVisitor {
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces.java
new file mode 100644 (file)
index 0000000..3a54cf3
--- /dev/null
@@ -0,0 +1,9 @@
+class DoubleLabelNoBraces {
+
+  void m(int i) {
+    while (i > 1)
+      while (i < 10)
+        a: b: c: for<caret> (int j = 0; j < 10; j++);
+
+  }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces_after.java
new file mode 100644 (file)
index 0000000..72b721a
--- /dev/null
@@ -0,0 +1,14 @@
+class DoubleLabelNoBraces {
+
+  void m(int i) {
+    while (i > 1)
+      while (i < 10) {
+          int j = 0;
+          a: b: c:
+          while (j < 10) {
+              j++;
+          }
+      }
+
+  }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop.java
new file mode 100644 (file)
index 0000000..dfe0c01
--- /dev/null
@@ -0,0 +1,9 @@
+class LabeledForLoop {
+
+  public void test() {
+    LABEL:
+    <caret>for (int i = 0; i < 10; i++) {
+      System.out.println("Hello!");
+    }
+  }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop_after.java
new file mode 100644 (file)
index 0000000..fa63e9d
--- /dev/null
@@ -0,0 +1,11 @@
+class LabeledForLoop {
+
+  public void test() {
+      int i = 0;
+      LABEL:
+      while (i < 10) {
+        System.out.println("Hello!");
+          i++;
+      }
+  }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock.java
new file mode 100644 (file)
index 0000000..74453a7
--- /dev/null
@@ -0,0 +1,9 @@
+class NotInBlock {
+
+  public void test(boolean b) {
+    if(b)
+      for<caret>(int i=0; i<10; i++) {
+        System.out.println("Hello!");
+      }
+  }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock_after.java
new file mode 100644 (file)
index 0000000..bb7813f
--- /dev/null
@@ -0,0 +1,12 @@
+class NotInBlock {
+
+  public void test(boolean b) {
+    if(b) {
+        int i=0;
+        while (i<10) {
+          System.out.println("Hello!");
+            i++;
+        }
+    }
+  }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch.java
new file mode 100644 (file)
index 0000000..e1f0ada
--- /dev/null
@@ -0,0 +1,8 @@
+class UpdatingMuch {
+
+  void m() {
+    for<caret> (int i = 0, j = 0, k = 0; i < 10; i++, j++, k++) {
+      System.out.println(i + j + k);
+    }
+  }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch_after.java
new file mode 100644 (file)
index 0000000..415872f
--- /dev/null
@@ -0,0 +1,12 @@
+class UpdatingMuch {
+
+  void m() {
+      int i = 0, j = 0, k = 0;
+      while (i < 10) {
+        System.out.println(i + j + k);
+          i++;
+          j++;
+          k++;
+      }
+  }
+}
\ No newline at end of file
diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntentionTest.java
new file mode 100644 (file)
index 0000000..ed9a294
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.siyeh.ipp.forloop;
+
+import com.siyeh.IntentionPowerPackBundle;
+import com.siyeh.ipp.IPPTestCase;
+
+/**
+ * @author Bas Leijdekkers
+ */
+public class ReplaceForLoopWithWhileLoopIntentionTest extends IPPTestCase {
+
+  public void testLabeledForLoop() { doTest(); }
+  public void testNotInBlock() { doTest(); }
+  public void testDoubleLabelNoBraces() { doTest(); }
+  public void testUpdatingMuch() { doTest(); }
+
+  @Override
+  protected String getIntentionName() {
+    return IntentionPowerPackBundle.message("replace.for.loop.with.while.loop.intention.name");
+  }
+
+  @Override
+  protected String getRelativePath() {
+    return "forloop/while_loop";
+  }
+}
\ No newline at end of file