IPP: care for labels and blocks when replacing for loop with while (IDEA-163267)

This commit is contained in:
Bas Leijdekkers
2016-11-01 09:29:01 +01:00
parent c17ad02427
commit 994b0f84a9
10 changed files with 145 additions and 6 deletions
@@ -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 {
@@ -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++);
}
}
@@ -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++;
}
}
}
}
@@ -0,0 +1,9 @@
class LabeledForLoop {
public void test() {
LABEL:
<caret>for (int i = 0; i < 10; i++) {
System.out.println("Hello!");
}
}
}
@@ -0,0 +1,11 @@
class LabeledForLoop {
public void test() {
int i = 0;
LABEL:
while (i < 10) {
System.out.println("Hello!");
i++;
}
}
}
@@ -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!");
}
}
}
@@ -0,0 +1,12 @@
class NotInBlock {
public void test(boolean b) {
if(b) {
int i=0;
while (i<10) {
System.out.println("Hello!");
i++;
}
}
}
}
@@ -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);
}
}
}
@@ -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++;
}
}
}
@@ -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";
}
}