diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPDebugger.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPDebugger.java index 79b934ff1..9cb2202fe 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPDebugger.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/ChromeRDPDebugger.java @@ -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) { diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPCallFrame.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPCallFrame.java index 150187ded..352a1a0e4 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPCallFrame.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPCallFrame.java @@ -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 variables; + private JavaScriptValue thisObject; + private JavaScriptValue closure; - public RDPCallFrame(String chromeId, JavaScriptLocation location, - Map variables) { + public RDPCallFrame(JavaScriptDebugger debugger, String chromeId, JavaScriptLocation location, + Map 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 getVariables() { return variables; } + + @Override + public JavaScriptDebugger getDebugger() { + return debugger; + } + + @Override + public JavaScriptValue getThisVariable() { + return thisObject; + } + + @Override + public JavaScriptValue getClosureVariable() { + return closure; + } } diff --git a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPValue.java b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPValue.java index 6918a9b48..24d695a7e 100644 --- a/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPValue.java +++ b/teavm-chrome-rdp/src/main/java/org/teavm/chromerdp/RDPValue.java @@ -76,4 +76,9 @@ public class RDPValue implements JavaScriptValue { public boolean hasInnerStructure() { return innerStructure; } + + @Override + public String getInstanceId() { + return objectId; + } } diff --git a/teavm-core/src/main/java/org/teavm/debugging/CallFrame.java b/teavm-core/src/main/java/org/teavm/debugging/CallFrame.java index 9787a1925..58f85195d 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/CallFrame.java +++ b/teavm-core/src/main/java/org/teavm/debugging/CallFrame.java @@ -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 variables; - CallFrame(JavaScriptLocation originalLocation, SourceLocation location, MethodReference method, + CallFrame(Debugger debugger, JavaScriptCallFrame originalFrame, SourceLocation location, MethodReference method, Map 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() { diff --git a/teavm-core/src/main/java/org/teavm/debugging/Debugger.java b/teavm-core/src/main/java/org/teavm/debugging/Debugger.java index ee62ae067..a6e757e77 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/Debugger.java +++ b/teavm-core/src/main/java/org/teavm/debugging/Debugger.java @@ -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 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; } diff --git a/teavm-core/src/main/java/org/teavm/debugging/Value.java b/teavm-core/src/main/java/org/teavm/debugging/Value.java index 84ab319eb..fa8d4df15 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/Value.java +++ b/teavm-core/src/main/java/org/teavm/debugging/Value.java @@ -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(); + } } diff --git a/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptCallFrame.java b/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptCallFrame.java index 87a2eb9bc..e18748192 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptCallFrame.java +++ b/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptCallFrame.java @@ -22,7 +22,13 @@ import java.util.Map; * @author Alexey Andreev */ public interface JavaScriptCallFrame { + JavaScriptDebugger getDebugger(); + JavaScriptLocation getLocation(); Map getVariables(); + + JavaScriptValue getThisVariable(); + + JavaScriptValue getClosureVariable(); } diff --git a/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptValue.java b/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptValue.java index d1e069d31..1047fe5c0 100644 --- a/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptValue.java +++ b/teavm-core/src/main/java/org/teavm/debugging/javascript/JavaScriptValue.java @@ -29,4 +29,6 @@ public interface JavaScriptValue { Map getProperties(); boolean hasInnerStructure(); + + String getInstanceId(); } diff --git a/teavm-eclipse/teavm-eclipse-plugin/plugin.xml b/teavm-eclipse/teavm-eclipse-plugin/plugin.xml index b48137e1c..1b78c5488 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/plugin.xml +++ b/teavm-eclipse/teavm-eclipse-plugin/plugin.xml @@ -42,7 +42,7 @@ + id="org.teavm.eclipse.debugger"> \ No newline at end of file diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugConstants.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugConstants.java index 621338dc2..0681bdd53 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugConstants.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugConstants.java @@ -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"; } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugElement.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugElement.java new file mode 100644 index 000000000..adbd2b31b --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugElement.java @@ -0,0 +1,23 @@ +package org.teavm.eclipse.debugger; + +import org.eclipse.debug.core.model.DebugElement; + +/** + * + * @author Alexey Andreev + */ +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(); + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java index c55d06378..05e4240ab 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java @@ -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 */ -@SuppressWarnings("rawtypes") -public class TeaVMDebugProcess implements IProcess { - private Map attributes = new HashMap<>(); - private ILaunch launch; - private TeaVMStreamsProxy streamsProxy = new TeaVMStreamsProxy(); +public class TeaVMDebugProcess extends PlatformObject implements IProcess { private TeaVMDebugTarget debugTarget; + private Map 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(); + } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java index d65490c21..91b84b97c 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java @@ -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 */ -@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 breakpointMap = new ConcurrentHashMap<>(); ConcurrentMap breakpointBackMap = new ConcurrentHashMap<>(); + private Map 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; + } + } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSScope.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSScope.java new file mode 100644 index 000000000..7307ba286 --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSScope.java @@ -0,0 +1,28 @@ +package org.teavm.eclipse.debugger; + +import org.eclipse.debug.core.DebugException; +import org.teavm.debugging.javascript.JavaScriptValue; + +/** + * + * @author Alexey Andreev + */ +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(); + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSStackFrame.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSStackFrame.java index 8e8fb8318..b628d74bb 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSStackFrame.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSStackFrame.java @@ -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 */ -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; - } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSThread.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSThread.java index 13cd5c5fd..4fb9d56cf 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSThread.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSThread.java @@ -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 */ -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(); } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSValue.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSValue.java index 087e82662..465580a1a 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSValue.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSValue.java @@ -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 */ -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(); } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariable.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariable.java index 27f65387a..047c9fabb 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariable.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariable.java @@ -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 */ -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; - } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariablesHolder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariablesHolder.java index e79690cee..63e082110 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariablesHolder.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJSVariablesHolder.java @@ -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 */ -public class TeaVMJSVariablesHolder { +public class TeaVMJSVariablesHolder extends TeaVMVariablesHolder { private TeaVMDebugTarget debugTarget; private Collection teavmVariables; - private AtomicReference variables = new AtomicReference<>(); + private JavaScriptValue thisScope; + private JavaScriptValue closureScope; - public TeaVMJSVariablesHolder(TeaVMDebugTarget debugTarget, Collection teavmVariables) { + public TeaVMJSVariablesHolder(TeaVMDebugTarget debugTarget, Collection 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 teavmVarList = new ArrayList<>(teavmVariables); - Collections.sort(teavmVarList, new Comparator() { - @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 variables = new ArrayList<>(); + if (thisScope != null) { + variables.add(new TeaVMJSScope(debugTarget, "this", thisScope)); } - return variables.get(); + if (closureScope != null) { + variables.add(new TeaVMJSScope(debugTarget, "", closureScope)); + } + List teavmVarList = new ArrayList<>(teavmVariables); + Collections.sort(teavmVarList, new Comparator() { + @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]); } } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaStackFrame.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaStackFrame.java new file mode 100644 index 000000000..df10e9bff --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaStackFrame.java @@ -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 + */ +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(); + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaThread.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaThread.java new file mode 100644 index 000000000..3eab8c9ba --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaThread.java @@ -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 + */ +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"; + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaValue.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaValue.java new file mode 100644 index 000000000..b056665c7 --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaValue.java @@ -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(); + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaVariable.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaVariable.java new file mode 100644 index 000000000..832a45e15 --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaVariable.java @@ -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(); + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaVariablesHolder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaVariablesHolder.java new file mode 100644 index 000000000..de132c179 --- /dev/null +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMJavaVariablesHolder.java @@ -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 teavmVariables; + + public TeaVMJavaVariablesHolder(TeaVMDebugTarget debugTarget, Collection teavmVariables) { + this.debugTarget = debugTarget; + this.teavmVariables = teavmVariables; + } + + @Override + protected TeaVMVariable[] createVariables() { + TeaVMJavaVariable[] newVariables = new TeaVMJavaVariable[teavmVariables.size()]; + List teavmVarList = new ArrayList<>(teavmVariables); + Collections.sort(teavmVarList, new Comparator() { + @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; + } +} diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java index dd62d622a..e59491024 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java @@ -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 */ -public class TeaVMLaunchConfigurationDelegate implements ILaunchConfigurationDelegate { +public class TeaVMLaunchConfigurationDelegate extends LaunchConfigurationDelegate { @Override public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor) throws CoreException { diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java index b628db403..6c48d6187 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java @@ -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()); diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java index 9b7c5415e..e1a508a13 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java @@ -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 */ -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; diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java index 6e8b11b41..7dbe8a3dc 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java @@ -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 */ -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]; } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMValue.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMValue.java index ef085fcdf..07ec32d74 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMValue.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMValue.java @@ -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 */ -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(); } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariable.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariable.java index df654b2ce..3dba0b5ee 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariable.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariable.java @@ -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 */ -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; } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariablesHolder.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariablesHolder.java index 876933e9c..968a9e2fd 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariablesHolder.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMVariablesHolder.java @@ -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 */ -public class TeaVMVariablesHolder { - private TeaVMDebugTarget debugTarget; - private Collection teavmVariables; +public abstract class TeaVMVariablesHolder { private AtomicReference variables = new AtomicReference<>(); - public TeaVMVariablesHolder(TeaVMDebugTarget debugTarget, Collection teavmVariables) { - this.debugTarget = debugTarget; - this.teavmVariables = teavmVariables; - } - public TeaVMVariable[] getVariables() { if (variables.get() == null) { - TeaVMVariable[] newVariables = new TeaVMVariable[teavmVariables.size()]; - List teavmVarList = new ArrayList<>(teavmVariables); - Collections.sort(teavmVarList, new Comparator() { - @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(); } diff --git a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMDebugModelPresentation.java b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMDebugModelPresentation.java index 6c2a9adc0..a12be407e 100644 --- a/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMDebugModelPresentation.java +++ b/teavm-eclipse/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMDebugModelPresentation.java @@ -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) {