From 994b0f84a98c42b90d4dea1ad53bafd29538eabd Mon Sep 17 00:00:00 2001 From: Bas Leijdekkers Date: Tue, 1 Nov 2016 08:59:53 +0100 Subject: [PATCH] IPP: care for labels and blocks when replacing for loop with while (IDEA-163267) --- .../ReplaceForLoopWithWhileLoopIntention.java | 27 ++++++++++--- .../while_loop/DoubleLabelNoBraces.java | 9 +++++ .../while_loop/DoubleLabelNoBraces_after.java | 14 +++++++ .../forloop/while_loop/LabeledForLoop.java | 9 +++++ .../while_loop/LabeledForLoop_after.java | 11 +++++ .../ipp/forloop/while_loop/NotInBlock.java | 9 +++++ .../forloop/while_loop/NotInBlock_after.java | 12 ++++++ .../ipp/forloop/while_loop/UpdatingMuch.java | 8 ++++ .../while_loop/UpdatingMuch_after.java | 12 ++++++ ...laceForLoopWithWhileLoopIntentionTest.java | 40 +++++++++++++++++++ 10 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces_after.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop_after.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock_after.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch_after.java create mode 100644 plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntentionTest.java diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntention.java index ace7955d1ab8..1f7e34fe3924 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntention.java @@ -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 index 000000000000..3a54cf3937e7 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces.java @@ -0,0 +1,9 @@ +class DoubleLabelNoBraces { + + void m(int i) { + while (i > 1) + while (i < 10) + a: b: c: for (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 index 000000000000..72b721a00bed --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/DoubleLabelNoBraces_after.java @@ -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 index 000000000000..dfe0c0162b29 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop.java @@ -0,0 +1,9 @@ +class LabeledForLoop { + + public void test() { + LABEL: + 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 index 000000000000..fa63e9d2b262 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/LabeledForLoop_after.java @@ -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 index 000000000000..74453a71d912 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock.java @@ -0,0 +1,9 @@ +class NotInBlock { + + public void test(boolean b) { + if(b) + 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/NotInBlock_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock_after.java new file mode 100644 index 000000000000..bb7813f8c063 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/NotInBlock_after.java @@ -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 index 000000000000..e1f0ada4084a --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch.java @@ -0,0 +1,8 @@ +class UpdatingMuch { + + void m() { + for (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 index 000000000000..415872fa37d4 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/forloop/while_loop/UpdatingMuch_after.java @@ -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 index 000000000000..ed9a294443c0 --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/forloop/ReplaceForLoopWithWhileLoopIntentionTest.java @@ -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