/******************************************************************************* * Copyright (c) 2009 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Zend Technologies *******************************************************************************/ package org.eclipse.php.internal.debug.ui.watch; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.debug.core.DebugException; import org.eclipse.debug.core.model.*; import org.eclipse.dltk.core.ISourceRange; import org.eclipse.php.internal.core.util.text.PHPTextSequenceUtilities; import org.eclipse.php.internal.debug.core.xdebug.dbgp.model.DBGpEvalVariable; import org.eclipse.php.internal.debug.core.xdebug.dbgp.model.DBGpStackFrame; import org.eclipse.php.internal.debug.core.xdebug.dbgp.model.DBGpStackVariable; import org.eclipse.php.internal.debug.core.xdebug.dbgp.model.DBGpTarget; import org.eclipse.php.internal.debug.core.xdebug.dbgp.model.DBGpVariable.Kind; import org.eclipse.php.internal.debug.core.xdebug.dbgp.protocol.DBGpResponse; import org.eclipse.php.internal.debug.ui.Logger; import org.eclipse.php.internal.debug.ui.PHPDebugUIMessages; import org.w3c.dom.Node; /** * XDebug watch expression delegate. */ public class XDebugWatchExpressionDelegate implements IWatchExpressionDelegate { private String expressionText; private IWatchExpressionListener watchListener; private DBGpTarget debugTarget; private DBGpStackFrame stackFrame; private Job evalJob; /** * @see org.eclipse.debug.core.model.IWatchExpressionDelegate#getValue(java.lang.String, * org.eclipse.debug.core.model.IDebugElement) */ public void evaluateExpression(String expression, IDebugElement context, IWatchExpressionListener listener) { expressionText = expression; watchListener = listener; IDebugTarget target = context.getDebugTarget(); if (target instanceof DBGpTarget && context instanceof DBGpStackFrame) { debugTarget = (DBGpTarget) target; stackFrame = (DBGpStackFrame) context; if (!debugTarget.isSuspended()) { // can't evaluate unless suspended watchListener.watchEvaluationFinished(null); } else { evalJob = new EvaluationRunnable(); evalJob.schedule(); } } else { watchListener.watchEvaluationFinished(null); } } /** * Runnable used to evaluate the expression. */ private final class EvaluationRunnable extends Job { public EvaluationRunnable() { super("XDEbugEvaluationRunnable"); //$NON-NLS-1$ setSystem(true); } public IStatus run(IProgressMonitor monitor) { try { XDebugWatchExpressionResult watchResult = new XDebugWatchExpressionResult(); watchResult.evaluate(); watchListener.watchEvaluationFinished(watchResult); } catch (Exception e) { Logger.logException(e); watchListener.watchEvaluationFinished(null); } return Status.OK_STATUS; } } private class XDebugWatchExpressionResult implements IWatchExpressionResult, IWatchExpressionResultExtension { private boolean hasErrors = false; private IValue evalResult; void evaluate() { String watchExpression = expressionText.trim(); Node result = null; String stackLevel = stackFrame.getStackLevel(); Kind exprKind = Kind.EVAL; if (watchExpression.startsWith("$")) {//$NON-NLS-1$ ISourceRange enclosingIdentifier = PHPTextSequenceUtilities.getEnclosingIdentifier(watchExpression, 0); if (enclosingIdentifier != null && enclosingIdentifier.getLength() == watchExpression.length() + 1) { exprKind = Kind.STACK; } } switch (exprKind) { case STACK: { result = debugTarget.getProperty(watchExpression, stackLevel, 0); if (result == null || DBGpResponse.REASON_ERROR.equals(result.getNodeName())) { // Check if it is not super global property stackLevel = "-1"; //$NON-NLS-1$ result = debugTarget.getProperty(watchExpression, stackLevel, 0); } break; } default: result = debugTarget.eval(watchExpression); break; } if (result != null) { IVariable tempVar; switch (exprKind) { case STACK: { tempVar = new DBGpStackVariable(debugTarget, result, Integer.valueOf(stackLevel)); break; } default: tempVar = new DBGpEvalVariable(debugTarget, watchExpression, result); break; } evalResult = null; try { evalResult = tempVar.getValue(); if (evalResult == null) { hasErrors = true; } } catch (Exception e) { hasErrors = true; } } else { hasErrors = true; } } public IValue getValue() { return evalResult; } public boolean hasErrors() { return hasErrors; } public String[] getErrorMessages() { if (hasErrors) { // failed to evaluate expression. return new String[] { PHPDebugUIMessages.XDebugWatch_failed }; } return null; } public String getExpressionText() { return expressionText; } public DebugException getException() { return null; } public IDebugTarget getDebugTarget() { return debugTarget; } } }