mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
[java-refactoring] CodeBlockSurrounder: allow if-splitting when extracting from && chain when else-branch is mutually exclusive
Fixes IDEA-309095 Improve the Safety of "Introduce Variable" Refactorings concening ClassCasts GitOrigin-RevId: a9c401378523aaf0142cde161e477a3675de3d5f
This commit is contained in:
committed by
intellij-monorepo-bot
parent
669d57601e
commit
6253884c82
@@ -10,15 +10,18 @@ import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
|
||||
import com.intellij.codeInspection.dataFlow.interpreter.RunnerResult;
|
||||
import com.intellij.codeInspection.dataFlow.interpreter.StandardDataFlowInterpreter;
|
||||
import com.intellij.codeInspection.dataFlow.java.ControlFlowAnalyzer;
|
||||
import com.intellij.codeInspection.dataFlow.java.JavaDfaListener;
|
||||
import com.intellij.codeInspection.dataFlow.java.inst.MethodCallInstruction;
|
||||
import com.intellij.codeInspection.dataFlow.jvm.descriptors.PlainDescriptor;
|
||||
import com.intellij.codeInspection.dataFlow.lang.DfaListener;
|
||||
import com.intellij.codeInspection.dataFlow.lang.ir.*;
|
||||
import com.intellij.codeInspection.dataFlow.memory.DfaMemoryState;
|
||||
import com.intellij.codeInspection.dataFlow.memory.DfaMemoryStateImpl;
|
||||
import com.intellij.codeInspection.dataFlow.types.DfPrimitiveType;
|
||||
import com.intellij.codeInspection.dataFlow.types.DfReferenceType;
|
||||
import com.intellij.codeInspection.dataFlow.types.DfType;
|
||||
import com.intellij.codeInspection.dataFlow.types.DfTypes;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
|
||||
import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
|
||||
import com.intellij.codeInspection.dataFlow.value.RelationType;
|
||||
@@ -792,4 +795,34 @@ public final class DfaPsiUtil {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param cond1 first condition
|
||||
* @param cond2 second condition
|
||||
* @return true if conditions cannot be true at the same time.
|
||||
*/
|
||||
public static boolean mutuallyExclusive(@NotNull PsiExpression cond1, @NotNull PsiExpression cond2) {
|
||||
Project project = cond1.getProject();
|
||||
PsiPolyadicExpression expr =
|
||||
(PsiPolyadicExpression)JavaPsiFacade.getElementFactory(project).createExpressionFromText("a && b", cond1);
|
||||
PsiExpression[] operands = expr.getOperands();
|
||||
operands[0].replace(cond1);
|
||||
operands[1].replace(cond2);
|
||||
DfaValueFactory factory = new DfaValueFactory(project);
|
||||
ControlFlow flow = ControlFlowAnalyzer.buildFlow(expr, factory, true);
|
||||
if (flow == null) return false;
|
||||
var listener = new JavaDfaListener() {
|
||||
final Set<DfType> results = new HashSet<>();
|
||||
|
||||
@Override
|
||||
public void beforeExpressionPush(@NotNull DfaValue value, @NotNull PsiExpression expression, @NotNull DfaMemoryState state) {
|
||||
if (expression == expr) {
|
||||
results.add(value.getDfType());
|
||||
}
|
||||
}
|
||||
};
|
||||
StandardDataFlowInterpreter interpreter = new StandardDataFlowInterpreter(flow, listener);
|
||||
if (interpreter.interpret(new DfaMemoryStateImpl(factory)) != RunnerResult.OK) return false;
|
||||
return DfTypes.FALSE.equals(ContainerUtil.getOnlyItem(listener.results));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user