diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java new file mode 100644 index 000000000000..8d940912ba8e --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/DoWhileStatementEvaluator.java @@ -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; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java index 9375f197ca11..85e0d4f2656c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java @@ -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); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java index 5914c878086e..065eb5978032 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java @@ -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) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java index 7af8c894e9b4..3b1e8cdf43e9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java @@ -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; } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java index 7b7b44856155..01d06cfc503f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java @@ -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); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LoopEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LoopEvaluator.java new file mode 100644 index 000000000000..3563211dbf5a --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/LoopEvaluator.java @@ -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); + } + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java index 82f4ca8de0ad..b328e55de29c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/WhileStatementEvaluator.java @@ -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; } - }