IDEA-75755 Do-while statement not supported in evaluate expression for Java.

This commit is contained in:
Egor.Ushakov
2014-11-21 17:42:53 +03:00
parent e0d50fd80f
commit 3307cb273b
7 changed files with 165 additions and 92 deletions
@@ -0,0 +1,57 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.sun.jdi.BooleanValue;
import org.jetbrains.annotations.NotNull;
/**
* @author egor
*/
public class DoWhileStatementEvaluator extends LoopEvaluator {
private final Evaluator myConditionEvaluator;
public DoWhileStatementEvaluator(@NotNull Evaluator conditionEvaluator, Evaluator bodyEvaluator, String labelName) {
super(labelName, bodyEvaluator);
myConditionEvaluator = new DisableGC(conditionEvaluator);
}
public Modifier getModifier() {
return myConditionEvaluator.getModifier();
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf();
while (true) {
if (body(context)) break;
value = myConditionEvaluator.evaluate(context);
if (!(value instanceof BooleanValue)) {
throw EvaluateExceptionUtil.BOOLEAN_EXPECTED;
}
else {
if (!((BooleanValue)value).booleanValue()) {
break;
}
}
}
return value;
}
}
@@ -213,20 +213,37 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
}
@Override
public void visitWhileStatement(PsiWhileStatement statement) {
PsiStatement body = statement.getBody();
if(body == null) return;
body.accept(this);
Evaluator bodyEvaluator = myResult;
public void visitLabeledStatement(PsiLabeledStatement labeledStatement) {
PsiStatement statement = labeledStatement.getStatement();
if (statement != null) {
statement.accept(this);
}
}
PsiExpression condition = statement.getCondition();
if(condition == null) return;
condition.accept(this);
private static String getLabel(PsiElement element) {
String label = null;
if(statement.getParent() instanceof PsiLabeledStatement) {
label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText();
if(element.getParent() instanceof PsiLabeledStatement) {
label = ((PsiLabeledStatement)element.getParent()).getName();
}
return label;
}
@Override
public void visitDoWhileStatement(PsiDoWhileStatement statement) {
Evaluator bodyEvaluator = accept(statement.getBody());
Evaluator conditionEvaluator = accept(statement.getCondition());
if (conditionEvaluator != null) {
myResult = new DoWhileStatementEvaluator(conditionEvaluator, bodyEvaluator, getLabel(statement));
}
}
@Override
public void visitWhileStatement(PsiWhileStatement statement) {
Evaluator bodyEvaluator = accept(statement.getBody());
Evaluator conditionEvaluator = accept(statement.getCondition());
if (conditionEvaluator != null) {
myResult = new WhileStatementEvaluator(conditionEvaluator, bodyEvaluator, getLabel(statement));
}
myResult = new WhileStatementEvaluator(myResult, bodyEvaluator, label);
}
@Override
@@ -235,13 +252,9 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
Evaluator conditionEvaluator = accept(statement.getCondition());
Evaluator updateEvaluator = accept(statement.getUpdate());
Evaluator bodyEvaluator = accept(statement.getBody());
if (bodyEvaluator == null) return;
String label = null;
if(statement.getParent() instanceof PsiLabeledStatement) {
label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText();
if (bodyEvaluator != null) {
myResult = new ForStatementEvaluator(initializerEvaluator, conditionEvaluator, updateEvaluator, bodyEvaluator, getLabel(statement));
}
myResult = new ForStatementEvaluator(initializerEvaluator, conditionEvaluator, updateEvaluator, bodyEvaluator, label);
}
@Override
@@ -253,13 +266,9 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder {
Evaluator iteratedValueEvaluator = accept(statement.getIteratedValue());
Evaluator bodyEvaluator = accept(statement.getBody());
if (bodyEvaluator == null) return;
String label = null;
if(statement.getParent() instanceof PsiLabeledStatement) {
label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText();
if (bodyEvaluator != null) {
myResult = new ForeachStatementEvaluator(iterationParameterEvaluator, iteratedValueEvaluator, bodyEvaluator, getLabel(statement));
}
myResult = new ForeachStatementEvaluator(iterationParameterEvaluator, iteratedValueEvaluator, bodyEvaluator, label);
}
catch (EvaluateException e) {
throw new EvaluateRuntimeException(e);
@@ -25,7 +25,6 @@ public class ForStatementEvaluator extends ForStatementEvaluatorBase {
private final Evaluator myInitializationEvaluator;
private final Evaluator myConditionEvaluator;
private final Evaluator myUpdateEvaluator;
private final Evaluator myBodyEvaluator;
private Modifier myModifier;
@@ -34,24 +33,16 @@ public class ForStatementEvaluator extends ForStatementEvaluatorBase {
Evaluator updateEvaluator,
Evaluator bodyEvaluator,
String labelName) {
super(labelName);
super(labelName, bodyEvaluator);
myInitializationEvaluator = initializationEvaluator != null ? new DisableGC(initializationEvaluator) : null;
myConditionEvaluator = conditionEvaluator != null ? new DisableGC(conditionEvaluator) : null;
myUpdateEvaluator = updateEvaluator != null ? new DisableGC(updateEvaluator) : null;
myBodyEvaluator = bodyEvaluator != null ? new DisableGC(bodyEvaluator) : null;
}
public Modifier getModifier() {
return myModifier;
}
@Override
protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException {
if (myBodyEvaluator != null) {
myBodyEvaluator.evaluate(context);
}
}
@Override
protected Object evaluateInitialization(EvaluationContextImpl context, Object value) throws EvaluateException {
if (myInitializationEvaluator != null) {
@@ -18,17 +18,14 @@ package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.openapi.util.Comparing;
import com.sun.jdi.BooleanValue;
/**
* @author egor
*/
public abstract class ForStatementEvaluatorBase implements Evaluator {
private final String myLabelName;
public ForStatementEvaluatorBase(String labelName) {
myLabelName = labelName;
public abstract class ForStatementEvaluatorBase extends LoopEvaluator {
public ForStatementEvaluatorBase(String labelName, Evaluator bodyEvaluator) {
super(labelName, bodyEvaluator);
}
public Object evaluate(EvaluationContextImpl context) throws EvaluateException {
@@ -49,26 +46,7 @@ public abstract class ForStatementEvaluatorBase implements Evaluator {
}
// body
try {
evaluateBody(context);
}
catch (BreakException e) {
if (Comparing.equal(e.getLabelName(), myLabelName)) {
break;
}
else {
throw e;
}
}
catch (ContinueException e) {
if (Comparing.equal(e.getLabelName(), myLabelName)) {
//continue;
}
else {
throw e;
}
}
if (body(context)) break;
// update
value = evaluateUpdate(context, value);
@@ -85,9 +63,6 @@ public abstract class ForStatementEvaluatorBase implements Evaluator {
return true;
}
protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException {
}
protected Object evaluateUpdate(EvaluationContextImpl context, Object value) throws EvaluateException {
return value;
}
@@ -27,7 +27,6 @@ import com.sun.jdi.Value;
public class ForeachStatementEvaluator extends ForStatementEvaluatorBase {
private final Evaluator myIterationParameterEvaluator;
private final Evaluator myIterableEvaluator;
private final Evaluator myBodyEvaluator;
private Evaluator myConditionEvaluator;
private Evaluator myNextEvaluator;
@@ -41,10 +40,9 @@ public class ForeachStatementEvaluator extends ForStatementEvaluatorBase {
Evaluator iterableEvaluator,
Evaluator bodyEvaluator,
String labelName) {
super(labelName);
super(labelName, bodyEvaluator);
myIterationParameterEvaluator = iterationParameterEvaluator;
myIterableEvaluator = new DisableGC(iterableEvaluator);
myBodyEvaluator = bodyEvaluator != null ? new DisableGC(bodyEvaluator) : null;
}
public Modifier getModifier() {
@@ -102,8 +100,6 @@ public class ForeachStatementEvaluator extends ForStatementEvaluatorBase {
@Override
protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException {
myNextEvaluator.evaluate(context);
if (myBodyEvaluator != null) {
myBodyEvaluator.evaluate(context);
}
super.evaluateBody(context);
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.openapi.util.Comparing;
/**
* @author egor
*/
public abstract class LoopEvaluator implements Evaluator {
private final String myLabelName;
private final Evaluator myBodyEvaluator;
public LoopEvaluator(String labelName, Evaluator bodyEvaluator) {
myLabelName = labelName;
myBodyEvaluator = bodyEvaluator != null ? new DisableGC(bodyEvaluator) : null;
}
protected boolean body(EvaluationContextImpl context) throws EvaluateException {
try {
evaluateBody(context);
}
catch (BreakException e) {
if (Comparing.equal(e.getLabelName(), myLabelName)) {
return true;
}
else {
throw e;
}
}
catch (ContinueException e) {
if (!Comparing.equal(e.getLabelName(), myLabelName)) {
throw e;
}
}
return false;
}
public String getLabelName() {
return myLabelName;
}
protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException {
if (myBodyEvaluator != null) {
myBodyEvaluator.evaluate(context);
}
}
}
@@ -18,21 +18,18 @@ package com.intellij.debugger.engine.evaluation.expression;
import com.intellij.debugger.engine.evaluation.EvaluateException;
import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil;
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
import com.intellij.openapi.util.Comparing;
import com.sun.jdi.BooleanValue;
import org.jetbrains.annotations.NotNull;
/**
* @author lex
*/
public class WhileStatementEvaluator implements Evaluator {
public class WhileStatementEvaluator extends LoopEvaluator {
private final Evaluator myConditionEvaluator;
private final Evaluator myBodyEvaluator;
private final String myLabelName;
public WhileStatementEvaluator(Evaluator conditionEvaluator, Evaluator bodyEvaluator, String labelName) {
public WhileStatementEvaluator(@NotNull Evaluator conditionEvaluator, Evaluator bodyEvaluator, String labelName) {
super(labelName, bodyEvaluator);
myConditionEvaluator = new DisableGC(conditionEvaluator);
myBodyEvaluator = new DisableGC(bodyEvaluator);
myLabelName = labelName;
}
public Modifier getModifier() {
@@ -51,25 +48,10 @@ public class WhileStatementEvaluator implements Evaluator {
break;
}
}
try {
myBodyEvaluator.evaluate(context);
}
catch (BreakException e) {
if (Comparing.equal(e.getLabelName(), myLabelName)) {
break;
}
else {
throw e;
}
}
catch (ContinueException e) {
if (!Comparing.equal(e.getLabelName(), myLabelName)) {
throw e;
}
}
if (body(context)) break;
}
return value;
}
}