/** * Aptana Studio * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the GNU Public License (GPL) v3 (with exceptions). * Please see the license.html included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package com.aptana.ruby.internal.debug.core.model; 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 com.aptana.ruby.debug.core.model.IEvaluationResult; import com.aptana.ruby.debug.core.model.IRubyStackFrame; import com.aptana.ruby.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 rubyThread) { // if (rubyThread == null || (rubyThread.isSuspended() && ((RubyThread) rubyThread).isInvokingMethod())) // { // return false; // } // return true; return rubyThread != null; } /** * 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(); } } }