blob: f2608868bdee0d888ae54fbbbd62309790f57be1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Sierra Wireless 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:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.ldt.debug.core.internal;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.dltk.dbgp.breakpoints.IDbgpBreakpoint;
import org.eclipse.dltk.dbgp.exceptions.DbgpException;
import org.eclipse.dltk.debug.core.eval.IScriptEvaluationEngine;
import org.eclipse.dltk.debug.core.model.IScriptThread;
import org.eclipse.dltk.internal.debug.core.model.IScriptStreamProxy;
import org.eclipse.dltk.internal.debug.core.model.ScriptThread;
/**
* Represents a coroutine for Lua debugger. This differ from a regular script thread because it cannot be controlled, and the way to get info about it
* is different (use non standard commands and switches).
*
* FIXME: extends {@link ScriptThread} instead of implementing {@link IScriptThread} because of hard-coded casts in DLTK code. This causes a lot of
* hacky code (duplicate stack, way to deal with DbgpSession, ...), in future versions of DLTY, try to see if there is a chance of stick only with
* interfaces.
*/
public class LuaCoroutine extends ScriptThread {
private LuaDebugTarget debugTarget;
private String coroutineId;
private String name;
private LuaCoroutineStack stack;
/**
* @param debugTarget
* @param frames
* @throws CoreException
* @throws DbgpException
*/
public LuaCoroutine(LuaDebugTarget debugTarget, String id, String name) throws DbgpException, CoreException {
// we can't access to this in LuaCoroutineDbgpSession ctor, so the coroutine is bound on a second time
super(debugTarget, new LuaCoroutineDbgpSession(debugTarget.getMainThread().getDbgpSession(), null), null);
this.debugTarget = debugTarget;
this.coroutineId = id;
this.name = name;
((LuaCoroutineDbgpSession) super.getDbgpSession()).bindToCoroutine(this);
// the way to handle stack is a bit different here (lazy loading)
this.stack = new LuaCoroutineStack(this);
}
public String getCoroutineId() {
return this.coroutineId;
}
protected void coroNotSupported() throws DebugException {
makeNotSupported("Not supported for a coroutine", null); //$NON-NLS-1$
}
// stack handling
/**
* @see org.eclipse.dltk.internal.debug.core.model.ScriptThread#hasStackFrames()
*/
@Override
public boolean hasStackFrames() {
return stack.hasFrames();
}
/**
* @see org.eclipse.dltk.internal.debug.core.model.ScriptThread#getStackFrames()
*/
@Override
public IStackFrame[] getStackFrames() throws DebugException {
return stack.getFrames();
}
/**
* @see org.eclipse.dltk.internal.debug.core.model.ScriptThread#updateStackFrames()
*/
@Override
public void updateStackFrames() {
stack.updateFrames();
}
// other methods
/**
* @see org.eclipse.debug.core.model.IThread#getPriority()
*/
@Override
public int getPriority() throws DebugException {
return 0;
}
/**
* @see org.eclipse.debug.core.model.IThread#getName()
*/
@Override
public String getName() {
return name;
}
/**
* @see org.eclipse.debug.core.model.IThread#getBreakpoints()
*/
@Override
public IBreakpoint[] getBreakpoints() {
return DebugPlugin.getDefault().getBreakpointManager().getBreakpoints(getModelIdentifier());
}
/**
* @see org.eclipse.debug.core.model.IDebugElement#getDebugTarget()
*/
@Override
public IDebugTarget getDebugTarget() {
return debugTarget;
}
/**
* @see org.eclipse.debug.core.model.ISuspendResume#canResume()
*/
@Override
public boolean canResume() {
return false;
}
/**
* @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
*/
@Override
public boolean canSuspend() {
return false;
}
/**
* @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
*/
@Override
public boolean isSuspended() {
IScriptThread mainThread = debugTarget.getMainThread();
return mainThread == null || mainThread.isSuspended();
}
/**
* @see org.eclipse.debug.core.model.ISuspendResume#resume()
*/
@Override
public void resume() throws DebugException {
coroNotSupported();
}
/**
* @see org.eclipse.debug.core.model.ISuspendResume#suspend()
*/
@Override
public void suspend() throws DebugException {
coroNotSupported();
}
/**
* @see org.eclipse.debug.core.model.IStep#canStepInto()
*/
@Override
public boolean canStepInto() {
return false;
}
/**
* @see org.eclipse.debug.core.model.IStep#canStepOver()
*/
@Override
public boolean canStepOver() {
return false;
}
/**
* @see org.eclipse.debug.core.model.IStep#canStepReturn()
*/
@Override
public boolean canStepReturn() {
return false;
}
/**
* @see org.eclipse.debug.core.model.IStep#isStepping()
*/
@Override
public boolean isStepping() {
return false;
}
/**
* @see org.eclipse.debug.core.model.IStep#stepInto()
*/
@Override
public void stepInto() throws DebugException {
coroNotSupported();
}
/**
* @see org.eclipse.debug.core.model.IStep#stepOver()
*/
@Override
public void stepOver() throws DebugException {
coroNotSupported();
}
/**
* @see org.eclipse.debug.core.model.IStep#stepReturn()
*/
@Override
public void stepReturn() throws DebugException {
coroNotSupported();
}
/**
* @see org.eclipse.debug.core.model.ITerminate#canTerminate()
*/
@Override
public boolean canTerminate() {
IScriptThread mainThread = debugTarget.getMainThread();
return mainThread != null && mainThread.canTerminate();
}
/**
* @see org.eclipse.debug.core.model.ITerminate#isTerminated()
*/
@Override
public boolean isTerminated() {
IScriptThread mainThread = debugTarget.getMainThread();
return mainThread == null || mainThread.isTerminated();
}
/**
* @see org.eclipse.debug.core.model.ITerminate#terminate()
*/
@Override
public void terminate() throws DebugException {
IScriptThread mainThread = debugTarget.getMainThread();
if (mainThread != null) {
mainThread.terminate();
}
}
/**
* @see org.eclipse.dltk.debug.core.model.IScriptThread#getDbgpBreakpoint(java.lang.String)
*/
@Override
public IDbgpBreakpoint getDbgpBreakpoint(String id) {
IScriptThread mainThread = debugTarget.getMainThread();
return mainThread == null ? null : mainThread.getDbgpBreakpoint(id);
}
/**
* @see org.eclipse.dltk.debug.core.model.IScriptThread#getStreamProxy()
*/
@Override
public IScriptStreamProxy getStreamProxy() {
IScriptThread mainThread = debugTarget.getMainThread();
return mainThread == null ? null : mainThread.getStreamProxy();
}
/**
* Returns {@link IScriptEvaluationEngine} from main thread
*
* This method is tricky because we could technically evaluate snippets in coroutine context but DBGp protocol does not provide a way to evaluate
* in a particular stack level and all coroutines are displayed are paused (that is in a yield call) so the context is not really useful.
*
* @see org.eclipse.dltk.debug.core.model.IScriptThread#getEvaluationEngine()
*/
@Override
public IScriptEvaluationEngine getEvaluationEngine() {
IScriptThread mainThread = debugTarget.getMainThread();
return mainThread == null ? null : mainThread.getEvaluationEngine();
}
/**
* @see org.eclipse.dltk.debug.core.model.IScriptThread#getModificationsCount()
*/
@Override
public int getModificationsCount() {
return 0;
}
/**
* @see org.eclipse.dltk.debug.core.model.IScriptThread#sendTerminationRequest()
*/
@Override
public void sendTerminationRequest() throws DebugException {
IScriptThread mainThread = debugTarget.getMainThread();
if (mainThread != null) {
debugTarget.getMainThread().sendTerminationRequest();
}
}
// some methods does not require any processing for coroutines
/**
* @see org.eclipse.dltk.internal.debug.core.model.ScriptThread#initialize(org.eclipse.core.runtime.IProgressMonitor)
*/
@Override
public void initialize(IProgressMonitor monitor) throws DbgpException {
}
/**
* @see org.eclipse.dltk.internal.debug.core.model.ScriptThread#objectTerminated(java.lang.Object, java.lang.Exception)
*/
@Override
public void objectTerminated(Object object, Exception e) {
}
/**
* @see org.eclipse.dltk.internal.debug.core.model.ScriptThread#handleTermination(org.eclipse.dltk.dbgp.exceptions.DbgpException)
*/
@Override
public void handleTermination(DbgpException e) {
}
/**
* @see org.eclipse.dltk.internal.debug.core.model.ScriptThread#handleResume(int)
*/
@Override
public void handleResume(int detail) {
}
/**
* @see org.eclipse.dltk.internal.debug.core.model.ScriptThread#handleSuspend(int)
*/
@Override
public void handleSuspend(int detail) {
}
}