package org.eclipse.dltk.rhino.dbgp;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.NativeArray;
import org.mozilla.javascript.NativeJavaArray;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.debug.DebugFrame;
import org.mozilla.javascript.debug.DebuggableScript;
import org.mozilla.javascript.debug.Debugger;
public final class DBGPDebugFrame implements DebugFrame {
private final String sourceName;
private final DBGPStackManager stackManager;
private int lineNumber;
private String where;
private Scriptable thisObj;
private Scriptable scope;
private DebuggableScript script;
private Object[] args;
private Context context;
private boolean suspend;
private boolean callOnEnter;
public boolean isSuspend() {
return suspend;
}
public void setSuspend(boolean suspend) {
this.suspend = suspend;
}
public DBGPDebugFrame(Context ct, DebuggableScript node,
DBGPDebugger debugger) {
sourceName = node.getSourceName();
this.context = ct;
stackManager = DBGPStackManager.getManager(ct);
where = node.getFunctionName();
this.script = node;
if (where == null) {
where = "module";
}
}
public String[] getParametersAndVars() {
String[] result = new String[script.getParamAndVarCount()];
for (int a = 0; a < result.length; a++) {
result[a] = script.getParamOrVarName(a);
}
return result;
}
@Override
public void onEnter(Context cx, Scriptable activation, Scriptable thisObj,
Object[] args) {
this.args = args;
this.scope = activation;
this.thisObj = thisObj;
callOnEnter = true;
}
@Override
public void onExceptionThrown(Context cx, Throwable ex) {
stackManager.exceptionThrown(ex);
}
@Override
public void onExit(Context cx, boolean byThrow, Object resultOrException) {
stackManager.exit(this);
}
@Override
public void onLineChange(Context cx, int lineNumber) {
this.lineNumber = lineNumber;
if (callOnEnter) {
callOnEnter = false;
stackManager.enter(this);
} else {
stackManager.changeLine(this, lineNumber);
}
}
public String getSourceName() {
return sourceName;
}
public int getLineNumber() {
return lineNumber;
}
public void setLineNumber(int lineNumber) {
this.lineNumber = lineNumber;
}
public String getWhere() {
return where;
}
public Object getValue(int num) {
Object object = scope.get(script.getParamOrVarName(num), thisObj);
return object;
}
public Object getStackFrameArgs() {
Object object = scope.get("arguments", thisObj);
return object;
}
public Scriptable getThis() {
return thisObj;
}
public void setValue(String name, String value) {
if (name.startsWith("this.")) {
name = name.substring("this.".length());
thisObj.put(name, thisObj, eval(value));
} else
scope.put(name, scope, value);
}
public Object eval(String value) {
Debugger debugger = context.getDebugger();
try {
context.setDebugger(null, null);
Scriptable cs = scope;
if (value.startsWith("this.")) {
value = value.substring("this.".length());
cs = thisObj;
}
Object evaluateString = context.evaluateString(cs, value, "eval", 0,
null);
return evaluateString;
} catch (Throwable e) {
return "Error during evaluation:" + e.getMessage();
} finally {
context.setDebugger(debugger, null);
}
}
public Object getValue(String longName) {
if (longName.startsWith("this")) {
int indexOf = longName.indexOf('.');
if (indexOf == -1)
return thisObj;
longName = longName.substring("this.".length());
return getProperty(thisObj, longName);
}
return getProperty(scope, longName);
}
private Object getProperty(Scriptable obj, String longName) {
int k = longName.indexOf('.');
if (k == -1)
return shortGet(obj, longName);
String shortName = longName.substring(0, k);
String sm = longName.substring(k + 1);
Object property = shortGet(obj, shortName);
if (property instanceof Scriptable) {
return getProperty((Scriptable) property, sm);
}
return null;
}
private Object shortGet(Scriptable obj, String longName) {
if (obj instanceof NativeJavaArray || obj instanceof NativeArray) {
longName = longName.trim();
if (longName.startsWith("["))
longName = longName.substring(1, longName.length() - 1);
int parseInt = Integer.parseInt(longName);
return obj.get(parseInt, obj);
}
Scriptable parent = obj;
while (parent != null) {
Object o = ScriptableObject.getProperty(parent, longName);
if (o != null && o != Scriptable.NOT_FOUND)
return o;
parent = parent.getParentScope();
}
try {
int parseInt = Integer.parseInt(longName);
Object o = ScriptableObject.getProperty(obj, parseInt);
if (o != null && o != Scriptable.NOT_FOUND)
return o;
} catch (Exception e) {
}
return null;
}
}