I can't help with the eclipse dltk, it looked interesting, but not for my
project.
I do want to post the results of what I've learned related to this question,
both to help out others in the future, and to make sure nobody spends effort
answering a question I have an answer to.
The code below is the most simple example of an embedded debugger I could
create. Of course a production implementation would break the interface
methods into a more logical structure, but this test piece shows the
creation of a basic debugger, beginning to end, what interfaces are required
(at a minimum), and includes a few comments to help out. All in the most
simple example I could create. It has no dependencies, you can execute it as
is.
If anyone on this list likes this example and wants to post it elsewhere,
feel free. It would have helped me to have it.
import org.mozilla.javascript.*;
import org.mozilla.javascript.debug.Debugger;
import org.mozilla.javascript.debug.DebuggableScript;
import org.mozilla.javascript.debug.DebugFrame;
public class MainPOC implements ContextAction, ContextFactory.Listener,
Debugger, DebugFrame {
ContextFactory contextFactory;
//The simple javascript to be executed. Replace this with whatever you
like.
static String js = "var x=1;" + "\n" +
"var y=2;" + "\n" +
"var z=3;" + "\n" +
"var a=4";
//main method simply instantiates an instance of this class
public static void main(String[] argv){
MainPOC environment = new MainPOC();
environment.execute();
}
//Primary method which begins execution
public void execute(){
//Get the global context factory instance
this.contextFactory = ContextFactory.getGlobal();
//Add a listener to the context factory, this is necessary so that
we may connect our debugger
//to the context as it is created.
contextFactory.addListener(this);
//This creates a context for the currently executing thread (in this
single threaded
//example that is just the Main thread). this.run will be executed
by the ContextFactory once the
//appropriate context has been created.
contextFactory.call(this);
}
//Executed by the ContextFactory. This method implements the interface
ContextAction and is pased
//to the ContextFactory. The execution of the script happens here. We
first create a scope (the environment/set of
//objects in which the the script will execute within), then execute the
script using the context making the
// call to this function and the scope we just created.
public Object run(Context cx) {
boolean amHere = true;
ScriptableObject scope = cx.initStandardObjects();
Script script = cx.compileString(js, "myJs", 1, null);
script.exec(cx, scope);
return null;
}
//Called when a context is created (in our example it only happens once,
but with multiple threads it would occur
//for each thread. It is at this point that you connect your debugger to
the context. Connecting a debugger
//to a context simply means that you pass it an object implementing the
Debugger interface. Callbacks from
//the runtime engine to this interface all the debugger to take action
as the script executes.
public void contextCreated(Context cx) {
//The ContextData object is any arbitrary object, it is not used by
the Rhino runtime engine at all, rather
//it is just passed back to the debugger methods implemented here
and provides a per context communication
//vehicle. In this example the object does nothing interesting.
ContextData contextData = new ContextData();
//The debugger is any object implementing the Debugger interface
cx.setDebugger(this, contextData);
cx.setGeneratingDebug(true);
cx.setOptimizationLevel(-1);
}
public void contextReleased(Context cx) {
//The use of amHere is simply there in order for you to set a
breakpoint and watch execution within this example
boolean amHere = true;
}
public void handleCompilationDone(Context cx, DebuggableScript
fnOrScript, String source) {
boolean amHere = true;
}
//This method must return an object implementing the DebugFrame
interface.
//The DebugFrame interface is called during script execution and
provides the line by line functions such as
//Line change, Exception capturing, Enter/Exit functions, etc.
public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) {
return this;
}
//The functions from here on down implement DebugFrame and are called by
the debugger as the script executes.
//They are self explanatory, and described in more detail in the
javadocs (though you must re-build the java
//docs from ant or manually if you want to get the java docs for the
debugger classes).
public void onEnter(Context cx, Scriptable activation, Scriptable
thisObj, Object[] args) {
boolean amHere = true;
}
public void onLineChange(Context cx, int lineNumber) {
boolean amHere = true;
System.out.println("At Line #: " + lineNumber);
}
public void onExceptionThrown(Context cx, Throwable ex) {
boolean amHere = true;
}
public void onExit(Context cx, boolean byThrow, Object
resultOrException) {
boolean amHere = true;
}
public void onDebuggerStatement(Context cx) {
boolean amHere = true;
}
class ContextData{
ContextData(){
//Unused constructor, this class can be used to store per
Context data, and is passed
//back to the host application by the debug engine, but it is
not used by the debug engine itself.
boolean amHere=true;
}
}
}
_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino