package org.rubypeople.rdt.internal.debug.ui; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.IDebugElement; import org.eclipse.debug.core.model.IStackFrame; import org.eclipse.debug.core.model.IThread; import org.eclipse.debug.core.model.IValue; import org.eclipse.debug.core.model.IWatchExpressionDelegate; import org.eclipse.debug.core.model.IWatchExpressionListener; import org.eclipse.debug.core.model.IWatchExpressionResult; import org.rubypeople.rdt.debug.core.model.IEvaluationResult; import org.rubypeople.rdt.debug.core.model.IRubyStackFrame; import org.rubypeople.rdt.debug.core.model.IRubyThread; public class RubyWatchExpressionDelegate implements IWatchExpressionDelegate { private IWatchExpressionListener fListener; private String fExpressionText; public void evaluateExpression(String expression, IDebugElement context, IWatchExpressionListener listener) { fExpressionText = expression; fListener = listener; // find a stack frame context if possible. IStackFrame frame = null; if (context instanceof IStackFrame) { frame = (IStackFrame) context; } else if (context instanceof IThread) { try { frame = ((IThread) context).getTopStackFrame(); } catch (DebugException e) { } } if (frame == null) { fListener.watchEvaluationFinished(null); } else { // consult the adapter in case of a wrappered debug model final IRubyStackFrame rubyStackFrame = (IRubyStackFrame) ((IAdaptable) frame) .getAdapter(IRubyStackFrame.class); if (rubyStackFrame != null) { doEvaluation(rubyStackFrame); } else { fListener.watchEvaluationFinished(null); } } } private void doEvaluation(IRubyStackFrame rubyStackFrame) { IRubyThread thread = (IRubyThread) rubyStackFrame.getThread(); if (preEvaluationCheck(thread)) { thread.queueRunnable(new EvaluationRunnable(rubyStackFrame)); } else { fListener.watchEvaluationFinished(null); } } private boolean preEvaluationCheck(IRubyThread javaThread) { if (javaThread == null) { return false; } // if (javaThread.isSuspended() && ((JDIThread)javaThread).isInvokingMethod()) { // return false; // } return true; } /** * Runnable used to evaluate the expression. */ private final class EvaluationRunnable implements Runnable { private final IRubyStackFrame fStackFrame; private EvaluationRunnable(IRubyStackFrame frame) { fStackFrame = frame; } public void run() { IEvaluationResult result = fStackFrame.evaluate(fExpressionText); IWatchExpressionResult watchResult = new EvaluationWatchExpressionResult(result); fListener.watchEvaluationFinished(watchResult); } } private class EvaluationWatchExpressionResult implements IWatchExpressionResult { private IEvaluationResult result; EvaluationWatchExpressionResult(IEvaluationResult result) { this.result = result; } public String[] getErrorMessages() { return result.getErrorMessages(); } public DebugException getException() { return result.getException(); } public String getExpressionText() { return result.getSnippet(); } public IValue getValue() { return result.getValue(); } public boolean hasErrors() { return result.hasErrors(); } } }