Avoid suggesting counting loop if loop variable must be effectively final

GitOrigin-RevId: eb15165f5034fa75de9c9af97fb2707a233e9fe5
This commit is contained in:
Tagir Valeev
2020-06-17 07:41:39 +03:00
committed by intellij-monorepo-bot
parent 1df2a19a7a
commit f988f89bbd
4 changed files with 41 additions and 3 deletions
@@ -138,6 +138,11 @@ public class CollapseIntoLoopAction implements IntentionAction {
if (start == null || step == null) return null;
// Prefer for(int x : new int[] {12, 17}) over for(int x = 12; x <= 17; x+= 5)
if (myLoopElements.size() == 2 && step != 1L && step != -1L) return null;
PsiElement parent = myStatements.get(0).getParent();
boolean mustBeEffectivelyFinal = myExpressionsToReplace.stream()
.map(ref -> PsiTreeUtil.getParentOfType(ref, PsiClass.class, PsiLambdaExpression.class))
.anyMatch(ctx -> ctx != null && PsiTreeUtil.isAncestor(parent, ctx, false));
if (mustBeEffectivelyFinal) return null;
String suffix = PsiType.LONG.equals(myType) ? "L" : "";
String initial = myType.getCanonicalText() + " " + varName + "=" + start + suffix;
String condition =
@@ -0,0 +1,14 @@
// "Collapse into loop" "true"
class X {
void test() {
for (int i : new int[]{1, 2, 3, 4}) {
consume(() -> i);
}
}
void consume(IntSupplier x) {}
interface IntSupplier {
int supply();
}
}
@@ -0,0 +1,15 @@
// "Collapse into loop" "true"
class X {
void test() {
<caret>consume(() -> 1);
consume(() -> 2);
consume(() -> 3);
consume(() -> 4);
}
void consume(IntSupplier x) {}
interface IntSupplier {
int supply();
}
}
@@ -626,13 +626,17 @@ public class EquivalenceChecker {
}
final PsiElement body1 = unwrapLambdaBody(expression1.getBody());
final PsiElement body2 = unwrapLambdaBody(expression2.getBody());
Match match;
if (body1 instanceof PsiCodeBlock && body2 instanceof PsiCodeBlock) {
return codeBlocksMatch((PsiCodeBlock)body1, (PsiCodeBlock)body2);
match = codeBlocksMatch((PsiCodeBlock)body1, (PsiCodeBlock)body2);
}
else if (body1 instanceof PsiExpression && body2 instanceof PsiExpression) {
return expressionsMatch((PsiExpression)body1, (PsiExpression)body2);
match = expressionsMatch((PsiExpression)body1, (PsiExpression)body2);
}
return EXACT_MISMATCH;
else {
match = EXACT_MISMATCH;
}
return match == EXACT_MISMATCH ? new Match(body1, body2) : match;
}
private static PsiElement unwrapLambdaBody(PsiElement element) {