fix NPE when using the debugger
This commit is contained in:
parent
2ce4f02f97
commit
9aca411bbd
|
@ -9,6 +9,7 @@ import org.junit.Before;
|
||||||
import org.junit.runner.Description;
|
import org.junit.runner.Description;
|
||||||
import org.junit.runner.Runner;
|
import org.junit.runner.Runner;
|
||||||
import org.junit.runner.notification.RunNotifier;
|
import org.junit.runner.notification.RunNotifier;
|
||||||
|
import org.mozilla.javascript.ContextFactory;
|
||||||
import org.mozilla.javascript.NativeArray;
|
import org.mozilla.javascript.NativeArray;
|
||||||
import org.mozilla.javascript.tools.debugger.Main;
|
import org.mozilla.javascript.tools.debugger.Main;
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ public class JasmineTestRunner extends Runner {
|
||||||
|
|
||||||
Main debugger = null;
|
Main debugger = null;
|
||||||
if (this.suiteAnnotation.debug()) {
|
if (this.suiteAnnotation.debug()) {
|
||||||
debugger = this.rhinoContext.createDebugger();
|
debugger = createDebugger();
|
||||||
}
|
}
|
||||||
|
|
||||||
this.rhinoContext = setUpRhinoScope();
|
this.rhinoContext = setUpRhinoScope();
|
||||||
|
@ -62,6 +63,23 @@ public class JasmineTestRunner extends Runner {
|
||||||
context.evalJS("jasmine.getEnv().addReporter(new jasmine.DelegatorJUnitReporter());");
|
context.evalJS("jasmine.getEnv().addReporter(new jasmine.DelegatorJUnitReporter());");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Main createDebugger() {
|
||||||
|
Main debugger = new Main("JS Debugger");
|
||||||
|
|
||||||
|
debugger.setExitAction(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
debugger.attachTo(ContextFactory.getGlobal());
|
||||||
|
debugger.pack();
|
||||||
|
debugger.setSize(600, 460);
|
||||||
|
debugger.setVisible(true);
|
||||||
|
|
||||||
|
return debugger;
|
||||||
|
}
|
||||||
|
|
||||||
private JasmineSuite getJasmineSuiteAnnotationFromTestClass() {
|
private JasmineSuite getJasmineSuiteAnnotationFromTestClass() {
|
||||||
JasmineSuite suiteAnnotation = testClass.getAnnotation(JasmineSuite.class);
|
JasmineSuite suiteAnnotation = testClass.getAnnotation(JasmineSuite.class);
|
||||||
if (suiteAnnotation == null) {
|
if (suiteAnnotation == null) {
|
||||||
|
|
|
@ -5,150 +5,132 @@ import org.mozilla.javascript.ContextFactory;
|
||||||
import org.mozilla.javascript.Function;
|
import org.mozilla.javascript.Function;
|
||||||
import org.mozilla.javascript.Scriptable;
|
import org.mozilla.javascript.Scriptable;
|
||||||
import org.mozilla.javascript.ScriptableObject;
|
import org.mozilla.javascript.ScriptableObject;
|
||||||
import org.mozilla.javascript.tools.debugger.Main;
|
|
||||||
import org.mozilla.javascript.tools.shell.Global;
|
import org.mozilla.javascript.tools.shell.Global;
|
||||||
|
|
||||||
public class RhinoContext {
|
public class RhinoContext {
|
||||||
|
|
||||||
private Context jsContext;
|
private Context jsContext;
|
||||||
private Scriptable jsScope;
|
private Scriptable jsScope;
|
||||||
|
|
||||||
public RhinoContext() {
|
public RhinoContext() {
|
||||||
this.jsContext = createJavascriptContext();
|
this.jsContext = createJavascriptContext();
|
||||||
this.jsScope = createJavascriptScopeForContext(this.jsContext);
|
this.jsScope = createJavascriptScopeForContext(this.jsContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RhinoContext(Scriptable sharedScope) {
|
public RhinoContext(Scriptable sharedScope) {
|
||||||
this.jsContext = createJavascriptContext();
|
this.jsContext = createJavascriptContext();
|
||||||
Scriptable newScope = this.jsContext.newObject(sharedScope);
|
Scriptable newScope = this.jsContext.newObject(sharedScope);
|
||||||
newScope.setPrototype(sharedScope);
|
newScope.setPrototype(sharedScope);
|
||||||
newScope.setParentScope(null);
|
newScope.setParentScope(null);
|
||||||
|
|
||||||
this.jsScope = newScope;
|
this.jsScope = newScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
private RhinoContext createNewRhinoContextBasedOnPrevious() {
|
private RhinoContext createNewRhinoContextBasedOnPrevious() {
|
||||||
return new RhinoContext(this.jsScope);
|
return new RhinoContext(this.jsScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void runAsync(final RhinoRunnable runnable) {
|
public void runAsync(final RhinoRunnable runnable) {
|
||||||
new Thread(new Runnable() {
|
new Thread(new Runnable() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
RhinoContext newRhinoContextBasedOnPrevious = createNewRhinoContextBasedOnPrevious();
|
RhinoContext newRhinoContextBasedOnPrevious = createNewRhinoContextBasedOnPrevious();
|
||||||
try {
|
try {
|
||||||
runnable.run(newRhinoContextBasedOnPrevious);
|
runnable.run(newRhinoContextBasedOnPrevious);
|
||||||
} finally {
|
} finally {
|
||||||
newRhinoContextBasedOnPrevious.exit();
|
newRhinoContextBasedOnPrevious.exit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).start();
|
}).start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object evalJS(String js) {
|
public Object evalJS(String js) {
|
||||||
return this.jsContext.evaluateString(this.jsScope, js, "script", 1, null);
|
return this.jsContext.evaluateString(this.jsScope, js, "script", 1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends ScriptableObject> T createClassInJS(Class<T> classToExport) {
|
public <T extends ScriptableObject> T createClassInJS(Class<T> classToExport) {
|
||||||
exportClass(classToExport);
|
exportClass(classToExport);
|
||||||
T newObj = (T) jsContext.newObject(jsScope, classToExport.getSimpleName());
|
T newObj = (T) jsContext.newObject(jsScope, classToExport.getSimpleName());
|
||||||
return newObj;
|
return newObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setProperty(String objectToReceiveProperty, String property, Object value) {
|
public void setProperty(String objectToReceiveProperty, String property, Object value) {
|
||||||
Object obj = evalJS(objectToReceiveProperty);
|
Object obj = evalJS(objectToReceiveProperty);
|
||||||
if (obj == null || !(obj instanceof ScriptableObject)) {
|
if (obj == null || !(obj instanceof ScriptableObject)) {
|
||||||
throw new IllegalStateException("object to receive property is no ScriptableObject but a "
|
throw new IllegalStateException("object to receive property is no ScriptableObject but a "
|
||||||
+ (obj == null ? "" : obj.getClass().getSimpleName()));
|
+ (obj == null ? "" : obj.getClass().getSimpleName()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptableObject objectToReceive = (ScriptableObject) obj;
|
ScriptableObject objectToReceive = (ScriptableObject) obj;
|
||||||
objectToReceive.put(property, objectToReceive, value);
|
objectToReceive.put(property, objectToReceive, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void exportClass(Class<? extends ScriptableObject> classToExport) {
|
private void exportClass(Class<? extends ScriptableObject> classToExport) {
|
||||||
try {
|
try {
|
||||||
ScriptableObject.defineClass(this.jsScope, classToExport);
|
ScriptableObject.defineClass(this.jsScope, classToExport);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(String path, String... jsFiles) {
|
public void load(String path, String... jsFiles) {
|
||||||
for (String jsFile : jsFiles) {
|
for (String jsFile : jsFiles) {
|
||||||
load(path + jsFile);
|
load(path + jsFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void load(String fileName) {
|
public void load(String fileName) {
|
||||||
evalJS("load('" + fileName + "')");
|
evalJS("load('" + fileName + "')");
|
||||||
// Main.processFile(this.jsContext, this.jsScope, fileName);
|
// Main.processFile(this.jsContext, this.jsScope, fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object executeFunction(ScriptableObject object, String fnName, Object[] arguments) {
|
public Object executeFunction(ScriptableObject object, String fnName, Object[] arguments) {
|
||||||
Object fnPointer = object.get(fnName, object);
|
Object fnPointer = object.get(fnName, object);
|
||||||
if (fnPointer == null || !(fnPointer instanceof Function)) {
|
if (fnPointer == null || !(fnPointer instanceof Function)) {
|
||||||
fnPointer = object.getPrototype().get(fnName, object);
|
fnPointer = object.getPrototype().get(fnName, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ((Function) fnPointer).call(jsContext, jsScope, object, arguments);
|
return ((Function) fnPointer).call(jsContext, jsScope, object, arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object executeFunction(ScriptableObject object, String fnName) {
|
public Object executeFunction(ScriptableObject object, String fnName) {
|
||||||
return executeFunction(object, fnName, new Object[] {});
|
return executeFunction(object, fnName, new Object[] {});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context getJsContext() {
|
public Context getJsContext() {
|
||||||
return jsContext;
|
return jsContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Scriptable getJsScope() {
|
public Scriptable getJsScope() {
|
||||||
return jsScope;
|
return jsScope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadEnv(String jsDir) {
|
public void loadEnv(String jsDir) {
|
||||||
// TODO ensure rhino 1.7R3 instead of R2 -> geen shim nodig + paths
|
// TODO ensure rhino 1.7R3 instead of R2 -> geen shim nodig + paths
|
||||||
// gedoe in orde zetten hier
|
// gedoe in orde zetten hier
|
||||||
load(jsDir + "/lib/es5-shim-0.0.4.min.js");
|
load(jsDir + "/lib/es5-shim-0.0.4.min.js");
|
||||||
load(jsDir + "/lib/env.rhino.1.2.js");
|
load(jsDir + "/lib/env.rhino.1.2.js");
|
||||||
load(jsDir + "/lib/env.utils.js");
|
load(jsDir + "/lib/env.utils.js");
|
||||||
load(jsDir + "/envJsOptions.js");
|
load(jsDir + "/envJsOptions.js");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Global createJavascriptScopeForContext(Context jsContext) {
|
private Global createJavascriptScopeForContext(Context jsContext) {
|
||||||
Global scope = new Global();
|
Global scope = new Global();
|
||||||
scope.init(jsContext);
|
scope.init(jsContext);
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Context createJavascriptContext() {
|
private Context createJavascriptContext() {
|
||||||
Context jsContext = ContextFactory.getGlobal().enterContext();
|
Context jsContext = ContextFactory.getGlobal().enterContext();
|
||||||
jsContext.setOptimizationLevel(-1);
|
jsContext.setOptimizationLevel(-1);
|
||||||
jsContext.setLanguageVersion(Context.VERSION_1_5); // TODO 1.8 plx
|
jsContext.setLanguageVersion(Context.VERSION_1_5); // TODO 1.8 plx
|
||||||
jsContext.setErrorReporter(new ChainedErrorReporter(jsContext.getErrorReporter()));
|
jsContext.setErrorReporter(new ChainedErrorReporter(jsContext.getErrorReporter()));
|
||||||
return jsContext;
|
return jsContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exit() {
|
public void exit() {
|
||||||
Context.exit();
|
Context.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Main createDebugger() {
|
|
||||||
Main debugger = new Main("JS Rhino Debugger");
|
|
||||||
|
|
||||||
debugger.setExitAction(new Runnable() {
|
|
||||||
|
|
||||||
public void run() {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
debugger.attachTo(ContextFactory.getGlobal());
|
|
||||||
debugger.pack();
|
|
||||||
debugger.setSize(600, 460);
|
|
||||||
debugger.setVisible(true);
|
|
||||||
return debugger;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue