mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-20 13:31:28 +07:00
[java-inspections] Do not suggest a fix which breaks the compilation (removing used pattern var)
Fixes IDEA-360403 Quick-fix for always-true pattern breaks the code GitOrigin-RevId: eb71b14424e628c6b9ea9ca115bc904447e9e7f6
This commit is contained in:
committed by
intellij-monorepo-bot
parent
039cec877f
commit
9e1742e86a
@@ -36,6 +36,7 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.siyeh.ig.psiutils.*;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -47,22 +48,47 @@ import static com.intellij.psi.JavaTokenType.WHEN_KEYWORD;
|
||||
public class SimplifyBooleanExpressionFix extends PsiUpdateModCommandAction<PsiExpression> {
|
||||
private static final Logger LOG = Logger.getInstance(SimplifyBooleanExpressionFix.class);
|
||||
|
||||
enum SideEffectStatus {
|
||||
NO_SIDE_EFFECTS,
|
||||
CAN_BE_EXTRACTED,
|
||||
MAY_CHANGE_SEMANTICS,
|
||||
BREAKS_COMPILATION
|
||||
}
|
||||
|
||||
private final boolean mySubExpressionValue;
|
||||
private final @NotNull SideEffectStatus mySideEffectStatus;
|
||||
|
||||
public SimplifyBooleanExpressionFix(@NotNull PsiExpression subExpression, boolean subExpressionValue) {
|
||||
super(subExpression);
|
||||
mySubExpressionValue = subExpressionValue;
|
||||
mySideEffectStatus = computeStatus(subExpression);
|
||||
}
|
||||
|
||||
private @IntentionName @NotNull String getText(@NotNull PsiExpression subExpression) {
|
||||
String suffix = "";
|
||||
if (SideEffectChecker.mayHaveSideEffects(subExpression, e -> shouldIgnore(e, subExpression))) {
|
||||
suffix = canExtractSideEffect(subExpression) ? QuickFixBundle.message("simplify.boolean.expression.extracting.side.effects")
|
||||
: JavaBundle.message("quickfix.text.suffix.may.change.semantics");
|
||||
}
|
||||
String suffix = switch (mySideEffectStatus) {
|
||||
case NO_SIDE_EFFECTS, BREAKS_COMPILATION -> "";
|
||||
case CAN_BE_EXTRACTED -> QuickFixBundle.message("simplify.boolean.expression.extracting.side.effects");
|
||||
case MAY_CHANGE_SEMANTICS -> JavaBundle.message("quickfix.text.suffix.may.change.semantics");
|
||||
};
|
||||
return getIntentionText(subExpression, mySubExpressionValue) + suffix;
|
||||
}
|
||||
|
||||
private SideEffectStatus computeStatus(@NotNull PsiExpression expression) {
|
||||
return StreamEx.of(SideEffectChecker.extractSideEffectExpressions(expression))
|
||||
.map(sideEffectExpression -> {
|
||||
if (sideEffectExpression instanceof PsiInstanceOfExpression instanceOf) {
|
||||
return shouldIgnore(instanceOf, expression) ? SideEffectStatus.NO_SIDE_EFFECTS :
|
||||
canExtractSideEffect(sideEffectExpression) ? SideEffectStatus.CAN_BE_EXTRACTED :
|
||||
SideEffectStatus.BREAKS_COMPILATION;
|
||||
}
|
||||
else {
|
||||
return canExtractSideEffect(sideEffectExpression) ? SideEffectStatus.CAN_BE_EXTRACTED : SideEffectStatus.MAY_CHANGE_SEMANTICS;
|
||||
}
|
||||
})
|
||||
.max(Comparator.naturalOrder())
|
||||
.orElse(SideEffectStatus.NO_SIDE_EFFECTS);
|
||||
}
|
||||
|
||||
private boolean shouldIgnore(PsiElement e, PsiExpression subExpression) {
|
||||
return e instanceof PsiInstanceOfExpression &&
|
||||
!ContainerUtil.exists(JavaPsiPatternUtil.getExposedPatternVariables(((PsiInstanceOfExpression)e)),
|
||||
@@ -119,6 +145,7 @@ public class SimplifyBooleanExpressionFix extends PsiUpdateModCommandAction<PsiE
|
||||
|
||||
public boolean isAvailable(@NotNull PsiExpression expression) {
|
||||
if (PsiUtil.isAccessedForWriting(expression)) return false;
|
||||
if (mySideEffectStatus == SideEffectStatus.BREAKS_COMPILATION) return false;
|
||||
PsiElement element = PsiUtil.skipParenthesizedExprUp(expression);
|
||||
PsiElement parent = element == null ? null : element.getParent();
|
||||
if (parent instanceof PsiDoWhileStatement && containsBreakOrContinue((PsiDoWhileStatement)parent)) return false;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// "Simplify 'u instanceof Upper(Lower l)' to true (may change semantics)" "false"
|
||||
class X {
|
||||
void test() {
|
||||
record Lower(int a, int b) {
|
||||
}
|
||||
record Upper(Lower lower) {
|
||||
}
|
||||
|
||||
Object rec = new Upper(new Lower(0, 0));
|
||||
switch (rec) {
|
||||
case Upper u when u instanceof <caret>Upper(Lower l) && l instanceof Lower(int a, int b) -> {
|
||||
System.out.println(u);
|
||||
System.out.println(l);
|
||||
System.out.println(a);
|
||||
}
|
||||
default -> throw new IllegalStateException("Unexpected value: " + rec);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user