| /******************************************************************************* |
| * Copyright (c) 2000, 2015 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.jdt.internal.debug.ui; |
| |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.debug.core.DebugEvent; |
| 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.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.debug.core.IJavaDebugTarget; |
| import org.eclipse.jdt.debug.core.IJavaStackFrame; |
| import org.eclipse.jdt.debug.core.IJavaThread; |
| import org.eclipse.jdt.debug.eval.IAstEvaluationEngine; |
| import org.eclipse.jdt.debug.eval.IEvaluationListener; |
| import org.eclipse.jdt.debug.eval.IEvaluationResult; |
| import org.eclipse.jdt.internal.debug.core.JDIDebugPlugin; |
| import org.eclipse.jdt.internal.debug.core.JavaDebugUtils; |
| import org.eclipse.jdt.internal.debug.core.model.JDIThread; |
| import org.eclipse.jdt.internal.debug.ui.display.JavaInspectExpression; |
| |
| /** |
| * |
| */ |
| public class JavaWatchExpressionDelegate implements IWatchExpressionDelegate { |
| |
| private String fExpressionText; |
| private IWatchExpressionListener fListener; |
| |
| /** |
| * @see org.eclipse.debug.core.model.IWatchExpressionDelegate#getValue(java.lang.String, org.eclipse.debug.core.model.IDebugElement) |
| */ |
| @Override |
| 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 IJavaStackFrame javaStackFrame = ((IAdaptable) frame).getAdapter(IJavaStackFrame.class); |
| if (javaStackFrame != null) { |
| doEvaluation(javaStackFrame); |
| } else { |
| fListener.watchEvaluationFinished(null); |
| } |
| } |
| } |
| |
| /** |
| * Ask to evaluate the expression in the context of the given stack frame. |
| * |
| * The evaluation is performed asynchronously. A change debug event, with |
| * this as the source, is fired when the evaluation is completed. |
| * |
| * @param javaStackFrame the stack frame in the context of which performed |
| * the evaluation. |
| */ |
| protected void doEvaluation(IJavaStackFrame javaStackFrame) { |
| IJavaThread thread = (IJavaThread)javaStackFrame.getThread(); |
| if (preEvaluationCheck(thread)) { |
| thread.queueRunnable(new EvaluationRunnable(javaStackFrame)); |
| } else { |
| fListener.watchEvaluationFinished(null); |
| } |
| } |
| |
| private boolean preEvaluationCheck(IJavaThread 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 IJavaStackFrame fStackFrame; |
| |
| private EvaluationRunnable(IJavaStackFrame frame) { |
| fStackFrame= frame; |
| } |
| |
| @Override |
| public void run() { |
| IJavaProject project = JavaDebugUtils.resolveJavaProject(fStackFrame); |
| if (project == null) { |
| fListener.watchEvaluationFinished(null); |
| return; |
| } |
| IAstEvaluationEngine evaluationEngine= JDIDebugPlugin.getDefault().getEvaluationEngine(project, (IJavaDebugTarget) fStackFrame.getDebugTarget()); |
| // the evaluation listener |
| IEvaluationListener listener= new IEvaluationListener() { |
| @Override |
| public void evaluationComplete(final IEvaluationResult result) { |
| IWatchExpressionResult watchResult= new IWatchExpressionResult() { |
| @Override |
| public IValue getValue() { |
| return result.getValue(); |
| } |
| @Override |
| public boolean hasErrors() { |
| return result.hasErrors(); |
| } |
| @Override |
| public String[] getErrorMessages() { |
| return JavaInspectExpression.getErrorMessages(result); |
| } |
| @Override |
| public String getExpressionText() { |
| return result.getSnippet(); |
| } |
| @Override |
| public DebugException getException() { |
| return result.getException(); |
| } |
| }; |
| fListener.watchEvaluationFinished(watchResult); |
| } |
| }; |
| try { |
| evaluationEngine.evaluate(fExpressionText, fStackFrame, listener, DebugEvent.EVALUATION_IMPLICIT, false); |
| } catch (DebugException e) { |
| JDIDebugPlugin.log(e); |
| fListener.watchEvaluationFinished(null); |
| } |
| } |
| } |
| } |