mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IPP: add codeblock when necessary (IDEA-170028)
This commit is contained in:
+17
-10
@@ -21,31 +21,38 @@ import com.intellij.psi.*;
|
||||
* @author Tagir Valeev
|
||||
*/
|
||||
public class BlockUtils {
|
||||
|
||||
/**
|
||||
* Add new statement before given anchor statement creating code block, if necessary
|
||||
* Adds new statements before given anchor statement creating a new code block, if necessary
|
||||
*
|
||||
* @param anchor existing statement
|
||||
* @param newStatement a new statement which should be added before an existing one
|
||||
* @return added physical statement
|
||||
* @param anchor existing statement
|
||||
* @param newStatements the new statements which should be added before the existing one
|
||||
* @return last added physical statement
|
||||
*/
|
||||
public static PsiStatement addBefore(PsiStatement anchor, PsiStatement newStatement) {
|
||||
public static PsiStatement addBefore(PsiStatement anchor, PsiStatement... newStatements) {
|
||||
if (newStatements.length == 0) throw new IllegalArgumentException();
|
||||
PsiElement oldStatement = anchor;
|
||||
PsiElement parent = oldStatement.getParent();
|
||||
while (parent instanceof PsiLabeledStatement) {
|
||||
oldStatement = parent;
|
||||
parent = oldStatement.getParent();
|
||||
}
|
||||
final PsiElement result;
|
||||
PsiElement result = null;
|
||||
if (parent instanceof PsiCodeBlock) {
|
||||
result = parent.addBefore(newStatement, oldStatement);
|
||||
for (PsiStatement statement : newStatements) {
|
||||
result = parent.addBefore(statement, oldStatement);
|
||||
}
|
||||
}
|
||||
else {
|
||||
PsiElementFactory factory = JavaPsiFacade.getElementFactory(anchor.getProject());
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(anchor.getProject());
|
||||
final PsiBlockStatement newBlockStatement = (PsiBlockStatement)factory.createStatementFromText("{}", oldStatement);
|
||||
final PsiElement codeBlock = newBlockStatement.getCodeBlock();
|
||||
codeBlock.add(newStatement);
|
||||
for (PsiStatement newStatement : newStatements) {
|
||||
codeBlock.add(newStatement);
|
||||
}
|
||||
codeBlock.add(oldStatement);
|
||||
result = ((PsiBlockStatement)oldStatement.replace(newBlockStatement)).getCodeBlock().getStatements()[0];
|
||||
final PsiStatement[] statements = ((PsiBlockStatement)oldStatement.replace(newBlockStatement)).getCodeBlock().getStatements();
|
||||
result = statements[statements.length - 2];
|
||||
}
|
||||
return (PsiStatement)result;
|
||||
}
|
||||
|
||||
+24
-45
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006-2016 Bas Leijdekkers
|
||||
* Copyright 2006-2017 Bas Leijdekkers
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -16,11 +16,14 @@
|
||||
package com.siyeh.ipp.forloop;
|
||||
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.siyeh.ig.psiutils.BlockUtils;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
import com.siyeh.ipp.base.PsiElementPredicate;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class ReplaceForLoopWithWhileLoopIntention extends Intention {
|
||||
|
||||
@Override
|
||||
@@ -40,7 +43,6 @@ public class ReplaceForLoopWithWhileLoopIntention extends Intention {
|
||||
final PsiWhileStatement whileStatement = (PsiWhileStatement)factory.createStatementFromText("while(true) {}", element);
|
||||
final PsiExpression forCondition = forStatement.getCondition();
|
||||
final PsiExpression whileCondition = whileStatement.getCondition();
|
||||
final PsiStatement body = forStatement.getBody();
|
||||
if (forCondition != null) {
|
||||
assert whileCondition != null;
|
||||
whileCondition.replace(forCondition);
|
||||
@@ -49,17 +51,18 @@ public class ReplaceForLoopWithWhileLoopIntention extends Intention {
|
||||
if (blockStatement == null) {
|
||||
return;
|
||||
}
|
||||
final PsiElement newBody;
|
||||
if (body instanceof PsiBlockStatement) {
|
||||
final PsiBlockStatement newWhileBody = (PsiBlockStatement)blockStatement.replace(body);
|
||||
newBody = newWhileBody.getCodeBlock();
|
||||
final PsiStatement forStatementBody = forStatement.getBody();
|
||||
final PsiElement loopBody;
|
||||
if (forStatementBody instanceof PsiBlockStatement) {
|
||||
final PsiBlockStatement newWhileBody = (PsiBlockStatement)blockStatement.replace(forStatementBody);
|
||||
loopBody = newWhileBody.getCodeBlock();
|
||||
}
|
||||
else {
|
||||
final PsiCodeBlock codeBlock = blockStatement.getCodeBlock();
|
||||
if (body != null && !(body instanceof PsiEmptyStatement)) {
|
||||
codeBlock.addAfter(body, codeBlock.getFirstChild());
|
||||
if (forStatementBody != null && !(forStatementBody instanceof PsiEmptyStatement)) {
|
||||
codeBlock.add(forStatementBody);
|
||||
}
|
||||
newBody = codeBlock;
|
||||
loopBody = codeBlock;
|
||||
}
|
||||
final PsiStatement update = forStatement.getUpdate();
|
||||
if (update != null) {
|
||||
@@ -69,53 +72,29 @@ public class ReplaceForLoopWithWhileLoopIntention extends Intention {
|
||||
final PsiExpressionList expressionList = expressionListStatement.getExpressionList();
|
||||
final PsiExpression[] expressions = expressionList.getExpressions();
|
||||
updateStatements = new PsiStatement[expressions.length];
|
||||
for (int i = 0, expressionsLength = expressions.length; i < expressionsLength; i++) {
|
||||
final PsiExpression expression = expressions[i];
|
||||
final PsiStatement updateStatement = factory.createStatementFromText(expression.getText() + ';', element);
|
||||
updateStatements[i] = updateStatement;
|
||||
for (int i = 0; i < expressions.length; i++) {
|
||||
updateStatements[i] = factory.createStatementFromText(expressions[i].getText() + ';', element);
|
||||
}
|
||||
}
|
||||
else {
|
||||
final PsiStatement updateStatement = factory.createStatementFromText(update.getText() + ';', element);
|
||||
updateStatements = new PsiStatement[]{updateStatement};
|
||||
}
|
||||
newBody.accept(new UpdateInserter(whileStatement, updateStatements));
|
||||
final Collection<PsiContinueStatement> continueStatements = PsiTreeUtil.findChildrenOfType(loopBody, PsiContinueStatement.class);
|
||||
for (PsiContinueStatement continueStatement : continueStatements) {
|
||||
BlockUtils.addBefore(continueStatement, updateStatements);
|
||||
}
|
||||
for (PsiStatement updateStatement : updateStatements) {
|
||||
newBody.addBefore(updateStatement, newBody.getLastChild());
|
||||
loopBody.addBefore(updateStatement, loopBody.getLastChild());
|
||||
}
|
||||
}
|
||||
if (initialization == null || initialization instanceof PsiEmptyStatement) {
|
||||
return;
|
||||
forStatement.replace(whileStatement);
|
||||
}
|
||||
initialization = (PsiStatement)initialization.copy();
|
||||
PsiElement newElement = forStatement.replace(whileStatement);
|
||||
BlockUtils.addBefore((PsiStatement)newElement, initialization);
|
||||
}
|
||||
|
||||
private static class UpdateInserter extends JavaRecursiveElementWalkingVisitor {
|
||||
|
||||
private final PsiWhileStatement whileStatement;
|
||||
private final PsiStatement[] updateStatements;
|
||||
|
||||
private UpdateInserter(PsiWhileStatement whileStatement, PsiStatement[] updateStatements) {
|
||||
this.whileStatement = whileStatement;
|
||||
this.updateStatements = updateStatements;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitContinueStatement(PsiContinueStatement statement) {
|
||||
final PsiStatement continuedStatement = statement.findContinuedStatement();
|
||||
if (!whileStatement.equals(continuedStatement)) {
|
||||
return;
|
||||
}
|
||||
final PsiElement parent = statement.getParent();
|
||||
if (parent == null) {
|
||||
return;
|
||||
}
|
||||
for (PsiStatement updateStatement : updateStatements) {
|
||||
parent.addBefore(updateStatement, statement);
|
||||
}
|
||||
super.visitContinueStatement(statement);
|
||||
else {
|
||||
initialization = (PsiStatement)initialization.copy();
|
||||
final PsiStatement newStatement = (PsiStatement)forStatement.replace(whileStatement);
|
||||
BlockUtils.addBefore(newStatement, initialization);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class Continuing {
|
||||
void testFor() {
|
||||
<caret>for (int i=0; i<10; i++) {
|
||||
if(i == 5) continue;
|
||||
System.out.println(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class Continuing {
|
||||
void testFor() {
|
||||
int i=0;
|
||||
while (i<10) {
|
||||
if(i == 5) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
System.out.println(i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
class NoInit{
|
||||
void m(int i) {
|
||||
<caret>for (; i < 100; i++) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class NoInit{
|
||||
void m(int i) {
|
||||
while (i < 100) {
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2016 JetBrains s.r.o.
|
||||
* Copyright 2000-2017 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.
|
||||
@@ -27,6 +27,8 @@ public class ReplaceForLoopWithWhileLoopIntentionTest extends IPPTestCase {
|
||||
public void testNotInBlock() { doTest(); }
|
||||
public void testDoubleLabelNoBraces() { doTest(); }
|
||||
public void testUpdatingMuch() { doTest(); }
|
||||
public void testContinuing() { doTest(); }
|
||||
public void testNoInit() { doTest(); }
|
||||
|
||||
@Override
|
||||
protected String getIntentionName() {
|
||||
|
||||
Reference in New Issue
Block a user