Refactor Eclipse plugin

This commit is contained in:
konsoletyper 2014-09-13 16:45:04 +04:00
parent 0fd69241f1
commit ce78bdb07f
32 changed files with 683 additions and 800 deletions

View File

@ -502,13 +502,21 @@ public class ChromeRDPDebugger implements JavaScriptDebugger, ChromeRDPExchangeC
RDPCallFrame map(CallFrameDTO dto) {
String scopeId = null;
RDPValue thisObject = null;
RDPValue closure = null;
for (ScopeDTO scope : dto.getScopeChain()) {
if (scope.getType().equals("local")) {
scopeId = scope.getObject().getObjectId();
break;
} else if (scope.getType().equals("closure")) {
closure = new RDPValue(this, scope.getObject().getDescription(), scope.getObject().getType(),
scope.getObject().getObjectId(), true);
} else if (scope.getType().equals("global")) {
thisObject = new RDPValue(this, scope.getObject().getDescription(), scope.getObject().getType(),
scope.getObject().getObjectId(), true);
}
}
return new RDPCallFrame(dto.getCallFrameId(), map(dto.getLocation()), new RDPScope(this, scopeId));
return new RDPCallFrame(this, dto.getCallFrameId(), map(dto.getLocation()), new RDPScope(this, scopeId),
thisObject, closure);
}
JavaScriptLocation map(LocationDTO dto) {

View File

@ -17,24 +17,29 @@ package org.teavm.chromerdp;
import java.util.Collections;
import java.util.Map;
import org.teavm.debugging.javascript.JavaScriptCallFrame;
import org.teavm.debugging.javascript.JavaScriptLocation;
import org.teavm.debugging.javascript.JavaScriptVariable;
import org.teavm.debugging.javascript.*;
/**
*
* @author Alexey Andreev
*/
public class RDPCallFrame implements JavaScriptCallFrame {
private JavaScriptDebugger debugger;
private String chromeId;
private JavaScriptLocation location;
private Map<String, JavaScriptVariable> variables;
private JavaScriptValue thisObject;
private JavaScriptValue closure;
public RDPCallFrame(String chromeId, JavaScriptLocation location,
Map<String, ? extends JavaScriptVariable> variables) {
public RDPCallFrame(JavaScriptDebugger debugger, String chromeId, JavaScriptLocation location,
Map<String, ? extends JavaScriptVariable> variables, JavaScriptValue thisObject,
JavaScriptValue closure) {
this.debugger = debugger;
this.chromeId = chromeId;
this.location = location;
this.variables = Collections.unmodifiableMap(variables);
this.thisObject = thisObject;
this.closure = closure;
}
public String getChromeId() {
@ -50,4 +55,19 @@ public class RDPCallFrame implements JavaScriptCallFrame {
public Map<String, JavaScriptVariable> getVariables() {
return variables;
}
@Override
public JavaScriptDebugger getDebugger() {
return debugger;
}
@Override
public JavaScriptValue getThisVariable() {
return thisObject;
}
@Override
public JavaScriptValue getClosureVariable() {
return closure;
}
}

View File

@ -76,4 +76,9 @@ public class RDPValue implements JavaScriptValue {
public boolean hasInnerStructure() {
return innerStructure;
}
@Override
public String getInstanceId() {
return objectId;
}
}

View File

@ -18,6 +18,7 @@ package org.teavm.debugging;
import java.util.Collections;
import java.util.Map;
import org.teavm.debugging.information.SourceLocation;
import org.teavm.debugging.javascript.JavaScriptCallFrame;
import org.teavm.debugging.javascript.JavaScriptLocation;
import org.teavm.model.MethodReference;
@ -26,21 +27,31 @@ import org.teavm.model.MethodReference;
* @author Alexey Andreev
*/
public class CallFrame {
JavaScriptLocation originalLocation;
private Debugger debugger;
private JavaScriptCallFrame originalCallFrame;
private SourceLocation location;
private MethodReference method;
private Map<String, Variable> variables;
CallFrame(JavaScriptLocation originalLocation, SourceLocation location, MethodReference method,
CallFrame(Debugger debugger, JavaScriptCallFrame originalFrame, SourceLocation location, MethodReference method,
Map<String, Variable> variables) {
this.originalLocation = originalLocation;
this.debugger = debugger;
this.originalCallFrame = originalFrame;
this.location = location;
this.method = method;
this.variables = Collections.unmodifiableMap(variables);
}
public Debugger getDebugger() {
return debugger;
}
public JavaScriptLocation getOriginalLocation() {
return originalLocation;
return originalCallFrame.getLocation();
}
public JavaScriptCallFrame getOriginalCallFrame() {
return originalCallFrame;
}
public SourceLocation getLocation() {

View File

@ -48,6 +48,10 @@ public class Debugger {
javaScriptDebugger.addListener(javaScriptListener);
}
public JavaScriptDebugger getJavaScriptDebugger() {
return javaScriptDebugger;
}
public void addListener(DebuggerListener listener) {
listeners.put(listener, dummyObject);
}
@ -99,7 +103,7 @@ public class Debugger {
Set<JavaScriptLocation> successors = new HashSet<>();
for (CallFrame frame : callStack) {
boolean exits;
String script = frame.originalLocation.getScript();
String script = frame.getOriginalLocation().getScript();
DebugInformation debugInfo = debugInformationMap.get(script);
if (frame.getLocation() != null && frame.getLocation().getFileName() != null &&
frame.getLocation().getLine() >= 0 && debugInfo != null) {
@ -297,7 +301,7 @@ public class Debugger {
jsFrame.getLocation().getColumn()) : null;
if (!empty || !wasEmpty) {
VariableMap vars = new VariableMap(jsFrame.getVariables(), this, jsFrame.getLocation());
frames.add(new CallFrame(jsFrame.getLocation(), loc, method, vars));
frames.add(new CallFrame(this, jsFrame, loc, method, vars));
}
wasEmpty = empty;
}

View File

@ -49,6 +49,16 @@ public class Value {
}
public boolean hasInnerStructure() {
if (getType().equals("long")) {
return false;
}
return jsValue.hasInnerStructure();
}
public String getInstanceId() {
if (getType().equals("long")) {
return null;
}
return jsValue.getInstanceId();
}
}

View File

@ -22,7 +22,13 @@ import java.util.Map;
* @author Alexey Andreev
*/
public interface JavaScriptCallFrame {
JavaScriptDebugger getDebugger();
JavaScriptLocation getLocation();
Map<String, JavaScriptVariable> getVariables();
JavaScriptValue getThisVariable();
JavaScriptValue getClosureVariable();
}

View File

@ -29,4 +29,6 @@ public interface JavaScriptValue {
Map<String, JavaScriptVariable> getProperties();
boolean hasInnerStructure();
String getInstanceId();
}

View File

@ -42,7 +42,7 @@
<extension point="org.eclipse.debug.ui.debugModelPresentations">
<debugModelPresentation
class="org.teavm.eclipse.debugger.ui.TeaVMDebugModelPresentation"
id="org.teavm.eclipse.debugger.frame">
id="org.teavm.eclipse.debugger">
</debugModelPresentation>
</extension>
</plugin>

View File

@ -26,12 +26,4 @@ public final class TeaVMDebugConstants {
public static final String JAVA_BREAKPOINT_INSTALL_COUNT = "org.eclipse.jdt.debug.core.installCount";
public static final String DEBUG_TARGET_ID = "org.teavm.eclipse.debugger";
public static final String THREAD_ID = DEBUG_TARGET_ID + ".thread";
public static final String STACK_FRAME_ID = DEBUG_TARGET_ID + ".frame";
public static final String VALUE_ID = DEBUG_TARGET_ID + ".value";
public static final String VARIABLE_ID = DEBUG_TARGET_ID + ".variable";
}

View File

@ -0,0 +1,23 @@
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.model.DebugElement;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public abstract class TeaVMDebugElement extends DebugElement {
public TeaVMDebugElement(TeaVMDebugTarget target) {
super(target);
}
@Override
public String getModelIdentifier() {
return getDebugTarget().getModelIdentifier();
}
@Override
public TeaVMDebugTarget getDebugTarget() {
return (TeaVMDebugTarget)super.getDebugTarget();
}
}

View File

@ -17,6 +17,7 @@ package org.teavm.eclipse.debugger;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IProcess;
@ -26,23 +27,15 @@ import org.eclipse.debug.core.model.IStreamsProxy;
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
@SuppressWarnings("rawtypes")
public class TeaVMDebugProcess implements IProcess {
private Map<String, String> attributes = new HashMap<>();
private ILaunch launch;
private TeaVMStreamsProxy streamsProxy = new TeaVMStreamsProxy();
public class TeaVMDebugProcess extends PlatformObject implements IProcess {
private TeaVMDebugTarget debugTarget;
private Map<String, String> attributes = new HashMap<>();
private TeaVMStreamsProxy streamsProxy = new TeaVMStreamsProxy();
public TeaVMDebugProcess(ILaunch launch, TeaVMDebugTarget debugTarget) {
this.launch = launch;
public TeaVMDebugProcess(TeaVMDebugTarget debugTarget) {
this.debugTarget = debugTarget;
}
@Override
public Object getAdapter(Class arg0) {
return null;
}
@Override
public boolean canTerminate() {
return debugTarget.canTerminate();
@ -73,11 +66,6 @@ public class TeaVMDebugProcess implements IProcess {
return "TeaVM debug process";
}
@Override
public ILaunch getLaunch() {
return launch;
}
@Override
public IStreamsProxy getStreamsProxy() {
return streamsProxy;
@ -87,4 +75,9 @@ public class TeaVMDebugProcess implements IProcess {
public void setAttribute(String attr, String value) {
attributes.put(attr, value);
}
@Override
public ILaunch getLaunch() {
return debugTarget.getLaunch();
}
}

View File

@ -17,10 +17,13 @@ package org.teavm.eclipse.debugger;
import static org.teavm.eclipse.debugger.TeaVMDebugConstants.DEBUG_TARGET_ID;
import static org.teavm.eclipse.debugger.TeaVMDebugConstants.JAVA_BREAKPOINT_INSTALL_COUNT;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
@ -37,18 +40,18 @@ import org.teavm.debugging.javascript.JavaScriptDebugger;
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
@SuppressWarnings("rawtypes")
public class TeaVMDebugTarget implements IDebugTarget, IStep {
public class TeaVMDebugTarget extends PlatformObject implements IDebugTarget, IStep {
ILaunch launch;
Debugger teavmDebugger;
JavaScriptDebugger jsDebugger;
private ChromeRDPServer server;
private volatile boolean terminated;
private TeaVMDebugProcess process;
private TeaVMThread thread;
private TeaVMJavaThread thread;
private TeaVMJSThread jsThread;
ConcurrentMap<IBreakpoint, Breakpoint> breakpointMap = new ConcurrentHashMap<>();
ConcurrentMap<Breakpoint, IJavaLineBreakpoint> breakpointBackMap = new ConcurrentHashMap<>();
private Map<String, Integer> instanceIdMap = new WeakHashMap<>();
public TeaVMDebugTarget(ILaunch launch, final Debugger teavmDebugger, JavaScriptDebugger jsDebugger,
ChromeRDPServer server) {
@ -56,8 +59,8 @@ public class TeaVMDebugTarget implements IDebugTarget, IStep {
this.teavmDebugger = teavmDebugger;
this.jsDebugger = jsDebugger;
this.server = server;
this.process = new TeaVMDebugProcess(launch, this);
this.thread = new TeaVMThread(this);
this.process = new TeaVMDebugProcess(this);
this.thread = new TeaVMJavaThread(this);
this.jsThread = new TeaVMJSThread(this);
DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this);
for (IBreakpoint breakpoint : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) {
@ -67,16 +70,30 @@ public class TeaVMDebugTarget implements IDebugTarget, IStep {
@Override
public void resumed() {
fireEvent(new DebugEvent(TeaVMDebugTarget.this, DebugEvent.RESUME));
thread.fireResumeEvent(0);
if (jsThread != null) {
jsThread.fireResumeEvent(0);
}
}
@Override
public void paused() {
fireEvent(new DebugEvent(TeaVMDebugTarget.this, DebugEvent.SUSPEND));
thread.fireSuspendEvent(0);
thread.fireChangeEvent(0);
if (jsThread != null) {
jsThread.fireSuspendEvent(0);
jsThread.fireChangeEvent(0);
}
}
@Override
public void detached() {
fireEvent(new DebugEvent(TeaVMDebugTarget.this, DebugEvent.CHANGE));
thread.fireChangeEvent(0);
if (jsThread != null) {
jsThread.fireChangeEvent(0);
}
for (Breakpoint teavmBreakpoint : teavmDebugger.getBreakpoints()) {
updateBreakpoint(teavmBreakpoint);
}
@ -132,19 +149,12 @@ public class TeaVMDebugTarget implements IDebugTarget, IStep {
public void terminate() throws DebugException {
terminated = true;
server.stop();
fireEvent(new DebugEvent(thread, DebugEvent.TERMINATE));
fireEvent(new DebugEvent(thread, DebugEvent.CHANGE));
fireEvent(new DebugEvent(jsThread, DebugEvent.TERMINATE));
fireEvent(new DebugEvent(jsThread, DebugEvent.CHANGE));
thread.fireTerminateEvent();
jsThread.fireTerminateEvent();
fireEvent(new DebugEvent(process, DebugEvent.TERMINATE));
fireEvent(new DebugEvent(this, DebugEvent.TERMINATE));
}
@Override
public Object getAdapter(Class arg0) {
return null;
}
@Override
public void breakpointAdded(IBreakpoint breakpoint) {
try {
@ -237,7 +247,7 @@ public class TeaVMDebugTarget implements IDebugTarget, IStep {
}
@Override
public String getName() throws DebugException {
public String getName() {
return "TeaVM debugger";
}
@ -295,4 +305,15 @@ public class TeaVMDebugTarget implements IDebugTarget, IStep {
public void stepReturn() throws DebugException {
thread.stepReturn();
}
public int getId(String instanceId) {
synchronized (instanceIdMap) {
Integer id = instanceIdMap.get(instanceId);
if (id == null) {
id = instanceIdMap.size();
instanceIdMap.put(instanceId, id);
}
return id;
}
}
}

View File

@ -0,0 +1,28 @@
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugException;
import org.teavm.debugging.javascript.JavaScriptValue;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMJSScope extends TeaVMVariable {
private String name;
private JavaScriptValue value;
public TeaVMJSScope(TeaVMDebugTarget debugTarget, String name, JavaScriptValue value) {
super(debugTarget, new TeaVMJSValue(debugTarget, value));
this.name = name;
}
@Override
public String getName() throws DebugException {
return name;
}
@Override
public String getReferenceTypeName() throws DebugException {
return value.getClassName();
}
}

View File

@ -16,138 +16,44 @@
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.*;
import org.teavm.debugging.javascript.JavaScriptCallFrame;
import org.teavm.debugging.javascript.JavaScriptDebugger;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMJSStackFrame implements IStackFrame {
TeaVMJSThread thread;
public class TeaVMJSStackFrame extends TeaVMStackFrame {
JavaScriptCallFrame callFrame;
JavaScriptDebugger jsDebugger;
private TeaVMJSVariablesHolder variablesHolder;
public TeaVMJSStackFrame(TeaVMJSThread thread, JavaScriptCallFrame callFrame) {
this.thread = thread;
public TeaVMJSStackFrame(TeaVMThread thread, JavaScriptDebugger jsDebugger, JavaScriptCallFrame callFrame) {
super(thread);
this.callFrame = callFrame;
this.variablesHolder = new TeaVMJSVariablesHolder(thread.debugTarget, callFrame.getVariables().values());
this.jsDebugger = jsDebugger;
this.variablesHolder = new TeaVMJSVariablesHolder(thread.debugTarget, callFrame.getVariables().values(),
callFrame.getThisVariable(), callFrame.getClosureVariable());
}
public JavaScriptCallFrame getCallFrame() {
return callFrame;
}
@Override
public boolean canTerminate() {
return thread.canTerminate();
}
@Override
public boolean isTerminated() {
return thread.isTerminated();
}
@Override
public void terminate() throws DebugException {
thread.terminate();
}
@Override
@SuppressWarnings("rawtypes")
public Object getAdapter(Class type) {
if (type.equals(ILaunch.class)) {
return thread.debugTarget.getLaunch();
} else if (type.equals(IDebugElement.class)) {
return this;
}
return null;
}
@Override
public boolean canStepInto() {
return thread.getTopStackFrame() == this;
}
@Override
public boolean canStepOver() {
return thread.getTopStackFrame() == this;
}
@Override
public boolean canStepReturn() {
return thread.getTopStackFrame() == this;
}
@Override
public boolean isStepping() {
return false;
}
@Override
public void stepInto() throws DebugException {
thread.stepInto();
jsDebugger.stepInto();
}
@Override
public void stepOver() throws DebugException {
thread.stepOver();
jsDebugger.stepOver();
}
@Override
public void stepReturn() throws DebugException {
thread.stepReturn();
}
@Override
public boolean canResume() {
return thread.getTopStackFrame() == this;
}
@Override
public boolean canSuspend() {
return thread.getTopStackFrame() == this;
}
@Override
public boolean isSuspended() {
return thread.isSuspended();
}
@Override
public void resume() throws DebugException {
thread.resume();
}
@Override
public void suspend() throws DebugException {
thread.suspend();
}
@Override
public IDebugTarget getDebugTarget() {
return thread.getDebugTarget();
}
@Override
public ILaunch getLaunch() {
return thread.getLaunch();
}
@Override
public String getModelIdentifier() {
return TeaVMDebugConstants.STACK_FRAME_ID;
}
@Override
public int getCharEnd() throws DebugException {
return -1;
}
@Override
public int getCharStart() throws DebugException {
return -1;
jsDebugger.stepOut();
}
@Override
@ -167,28 +73,8 @@ public class TeaVMJSStackFrame implements IStackFrame {
return sb.toString();
}
@Override
public IRegisterGroup[] getRegisterGroups() throws DebugException {
return null;
}
@Override
public IThread getThread() {
return thread;
}
@Override
public IVariable[] getVariables() throws DebugException {
return variablesHolder.getVariables();
}
@Override
public boolean hasRegisterGroups() throws DebugException {
return false;
}
@Override
public boolean hasVariables() throws DebugException {
return true;
}
}

View File

@ -17,12 +17,6 @@ package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.teavm.debugging.javascript.JavaScriptBreakpoint;
import org.teavm.debugging.javascript.JavaScriptCallFrame;
import org.teavm.debugging.javascript.JavaScriptDebugger;
@ -32,12 +26,11 @@ import org.teavm.debugging.javascript.JavaScriptDebuggerListener;
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMJSThread implements IThread {
public class TeaVMJSThread extends TeaVMThread {
private JavaScriptDebugger jsDebugger;
TeaVMDebugTarget debugTarget;
private volatile TeaVMJSStackFrame[] stackTrace;
public TeaVMJSThread(TeaVMDebugTarget debugTarget) {
super(debugTarget);
this.debugTarget = debugTarget;
this.jsDebugger = debugTarget.jsDebugger;
jsDebugger.addListener(new JavaScriptDebuggerListener() {
@ -66,7 +59,8 @@ public class TeaVMJSThread implements IThread {
});
}
private void updateStackTrace() {
@Override
protected void updateStackTrace() {
if (jsDebugger.getCallStack() == null) {
this.stackTrace = null;
} else {
@ -74,63 +68,13 @@ public class TeaVMJSThread implements IThread {
TeaVMJSStackFrame[] stackTrace = new TeaVMJSStackFrame[jsCallStack.length];
for (int i = 0; i < jsCallStack.length; ++i) {
JavaScriptCallFrame jsFrame = jsCallStack[i];
stackTrace[i] = new TeaVMJSStackFrame(this, jsFrame);
stackTrace[i] = new TeaVMJSStackFrame(this, jsDebugger, jsFrame);
}
this.stackTrace = stackTrace;
}
fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
}
private void fireEvent(DebugEvent event) {
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
}
@Override
public boolean canTerminate() {
return debugTarget.canTerminate();
}
@Override
public boolean isTerminated() {
return debugTarget.isTerminated();
}
@Override
public void terminate() throws DebugException {
debugTarget.terminate();
}
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class type) {
return null;
}
@Override
public boolean canResume() {
return debugTarget.canResume();
}
@Override
public boolean canSuspend() {
return debugTarget.canSuspend();
}
@Override
public boolean isSuspended() {
return jsDebugger.isSuspended();
}
@Override
public void resume() throws DebugException {
jsDebugger.resume();
}
@Override
public void suspend() throws DebugException {
jsDebugger.suspend();
}
@Override
public boolean canStepInto() {
return debugTarget.canStepInto();
@ -167,55 +111,22 @@ public class TeaVMJSThread implements IThread {
}
@Override
public IDebugTarget getDebugTarget() {
return debugTarget;
}
@Override
public ILaunch getLaunch() {
return debugTarget.launch;
}
@Override
public String getModelIdentifier() {
return TeaVMDebugConstants.THREAD_ID;
}
@Override
public IBreakpoint[] getBreakpoints() {
return debugTarget.breakpointMap.keySet().toArray(new IBreakpoint[0]);
}
@Override
public String getName() throws DebugException {
public String getName() {
return "JavaScript";
}
@Override
public int getPriority() throws DebugException {
return 0;
public boolean isSuspended() {
return jsDebugger.isSuspended();
}
@Override
public IStackFrame[] getStackFrames() throws DebugException {
if (isTerminated()) {
return new IStackFrame[0];
}
TeaVMJSStackFrame[] stackTrace = this.stackTrace;
return stackTrace != null ? stackTrace.clone() : new IStackFrame[0];
public void resume() throws DebugException {
jsDebugger.resume();
}
@Override
public IStackFrame getTopStackFrame() {
if (isTerminated()) {
return null;
}
TeaVMJSStackFrame[] stackTrace = this.stackTrace;
return stackTrace != null && stackTrace.length > 0 ? stackTrace[0] : null;
}
@Override
public boolean hasStackFrames() throws DebugException {
return !isTerminated() && stackTrace != null;
public void suspend() throws DebugException {
jsDebugger.suspend();
}
}

View File

@ -16,63 +16,34 @@
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.teavm.debugging.javascript.JavaScriptValue;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMJSValue implements IValue {
TeaVMDebugTarget debugTarget;
private JavaScriptValue teavmValue;
private TeaVMJSVariablesHolder variablesHolder;
public class TeaVMJSValue extends TeaVMValue {
private JavaScriptValue jsValue;
private boolean innerStructure;
public TeaVMJSValue(TeaVMDebugTarget debugTarget, JavaScriptValue teavmValue) {
this.debugTarget = debugTarget;
this.teavmValue = teavmValue;
super(debugTarget, new TeaVMJSVariablesHolder(debugTarget, teavmValue.getProperties().values(), null, null));
this.jsValue = teavmValue;
this.innerStructure = teavmValue.hasInnerStructure();
this.variablesHolder = new TeaVMJSVariablesHolder(debugTarget, teavmValue.getProperties().values());
}
@Override
public IDebugTarget getDebugTarget() {
return debugTarget;
}
@Override
public ILaunch getLaunch() {
return debugTarget.getLaunch();
}
@Override
public String getModelIdentifier() {
return TeaVMDebugConstants.VALUE_ID;
}
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class arg0) {
return null;
}
@Override
public String getReferenceTypeName() throws DebugException {
return teavmValue.getClassName();
return jsValue.getClassName();
}
@Override
public String getValueString() throws DebugException {
return teavmValue.getRepresentation();
}
@Override
public IVariable[] getVariables() throws DebugException {
return variablesHolder.getVariables();
if (jsValue.getInstanceId() != null) {
return jsValue.getClassName() + " (id: " + getDebugTarget().getId(jsValue.getInstanceId()) + ")";
} else {
return jsValue.getRepresentation();
}
}
@Override
@ -80,8 +51,12 @@ public class TeaVMJSValue implements IValue {
return innerStructure;
}
public JavaScriptValue getJavaScriptValue() {
return jsValue;
}
@Override
public boolean isAllocated() throws DebugException {
return true;
public String getDescription() {
return jsValue.getRepresentation();
}
}

View File

@ -15,74 +15,19 @@
*/
package org.teavm.eclipse.debugger;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.teavm.debugging.javascript.JavaScriptVariable;
import org.teavm.eclipse.TeaVMEclipsePlugin;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMJSVariable implements IVariable {
private TeaVMDebugTarget debugTarget;
public class TeaVMJSVariable extends TeaVMVariable {
private JavaScriptVariable var;
private TeaVMJSValue value;
public TeaVMJSVariable(TeaVMDebugTarget debugTarget, JavaScriptVariable var) {
this.debugTarget = debugTarget;
super(debugTarget, new TeaVMJSValue(debugTarget, var.getValue()));
this.var = var;
this.value = new TeaVMJSValue(debugTarget, var.getValue());
}
@Override
public void setValue(IValue arg0) throws DebugException {
throw new DebugException(new Status(Status.ERROR, TeaVMEclipsePlugin.ID, "Can't set value"));
}
@Override
public void setValue(String arg0) throws DebugException {
throw new DebugException(new Status(Status.ERROR, TeaVMEclipsePlugin.ID, "Can't set value"));
}
@Override
public boolean supportsValueModification() {
return false;
}
@Override
public boolean verifyValue(IValue arg0) throws DebugException {
return false;
}
@Override
public boolean verifyValue(String arg0) throws DebugException {
return false;
}
@Override
public IDebugTarget getDebugTarget() {
return debugTarget;
}
@Override
public ILaunch getLaunch() {
return debugTarget.getLaunch();
}
@Override
public String getModelIdentifier() {
return TeaVMDebugConstants.VARIABLE_ID;
}
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class arg0) {
return null;
}
@Override
@ -94,14 +39,4 @@ public class TeaVMJSVariable implements IVariable {
public String getReferenceTypeName() throws DebugException {
return var.getValue().getClassName();
}
@Override
public IValue getValue() throws DebugException {
return value;
}
@Override
public boolean hasValueChanged() throws DebugException {
return false;
}
}

View File

@ -16,37 +16,45 @@
package org.teavm.eclipse.debugger;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import org.teavm.debugging.javascript.JavaScriptValue;
import org.teavm.debugging.javascript.JavaScriptVariable;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMJSVariablesHolder {
public class TeaVMJSVariablesHolder extends TeaVMVariablesHolder {
private TeaVMDebugTarget debugTarget;
private Collection<JavaScriptVariable> teavmVariables;
private AtomicReference<TeaVMJSVariable[]> variables = new AtomicReference<>();
private JavaScriptValue thisScope;
private JavaScriptValue closureScope;
public TeaVMJSVariablesHolder(TeaVMDebugTarget debugTarget, Collection<JavaScriptVariable> teavmVariables) {
public TeaVMJSVariablesHolder(TeaVMDebugTarget debugTarget, Collection<JavaScriptVariable> teavmVariables,
JavaScriptValue thisScope, JavaScriptValue closureScope) {
this.debugTarget = debugTarget;
this.teavmVariables = teavmVariables;
this.thisScope = thisScope;
this.closureScope = closureScope;
}
public TeaVMJSVariable[] getVariables() {
if (variables.get() == null) {
TeaVMJSVariable[] newVariables = new TeaVMJSVariable[teavmVariables.size()];
List<JavaScriptVariable> teavmVarList = new ArrayList<>(teavmVariables);
Collections.sort(teavmVarList, new Comparator<JavaScriptVariable>() {
@Override public int compare(JavaScriptVariable o1, JavaScriptVariable o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (int i = 0; i < teavmVarList.size(); ++i) {
newVariables[i] = new TeaVMJSVariable(debugTarget, teavmVarList.get(i));
}
variables.compareAndSet(null, newVariables);
@Override
protected TeaVMVariable[] createVariables() {
List<TeaVMVariable> variables = new ArrayList<>();
if (thisScope != null) {
variables.add(new TeaVMJSScope(debugTarget, "this", thisScope));
}
return variables.get();
if (closureScope != null) {
variables.add(new TeaVMJSScope(debugTarget, "<closure>", closureScope));
}
List<JavaScriptVariable> teavmVarList = new ArrayList<>(teavmVariables);
Collections.sort(teavmVarList, new Comparator<JavaScriptVariable>() {
@Override public int compare(JavaScriptVariable o1, JavaScriptVariable o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (int i = 0; i < teavmVarList.size(); ++i) {
variables.add(new TeaVMJSVariable(debugTarget, teavmVarList.get(i)));
}
return variables.toArray(new TeaVMVariable[0]);
}
}

View File

@ -0,0 +1,79 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IVariable;
import org.teavm.debugging.CallFrame;
import org.teavm.debugging.Debugger;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMJavaStackFrame extends TeaVMStackFrame {
Debugger teavmDebugger;
CallFrame callFrame;
private TeaVMJavaVariablesHolder variablesHolder;
public TeaVMJavaStackFrame(TeaVMThread thread, Debugger teavmDebugger, CallFrame callFrame) {
super(thread);
this.callFrame = callFrame;
this.teavmDebugger = teavmDebugger;
this.variablesHolder = new TeaVMJavaVariablesHolder(thread.debugTarget, callFrame.getVariables().values());
}
public CallFrame getCallFrame() {
return callFrame;
}
@Override
public void stepInto() throws DebugException {
teavmDebugger.stepInto();
}
@Override
public void stepOver() throws DebugException {
teavmDebugger.stepOver();
}
@Override
public void stepReturn() throws DebugException {
teavmDebugger.stepOut();
}
@Override
public int getLineNumber() throws DebugException {
return callFrame.getLocation() != null && callFrame.getLocation().getLine() >= 0 ?
callFrame.getLocation().getLine() : callFrame.getOriginalLocation().getLine() + 1;
}
@Override
public String getName() {
StringBuilder sb = new StringBuilder();
String fileName = callFrame.getLocation() != null ? callFrame.getLocation().getFileName() : null;
sb.append(fileName != null ? fileName : "unknown");
if (callFrame.getLocation() != null) {
sb.append(":").append(callFrame.getLocation().getLine());
}
return sb.toString();
}
@Override
public IVariable[] getVariables() throws DebugException {
return variablesHolder.getVariables();
}
}

View File

@ -0,0 +1,118 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.teavm.debugging.Breakpoint;
import org.teavm.debugging.CallFrame;
import org.teavm.debugging.Debugger;
import org.teavm.debugging.DebuggerListener;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMJavaThread extends TeaVMThread {
private Debugger teavmDebugger;
public TeaVMJavaThread(TeaVMDebugTarget debugTarget) {
super(debugTarget);
this.teavmDebugger = debugTarget.teavmDebugger;
this.teavmDebugger.addListener(new DebuggerListener() {
@Override
public void resumed() {
updateStackTrace();
fireEvent(new DebugEvent(TeaVMJavaThread.this, DebugEvent.RESUME));
}
@Override
public void paused() {
updateStackTrace();
fireEvent(new DebugEvent(TeaVMJavaThread.this, DebugEvent.SUSPEND));
}
@Override
public void detached() {
}
@Override
public void breakpointStatusChanged(Breakpoint breakpoint) {
}
@Override
public void attached() {
}
});
}
@Override
protected void updateStackTrace() {
if (teavmDebugger.getCallStack() == null) {
this.stackTrace = null;
} else {
CallFrame[] teavmCallStack = teavmDebugger.getCallStack();
TeaVMStackFrame[] stackTrace = new TeaVMStackFrame[teavmCallStack.length];
for (int i = 0; i < teavmCallStack.length; ++i) {
CallFrame teavmFrame = teavmCallStack[i];
if (teavmFrame.getLocation() != null && teavmFrame.getLocation().getFileName() != null) {
stackTrace[i] = new TeaVMJavaStackFrame(this, teavmDebugger, teavmFrame);
} else {
stackTrace[i] = new TeaVMJSStackFrame(this, teavmDebugger.getJavaScriptDebugger(),
teavmFrame.getOriginalCallFrame());
}
}
this.stackTrace = stackTrace;
}
fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
}
@Override
public boolean isSuspended() {
return teavmDebugger.isSuspended();
}
@Override
public void resume() throws DebugException {
teavmDebugger.resume();
}
@Override
public void suspend() throws DebugException {
teavmDebugger.suspend();
}
@Override
public void stepInto() throws DebugException {
teavmDebugger.stepInto();
}
@Override
public void stepOver() throws DebugException {
teavmDebugger.stepOver();
}
@Override
public void stepReturn() throws DebugException {
teavmDebugger.stepOut();
}
@Override
public String getName() {
return "main";
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugException;
import org.teavm.debugging.Value;
/**
*
* @author Alexey Andreev
*/
public class TeaVMJavaValue extends TeaVMValue {
private Value teavmValue;
private boolean innerStructure;
public TeaVMJavaValue(TeaVMDebugTarget debugTarget, Value teavmValue) {
super(debugTarget, new TeaVMJavaVariablesHolder(debugTarget, teavmValue.getProperties().values()));
this.teavmValue = teavmValue;
this.innerStructure = teavmValue.hasInnerStructure();
}
public Value getTeavmValue() {
return teavmValue;
}
@Override
public String getReferenceTypeName() throws DebugException {
return teavmValue.getType();
}
@Override
public String getValueString() throws DebugException {
if (teavmValue.getInstanceId() != null) {
return teavmValue.getType() + " (id: " + getDebugTarget().getId(teavmValue.getInstanceId()) + ")";
} else {
return teavmValue.getRepresentation();
}
}
@Override
public boolean hasVariables() throws DebugException {
return innerStructure;
}
@Override
public String getDescription() {
return teavmValue.getRepresentation();
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugException;
import org.teavm.debugging.Variable;
/**
*
* @author Alexey Andreev
*/
public class TeaVMJavaVariable extends TeaVMVariable {
private Variable var;
public TeaVMJavaVariable(TeaVMDebugTarget debugTarget, Variable var) {
super(debugTarget, new TeaVMJavaValue(debugTarget, var.getValue()));
this.var = var;
}
@Override
public String getName() throws DebugException {
return var.getName();
}
@Override
public String getReferenceTypeName() throws DebugException {
return var.getValue().getType();
}
}

View File

@ -0,0 +1,48 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import java.util.*;
import org.teavm.debugging.Variable;
/**
*
* @author Alexey Andreev
*/
public class TeaVMJavaVariablesHolder extends TeaVMVariablesHolder {
private TeaVMDebugTarget debugTarget;
private Collection<Variable> teavmVariables;
public TeaVMJavaVariablesHolder(TeaVMDebugTarget debugTarget, Collection<Variable> teavmVariables) {
this.debugTarget = debugTarget;
this.teavmVariables = teavmVariables;
}
@Override
protected TeaVMVariable[] createVariables() {
TeaVMJavaVariable[] newVariables = new TeaVMJavaVariable[teavmVariables.size()];
List<Variable> teavmVarList = new ArrayList<>(teavmVariables);
Collections.sort(teavmVarList, new Comparator<Variable>() {
@Override public int compare(Variable o1, Variable o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (int i = 0; i < teavmVarList.size(); ++i) {
newVariables[i] = new TeaVMJavaVariable(debugTarget, teavmVarList.get(i));
}
return newVariables;
}
}

View File

@ -20,7 +20,7 @@ import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.ILaunchConfigurationDelegate;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.teavm.chromerdp.ChromeRDPDebugger;
import org.teavm.chromerdp.ChromeRDPServer;
import org.teavm.debugging.Debugger;
@ -30,7 +30,7 @@ import org.teavm.debugging.information.URLDebugInformationProvider;
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMLaunchConfigurationDelegate implements ILaunchConfigurationDelegate {
public class TeaVMLaunchConfigurationDelegate extends LaunchConfigurationDelegate {
@Override
public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor)
throws CoreException {

View File

@ -50,8 +50,8 @@ public class TeaVMSourceLookupParticipant extends AbstractSourceLookupParticipan
@Override
public String getSourceName(Object object) throws CoreException {
if (object instanceof TeaVMStackFrame) {
TeaVMStackFrame stackFrame = (TeaVMStackFrame)object;
if (object instanceof TeaVMJavaStackFrame) {
TeaVMJavaStackFrame stackFrame = (TeaVMJavaStackFrame)object;
SourceLocation location = stackFrame.callFrame.getLocation();
if (location != null) {
return location.getFileName();
@ -76,8 +76,8 @@ public class TeaVMSourceLookupParticipant extends AbstractSourceLookupParticipan
if (location != null) {
addUrlElement(result, location);
}
} else if (object instanceof TeaVMStackFrame) {
TeaVMStackFrame stackFrame = (TeaVMStackFrame)object;
} else if (object instanceof TeaVMJavaStackFrame) {
TeaVMJavaStackFrame stackFrame = (TeaVMJavaStackFrame)object;
CallFrame callFrame = stackFrame.getCallFrame();
if (callFrame.getMethod() == null && callFrame.getLocation() != null) {
addUrlElement(result, callFrame.getOriginalLocation());

View File

@ -1,42 +1,18 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.*;
import org.teavm.debugging.CallFrame;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMStackFrame implements IStackFrame {
public abstract class TeaVMStackFrame extends TeaVMDebugElement implements IStackFrame {
TeaVMThread thread;
CallFrame callFrame;
private TeaVMVariablesHolder variablesHolder;
public TeaVMStackFrame(TeaVMThread thread, CallFrame callFrame) {
public TeaVMStackFrame(TeaVMThread thread) {
super(thread.getDebugTarget());
this.thread = thread;
this.callFrame = callFrame;
this.variablesHolder = new TeaVMVariablesHolder(thread.debugTarget, callFrame.getVariables().values());
}
public CallFrame getCallFrame() {
return callFrame;
}
@Override
@ -54,16 +30,6 @@ public class TeaVMStackFrame implements IStackFrame {
thread.terminate();
}
@Override
public Object getAdapter(@SuppressWarnings("rawtypes") Class type) {
if (type.equals(ILaunch.class)) {
return thread.debugTarget.getLaunch();
} else if (type.equals(IDebugElement.class)) {
return this;
}
return null;
}
@Override
public boolean canStepInto() {
return thread.getTopStackFrame() == this;
@ -84,21 +50,6 @@ public class TeaVMStackFrame implements IStackFrame {
return false;
}
@Override
public void stepInto() throws DebugException {
thread.stepInto();
}
@Override
public void stepOver() throws DebugException {
thread.stepOver();
}
@Override
public void stepReturn() throws DebugException {
thread.stepReturn();
}
@Override
public boolean canResume() {
return thread.getTopStackFrame() == this;
@ -124,21 +75,6 @@ public class TeaVMStackFrame implements IStackFrame {
thread.suspend();
}
@Override
public IDebugTarget getDebugTarget() {
return thread.getDebugTarget();
}
@Override
public ILaunch getLaunch() {
return thread.getLaunch();
}
@Override
public String getModelIdentifier() {
return TeaVMDebugConstants.STACK_FRAME_ID;
}
@Override
public int getCharEnd() throws DebugException {
return -1;
@ -149,23 +85,6 @@ public class TeaVMStackFrame implements IStackFrame {
return -1;
}
@Override
public int getLineNumber() throws DebugException {
return callFrame.getLocation() != null && callFrame.getLocation().getLine() >= 0 ?
callFrame.getLocation().getLine() : callFrame.getOriginalLocation().getLine() + 1;
}
@Override
public String getName() {
StringBuilder sb = new StringBuilder();
String fileName = callFrame.getLocation() != null ? callFrame.getLocation().getFileName() : null;
sb.append(fileName != null ? fileName : "unknown");
if (callFrame.getLocation() != null) {
sb.append(":").append(callFrame.getLocation().getLine());
}
return sb.toString();
}
@Override
public IRegisterGroup[] getRegisterGroups() throws DebugException {
return null;
@ -176,11 +95,6 @@ public class TeaVMStackFrame implements IStackFrame {
return thread;
}
@Override
public IVariable[] getVariables() throws DebugException {
return variablesHolder.getVariables();
}
@Override
public boolean hasRegisterGroups() throws DebugException {
return false;

View File

@ -1,89 +1,23 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.teavm.debugging.Breakpoint;
import org.teavm.debugging.CallFrame;
import org.teavm.debugging.Debugger;
import org.teavm.debugging.DebuggerListener;
import org.eclipse.debug.core.model.*;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMThread implements IThread {
private Debugger teavmDebugger;
public abstract class TeaVMThread extends TeaVMDebugElement implements IThread {
TeaVMDebugTarget debugTarget;
private volatile TeaVMStackFrame[] stackTrace;
protected volatile TeaVMStackFrame[] stackTrace;
public TeaVMThread(TeaVMDebugTarget debugTarget) {
super(debugTarget);
this.debugTarget = debugTarget;
this.teavmDebugger = debugTarget.teavmDebugger;
this.teavmDebugger.addListener(new DebuggerListener() {
@Override
public void resumed() {
updateStackTrace();
fireEvent(new DebugEvent(TeaVMThread.this, DebugEvent.RESUME));
}
@Override
public void paused() {
updateStackTrace();
fireEvent(new DebugEvent(TeaVMThread.this, DebugEvent.SUSPEND));
}
@Override
public void detached() {
}
@Override
public void breakpointStatusChanged(Breakpoint breakpoint) {
}
@Override
public void attached() {
}
});
}
private void updateStackTrace() {
if (teavmDebugger.getCallStack() == null) {
this.stackTrace = null;
} else {
CallFrame[] teavmCallStack = teavmDebugger.getCallStack();
TeaVMStackFrame[] stackTrace = new TeaVMStackFrame[teavmCallStack.length];
for (int i = 0; i < teavmCallStack.length; ++i) {
CallFrame teavmFrame = teavmCallStack[i];
stackTrace[i] = new TeaVMStackFrame(this, teavmFrame);
}
this.stackTrace = stackTrace;
}
fireEvent(new DebugEvent(this, DebugEvent.CHANGE));
}
private void fireEvent(DebugEvent event) {
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
protected void updateStackTrace() {
fireChangeEvent(0);
}
@Override
@ -101,12 +35,6 @@ public class TeaVMThread implements IThread {
debugTarget.terminate();
}
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class type) {
return null;
}
@Override
public boolean canResume() {
return debugTarget.canResume();
@ -117,21 +45,6 @@ public class TeaVMThread implements IThread {
return debugTarget.canSuspend();
}
@Override
public boolean isSuspended() {
return teavmDebugger.isSuspended();
}
@Override
public void resume() throws DebugException {
teavmDebugger.resume();
}
@Override
public void suspend() throws DebugException {
teavmDebugger.suspend();
}
@Override
public boolean canStepInto() {
return debugTarget.canStepInto();
@ -152,53 +65,21 @@ public class TeaVMThread implements IThread {
return debugTarget.isStepping();
}
@Override
public void stepInto() throws DebugException {
teavmDebugger.stepInto();
}
@Override
public void stepOver() throws DebugException {
teavmDebugger.stepOver();
}
@Override
public void stepReturn() throws DebugException {
teavmDebugger.stepOut();
}
@Override
public IDebugTarget getDebugTarget() {
return debugTarget;
}
@Override
public ILaunch getLaunch() {
return debugTarget.launch;
}
@Override
public String getModelIdentifier() {
return TeaVMDebugConstants.THREAD_ID;
}
@Override
public IBreakpoint[] getBreakpoints() {
return debugTarget.breakpointMap.keySet().toArray(new IBreakpoint[0]);
}
@Override
public String getName() throws DebugException {
return "main";
}
@Override
public int getPriority() throws DebugException {
public int getPriority() {
return 0;
}
@Override
public IStackFrame[] getStackFrames() throws DebugException {
public abstract String getName();
@Override
public IStackFrame[] getStackFrames() {
if (isTerminated()) {
return new IStackFrame[0];
}

View File

@ -1,73 +1,19 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.teavm.debugging.Value;
/**
*
* @author Alexey Andreev
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMValue implements IValue {
TeaVMDebugTarget debugTarget;
private Value teavmValue;
public abstract class TeaVMValue extends TeaVMDebugElement implements IValue {
private TeaVMVariablesHolder variablesHolder;
private boolean innerStructure;
public TeaVMValue(TeaVMDebugTarget debugTarget, Value teavmValue) {
this.debugTarget = debugTarget;
this.teavmValue = teavmValue;
this.innerStructure = teavmValue.hasInnerStructure();
this.variablesHolder = new TeaVMVariablesHolder(debugTarget, teavmValue.getProperties().values());
}
@Override
public IDebugTarget getDebugTarget() {
return debugTarget;
}
@Override
public ILaunch getLaunch() {
return debugTarget.getLaunch();
}
@Override
public String getModelIdentifier() {
return TeaVMDebugConstants.VALUE_ID;
}
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class arg0) {
return null;
}
@Override
public String getReferenceTypeName() throws DebugException {
return teavmValue.getType();
}
@Override
public String getValueString() throws DebugException {
return teavmValue.getRepresentation();
public TeaVMValue(TeaVMDebugTarget debugTarget, TeaVMVariablesHolder variablesHolder) {
super(debugTarget);
this.variablesHolder = variablesHolder;
}
@Override
@ -75,13 +21,10 @@ public class TeaVMValue implements IValue {
return variablesHolder.getVariables();
}
@Override
public boolean hasVariables() throws DebugException {
return innerStructure;
}
@Override
public boolean isAllocated() throws DebugException {
return true;
}
public abstract String getDescription();
}

View File

@ -1,51 +1,30 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;
import org.teavm.debugging.Variable;
import org.teavm.eclipse.TeaVMEclipsePlugin;
/**
*
* @author Alexey Andreev
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMVariable implements IVariable {
private TeaVMDebugTarget debugTarget;
private Variable var;
public abstract class TeaVMVariable extends TeaVMDebugElement implements IVariable {
private TeaVMValue value;
public TeaVMVariable(TeaVMDebugTarget debugTarget, Variable var) {
this.debugTarget = debugTarget;
this.var = var;
this.value = new TeaVMValue(debugTarget, var.getValue());
public TeaVMVariable(TeaVMDebugTarget debugTarget, TeaVMValue value) {
super(debugTarget);
this.value = value;
}
@Override
public void setValue(IValue arg0) throws DebugException {
public void setValue(IValue value) throws DebugException {
throw new DebugException(new Status(Status.ERROR, TeaVMEclipsePlugin.ID, "Can't set value"));
}
@Override
public void setValue(String arg0) throws DebugException {
public void setValue(String value) throws DebugException {
throw new DebugException(new Status(Status.ERROR, TeaVMEclipsePlugin.ID, "Can't set value"));
}
@ -55,48 +34,17 @@ public class TeaVMVariable implements IVariable {
}
@Override
public boolean verifyValue(IValue arg0) throws DebugException {
public boolean verifyValue(IValue value) throws DebugException {
return false;
}
@Override
public boolean verifyValue(String arg0) throws DebugException {
public boolean verifyValue(String value) throws DebugException {
return false;
}
@Override
public IDebugTarget getDebugTarget() {
return debugTarget;
}
@Override
public ILaunch getLaunch() {
return debugTarget.getLaunch();
}
@Override
public String getModelIdentifier() {
return TeaVMDebugConstants.VARIABLE_ID;
}
@SuppressWarnings("rawtypes")
@Override
public Object getAdapter(Class arg0) {
return null;
}
@Override
public String getName() throws DebugException {
return var.getName();
}
@Override
public String getReferenceTypeName() throws DebugException {
return var.getValue().getType();
}
@Override
public IValue getValue() throws DebugException {
public TeaVMValue getValue(){
return value;
}

View File

@ -1,52 +1,20 @@
/*
* Copyright 2014 Alexey Andreev.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.teavm.eclipse.debugger;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import org.teavm.debugging.Variable;
/**
*
* @author Alexey Andreev
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMVariablesHolder {
private TeaVMDebugTarget debugTarget;
private Collection<Variable> teavmVariables;
public abstract class TeaVMVariablesHolder {
private AtomicReference<TeaVMVariable[]> variables = new AtomicReference<>();
public TeaVMVariablesHolder(TeaVMDebugTarget debugTarget, Collection<Variable> teavmVariables) {
this.debugTarget = debugTarget;
this.teavmVariables = teavmVariables;
}
public TeaVMVariable[] getVariables() {
if (variables.get() == null) {
TeaVMVariable[] newVariables = new TeaVMVariable[teavmVariables.size()];
List<Variable> teavmVarList = new ArrayList<>(teavmVariables);
Collections.sort(teavmVarList, new Comparator<Variable>() {
@Override public int compare(Variable o1, Variable o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (int i = 0; i < teavmVarList.size(); ++i) {
newVariables[i] = new TeaVMVariable(debugTarget, teavmVarList.get(i));
}
variables.compareAndSet(null, newVariables);
variables.compareAndSet(null, createVariables());
}
return variables.get();
}
protected abstract TeaVMVariable[] createVariables();
}

View File

@ -33,10 +33,11 @@ import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.part.FileEditorInput;
import org.teavm.debugging.CallFrame;
import org.teavm.debugging.Value;
import org.teavm.debugging.javascript.JavaScriptCallFrame;
import org.teavm.debugging.javascript.JavaScriptLocation;
import org.teavm.eclipse.debugger.TeaVMJSStackFrame;
import org.teavm.eclipse.debugger.TeaVMStackFrame;
import org.teavm.debugging.javascript.JavaScriptValue;
import org.teavm.eclipse.debugger.*;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReference;
import org.teavm.model.ValueType;
@ -80,25 +81,66 @@ public class TeaVMDebugModelPresentation extends LabelProvider implements IDebug
}
@Override
public void computeDetail(IValue arg0, IValueDetailListener arg1) {
public void computeDetail(IValue value, IValueDetailListener listener) {
if (value instanceof TeaVMValue) {
String description = ((TeaVMValue)value).getDescription();
listener.detailComputed(value, description);
} else {
listener.detailComputed(value, "");
}
}
@Override
public void setAttribute(String arg0, Object arg1) {
public void setAttribute(String attr, Object value) {
}
@Override
public String getText(Object element) {
if (element instanceof TeaVMStackFrame) {
TeaVMStackFrame stackFrame = (TeaVMStackFrame)element;
System.out.println(element.getClass().getName());
if (element instanceof TeaVMJavaStackFrame) {
TeaVMJavaStackFrame stackFrame = (TeaVMJavaStackFrame)element;
return callFrameAsString(stackFrame.getCallFrame());
} else if (element instanceof TeaVMJSStackFrame) {
TeaVMJSStackFrame stackFrame = (TeaVMJSStackFrame)element;
return callFrameAsString(stackFrame.getCallFrame());
} else if (element instanceof TeaVMJavaVariable) {
TeaVMJavaVariable var = (TeaVMJavaVariable)element;
return getText((TeaVMJavaValue)var.getValue());
} else if (element instanceof TeaVMJavaValue) {
return getText((TeaVMJavaValue)element);
} else if (element instanceof TeaVMJSVariable) {
TeaVMJSVariable var = (TeaVMJSVariable)element;
return getText((TeaVMJSValue)var.getValue());
} else if (element instanceof TeaVMJSValue) {
return getText((TeaVMJSValue)element);
} else if (element instanceof TeaVMDebugTarget) {
return ((TeaVMDebugTarget)element).getName();
} else if (element instanceof TeaVMThread) {
return ((TeaVMThread)element).getName();
}
return super.getText(element);
}
private String getText(TeaVMJavaValue value) {
TeaVMDebugTarget debugTarget = value.getDebugTarget();
Value teavmValue = value.getTeavmValue();
if (teavmValue.getInstanceId() == null) {
return teavmValue.getType() + " (id: " + debugTarget.getId(teavmValue.getInstanceId()) + ")";
} else {
return teavmValue.getRepresentation();
}
}
private String getText(TeaVMJSValue value) {
TeaVMDebugTarget debugTarget = value.getDebugTarget();
JavaScriptValue jsValue = value.getJavaScriptValue();
if (jsValue.getInstanceId() == null) {
return jsValue.getClassName() + " (id: " + debugTarget.getId(jsValue.getInstanceId()) + ")";
} else {
return jsValue.getRepresentation();
}
}
private String callFrameAsString(CallFrame callFrame) {
MethodReference method = callFrame.getMethod();
if (method == null) {