IDEA-70913 smart step into should not propose methods from both branches in conditional expressions - support if statement

This commit is contained in:
Egor.Ushakov
2016-08-31 12:44:59 +03:00
parent 877358aea3
commit 950322165f
2 changed files with 32 additions and 15 deletions
@@ -201,28 +201,42 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler {
}
}
@Override
public void visitIfStatement(PsiIfStatement statement) {
visitConditional(statement.getCondition(), statement.getThenBranch(), statement.getElseBranch());
}
@Override
public void visitConditionalExpression(PsiConditionalExpression expression) {
PsiExpression condition = expression.getCondition();
condition.accept(this);
ThreeState conditionRes = ThreeState.UNSURE;
if (!DebuggerUtils.hasSideEffects(condition)) {
visitConditional(expression.getCondition(), expression.getThenExpression(), expression.getElseExpression());
}
private void visitConditional(@Nullable PsiElement condition,
@Nullable PsiElement thenBranch,
@Nullable PsiElement elseBranch) {
if (condition != null) {
condition.accept(this);
}
ThreeState conditionRes = evaluateCondition(condition);
if (conditionRes != ThreeState.NO && thenBranch != null) {
thenBranch.accept(this);
}
if (conditionRes != ThreeState.YES && elseBranch != null) {
elseBranch.accept(this);
}
}
private ThreeState evaluateCondition(@Nullable PsiElement condition) {
if (condition != null && !DebuggerUtils.hasSideEffects(condition)) {
try {
ExpressionEvaluator evaluator = EvaluatorBuilderImpl.getInstance().build(condition, position);
conditionRes = ThreeState.fromBoolean(DebuggerUtilsEx.evaluateBoolean(evaluator, debuggerContext.createEvaluationContext()));
return ThreeState.fromBoolean(DebuggerUtilsEx.evaluateBoolean(evaluator, debuggerContext.createEvaluationContext()));
}
catch (EvaluateException e) {
LOG.info(e);
}
}
PsiExpression thenExpression = expression.getThenExpression();
if (conditionRes != ThreeState.NO && thenExpression != null) {
thenExpression.accept(this);
}
PsiExpression elseExpression = expression.getElseExpression();
if (conditionRes != ThreeState.YES && elseExpression != null) {
elseExpression.accept(this);
}
return ThreeState.UNSURE;
}
@Override
@@ -423,11 +423,14 @@ public abstract class DebuggerUtils {
}
}
public static boolean hasSideEffects(PsiElement element) {
public static boolean hasSideEffects(@Nullable PsiElement element) {
return hasSideEffectsOrReferencesMissingVars(element, null);
}
public static boolean hasSideEffectsOrReferencesMissingVars(PsiElement element, @Nullable final Set<String> visibleLocalVariables) {
public static boolean hasSideEffectsOrReferencesMissingVars(@Nullable PsiElement element, @Nullable final Set<String> visibleLocalVariables) {
if (element == null) {
return false;
}
final Ref<Boolean> rv = new Ref<>(Boolean.FALSE);
element.accept(new JavaRecursiveElementWalkingVisitor() {
@Override