mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-intentions] IDEA-331850 Support 'Unroll Loop' intention when there are declarations in a loop
GitOrigin-RevId: 5fa9904997f3eade008dae8278ffc44dd0e9172d
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ce7ea33a0a
commit
bdc4c6c8c1
@@ -62,7 +62,6 @@ public class UnrollLoopAction extends PsiUpdateModCommandAction<PsiLoopStatement
|
||||
}
|
||||
PsiStatement[] statements = ControlFlowUtils.unwrapBlock(body);
|
||||
if (statements.length == 0) return null;
|
||||
if (ContainerUtil.exists(statements, PsiDeclarationStatement.class::isInstance)) return null;
|
||||
if (VariableAccessUtils.variableIsAssigned(iterationParameter, body)) return null;
|
||||
for (PsiStatement statement : statements) {
|
||||
if (isLoopBreak(statement)) continue;
|
||||
@@ -193,7 +192,7 @@ public class UnrollLoopAction extends PsiUpdateModCommandAction<PsiLoopStatement
|
||||
|
||||
@Override
|
||||
protected void invoke(@NotNull ActionContext context, @NotNull PsiLoopStatement loop, @NotNull ModPsiUpdater updater) {
|
||||
if (!(loop.getParent() instanceof PsiCodeBlock)) return;
|
||||
if (!(loop.getParent() instanceof PsiCodeBlock parentBlock)) return;
|
||||
List<PsiExpression> expressions = extractExpressions(loop);
|
||||
if (expressions.isEmpty()) return;
|
||||
Project project = context.project();
|
||||
@@ -215,14 +214,19 @@ public class UnrollLoopAction extends PsiUpdateModCommandAction<PsiLoopStatement
|
||||
PsiElement[] children;
|
||||
if (body instanceof PsiBlockStatement) {
|
||||
PsiCodeBlock block = ((PsiBlockStatement)Objects.requireNonNull(loop.getBody())).getCodeBlock();
|
||||
PsiElement firstBodyElement = block.getFirstBodyElement();
|
||||
PsiElement lastBodyElement = block.getLastBodyElement();
|
||||
if (firstBodyElement != null && lastBodyElement != null) {
|
||||
ct.markRangeUnchanged(firstBodyElement, lastBodyElement);
|
||||
if (canUnwrapBlock(block, parentBlock, expressions)) {
|
||||
PsiElement firstBodyElement = block.getFirstBodyElement();
|
||||
PsiElement lastBodyElement = block.getLastBodyElement();
|
||||
if (firstBodyElement != null && lastBodyElement != null) {
|
||||
ct.markRangeUnchanged(firstBodyElement, lastBodyElement);
|
||||
}
|
||||
children = ((PsiBlockStatement)body).getCodeBlock().getChildren();
|
||||
// Skip {braces}
|
||||
children = Arrays.copyOfRange(children, 1, children.length-1);
|
||||
} else {
|
||||
ct.markUnchanged(loop.getBody());
|
||||
children = new PsiElement[]{body};
|
||||
}
|
||||
children = ((PsiBlockStatement)body).getCodeBlock().getChildren();
|
||||
// Skip {braces}
|
||||
children = Arrays.copyOfRange(children, 1, children.length-1);
|
||||
} else {
|
||||
ct.markUnchanged(loop.getBody());
|
||||
children = new PsiElement[]{body};
|
||||
@@ -247,6 +251,25 @@ public class UnrollLoopAction extends PsiUpdateModCommandAction<PsiLoopStatement
|
||||
ct.deleteAndRestoreComments(loop);
|
||||
}
|
||||
|
||||
private static boolean canUnwrapBlock(@NotNull PsiCodeBlock block, PsiCodeBlock parentBlock, List<PsiExpression> expressions) {
|
||||
for (PsiStatement statement : block.getStatements()) {
|
||||
if (statement instanceof PsiDeclarationStatement declaration) {
|
||||
if (expressions.size() > 1) return false;
|
||||
for (PsiElement element : declaration.getDeclaredElements()) {
|
||||
if (element instanceof PsiVariable variable) {
|
||||
String name = variable.getName();
|
||||
if (name != null) {
|
||||
if (PsiResolveHelper.getInstance(block.getProject()).resolveReferencedVariable(name, parentBlock) != null) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isLoopBreak(PsiStatement statement) {
|
||||
if (!(statement instanceof PsiIfStatement ifStatement)) return false;
|
||||
if (ifStatement.getElseBranch() != null || ifStatement.getCondition() == null) return false;
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Unroll loop" "true-preview"
|
||||
class X {
|
||||
void test() {
|
||||
{
|
||||
int y = 1 + 1;
|
||||
System.out.println(y);
|
||||
}
|
||||
int y = 2;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Unroll loop" "true-preview"
|
||||
class X {
|
||||
void test() {
|
||||
int y = 1 + 1;
|
||||
System.out.println(y);
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Unroll loop" "true-preview"
|
||||
class X {
|
||||
void test() {
|
||||
{
|
||||
int y = 1 + 1;
|
||||
System.out.println(y);
|
||||
}
|
||||
{
|
||||
int y = 2 + 1;
|
||||
System.out.println(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
// "Unroll loop" "true-preview"
|
||||
class X {
|
||||
void test() {
|
||||
<caret>for (int x : new int[]{1}) {
|
||||
int y = x + 1;
|
||||
System.out.println(y);
|
||||
}
|
||||
int y = 2;
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Unroll loop" "true-preview"
|
||||
class X {
|
||||
void test() {
|
||||
<caret>for (int x : new int[]{1}) {
|
||||
int y = x + 1;
|
||||
System.out.println(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
// "Unroll loop" "true-preview"
|
||||
class X {
|
||||
void test() {
|
||||
<caret>for (int x : new int[]{1, 2}) {
|
||||
int y = x + 1;
|
||||
System.out.println(y);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user