From 930d2087abc22a4c5e96762987bfedaa62cae5b6 Mon Sep 17 00:00:00 2001 From: konsoletyper Date: Thu, 31 Jul 2014 20:01:56 +0400 Subject: [PATCH] First working prototype of eclipse plugin --- .../main/java/org/teavm/parsing/Parser.java | 3 +- .../.gitignore | 1 + teavm-eclipse-plugin/META-INF/MANIFEST.MF | 55 ++++++++++++ teavm-eclipse-plugin/build.properties | 44 +++++++++ teavm-eclipse-plugin/logback.xml | 10 +++ .../plugin.xml | 15 +++- .../pom.xml | 29 +++--- .../org/teavm/eclipse/TeaVMEclipsePlugin.java | 0 .../debugger/TeaVMDebugModelPresentation.java | 52 +++++++++++ .../eclipse/debugger/TeaVMDebugProcess.java | 0 .../eclipse/debugger/TeaVMDebugTarget.java | 90 +++++++++++++------ .../TeaVMLaunchConfigurationDelegate.java | 35 +++++--- .../debugger/TeaVMSourceLookupDirector.java | 0 .../TeaVMSourceLookupParticipant.java | 10 +-- .../TeaVMSourcePathComputerDelegate.java | 43 +++++++++ .../eclipse/debugger/TeaVMStackFrame.java | 33 ++++--- .../eclipse/debugger/TeaVMStreamMonitor.java | 0 .../eclipse/debugger/TeaVMStreamsProxy.java | 0 .../teavm/eclipse/debugger/TeaVMThread.java | 59 ++++++++++-- .../teavm/eclipse/debugger/ui/TeaVMTab.java | 2 +- .../eclipse/debugger/ui/TeaVMTabGroup.java | 0 21 files changed, 397 insertions(+), 84 deletions(-) rename {teavm-eclipse => teavm-eclipse-plugin}/.gitignore (89%) create mode 100644 teavm-eclipse-plugin/META-INF/MANIFEST.MF create mode 100644 teavm-eclipse-plugin/build.properties create mode 100644 teavm-eclipse-plugin/logback.xml rename {teavm-eclipse/src/main/resources => teavm-eclipse-plugin}/plugin.xml (65%) rename {teavm-eclipse => teavm-eclipse-plugin}/pom.xml (73%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java (100%) create mode 100644 teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugModelPresentation.java rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java (100%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java (69%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java (77%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java (100%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java (61%) create mode 100644 teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java (76%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java (100%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java (100%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java (61%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java (98%) rename {teavm-eclipse => teavm-eclipse-plugin}/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java (100%) diff --git a/teavm-core/src/main/java/org/teavm/parsing/Parser.java b/teavm-core/src/main/java/org/teavm/parsing/Parser.java index 9ff34de53..e8d647ed8 100644 --- a/teavm-core/src/main/java/org/teavm/parsing/Parser.java +++ b/teavm-core/src/main/java/org/teavm/parsing/Parser.java @@ -64,9 +64,10 @@ public final class Parser { FieldNode fieldNode = (FieldNode)obj; cls.addField(parseField(fieldNode)); } + String fullFileName = node.name.substring(0, node.name.lastIndexOf('/') + 1) + node.sourceFile; for (Object obj : node.methods) { MethodNode methodNode = (MethodNode)obj; - cls.addMethod(parseMethod(methodNode, node.name, node.sourceFile)); + cls.addMethod(parseMethod(methodNode, node.name, fullFileName)); } if (node.outerClass != null) { cls.setOwnerName(node.outerClass.replace('/', '.')); diff --git a/teavm-eclipse/.gitignore b/teavm-eclipse-plugin/.gitignore similarity index 89% rename from teavm-eclipse/.gitignore rename to teavm-eclipse-plugin/.gitignore index 4e247eee2..d3f7a8a94 100644 --- a/teavm-eclipse/.gitignore +++ b/teavm-eclipse-plugin/.gitignore @@ -1,4 +1,5 @@ /.settings +/lib /target /.classpath /.project diff --git a/teavm-eclipse-plugin/META-INF/MANIFEST.MF b/teavm-eclipse-plugin/META-INF/MANIFEST.MF new file mode 100644 index 000000000..11ce4a80d --- /dev/null +++ b/teavm-eclipse-plugin/META-INF/MANIFEST.MF @@ -0,0 +1,55 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: TeaVM plugin for Eclipse +Bundle-SymbolicName: teavm-eclipse-plugin;singleton:=true +Bundle-Version: 0.2.0.SNAPSHOT +Bundle-Vendor: Alexey Andreev +Bundle-RequiredExecutionEnvironment: JavaSE-1.7 +Require-Bundle: org.eclipse.core.runtime;bundle-version="3.9.0", + org.eclipse.debug.core;bundle-version="3.8.0", + org.eclipse.debug.ui;bundle-version="3.9.0", + org.eclipse.swt;bundle-version="3.102.0", + org.eclipse.ui;bundle-version="3.105.0", + org.eclipse.jdt.debug;bundle-version="3.8.0", + org.eclipse.jdt.debug.ui;bundle-version="3.6.200", + org.eclipse.jdt.core;bundle-version="3.9.2", + org.eclipse.jdt.launching;bundle-version="3.7.1", + org.eclipse.ui.editors;bundle-version="3.8.100", + org.eclipse.ui.ide;bundle-version="3.9.0", + org.eclipse.jdt.ui;bundle-version="3.9.2" +Bundle-ClassPath: lib/asm-5.0.1.jar, + lib/asm-commons-5.0.1.jar, + lib/asm-debug-all-4.2.jar, + lib/asm-tree-5.0.1.jar, + lib/commons-io-2.4.jar, + lib/jackson-core-asl-1.9.13.jar, + lib/jackson-mapper-asl-1.9.13.jar, + lib/javax-websocket-client-impl-9.2.1.v20140609.jar, + lib/javax-websocket-server-impl-9.2.1.v20140609.jar, + lib/javax.annotation-api-1.2.jar, + lib/javax.servlet-api-3.1.0.jar, + lib/javax.websocket-api-1.0.jar, + lib/jetty-annotations-9.2.1.v20140609.jar, + lib/jetty-http-9.2.1.v20140609.jar, + lib/jetty-io-9.2.1.v20140609.jar, + lib/jetty-jndi-9.2.1.v20140609.jar, + lib/jetty-plus-9.2.1.v20140609.jar, + lib/jetty-security-9.2.1.v20140609.jar, + lib/jetty-server-9.2.1.v20140609.jar, + lib/jetty-servlet-9.2.1.v20140609.jar, + lib/jetty-util-9.2.1.v20140609.jar, + lib/jetty-webapp-9.2.1.v20140609.jar, + lib/jetty-xml-9.2.1.v20140609.jar, + lib/slf4j-api-1.7.7.jar, + lib/teavm-chrome-rdp-0.2-SNAPSHOT.jar, + lib/teavm-core-0.2-SNAPSHOT.jar, + lib/websocket-api-9.2.1.v20140609.jar, + lib/websocket-client-9.2.1.v20140609.jar, + lib/websocket-common-9.2.1.v20140609.jar, + lib/websocket-server-9.2.1.v20140609.jar, + lib/websocket-servlet-9.2.1.v20140609.jar, + ., + lib/logback-classic-1.1.2.jar, + lib/logback-core-1.1.2.jar +Export-Package: org.teavm.eclipse.debugger, + org.teavm.eclipse.debugger.ui diff --git a/teavm-eclipse-plugin/build.properties b/teavm-eclipse-plugin/build.properties new file mode 100644 index 000000000..b7c5afb9c --- /dev/null +++ b/teavm-eclipse-plugin/build.properties @@ -0,0 +1,44 @@ +source.. = src/main/java/ +output.. = target/ +bin.includes = plugin.xml,\ + META-INF/,\ + .,\ + lib/asm-5.0.1.jar,\ + lib/websocket-servlet-9.2.1.v20140609.jar,\ + lib/websocket-server-9.2.1.v20140609.jar,\ + lib/websocket-common-9.2.1.v20140609.jar,\ + lib/websocket-client-9.2.1.v20140609.jar,\ + lib/websocket-api-9.2.1.v20140609.jar,\ + lib/teavm-core-0.2-SNAPSHOT.jar,\ + lib/teavm-chrome-rdp-0.2-SNAPSHOT.jar,\ + lib/slf4j-api-1.7.7.jar,\ + lib/jetty-xml-9.2.1.v20140609.jar,\ + lib/jetty-webapp-9.2.1.v20140609.jar,\ + lib/jetty-util-9.2.1.v20140609.jar,\ + lib/jetty-servlet-9.2.1.v20140609.jar,\ + lib/jetty-server-9.2.1.v20140609.jar,\ + lib/jetty-security-9.2.1.v20140609.jar,\ + lib/jetty-plus-9.2.1.v20140609.jar,\ + lib/jetty-jndi-9.2.1.v20140609.jar,\ + lib/jetty-io-9.2.1.v20140609.jar,\ + lib/jetty-http-9.2.1.v20140609.jar,\ + lib/jetty-annotations-9.2.1.v20140609.jar,\ + lib/javax.websocket-api-1.0.jar,\ + lib/javax.servlet-api-3.1.0.jar,\ + lib/javax.annotation-api-1.2.jar,\ + lib/javax-websocket-server-impl-9.2.1.v20140609.jar,\ + lib/javax-websocket-client-impl-9.2.1.v20140609.jar,\ + lib/jackson-mapper-asl-1.9.13.jar,\ + lib/jackson-core-asl-1.9.13.jar,\ + lib/commons-io-2.4.jar,\ + lib/asm-tree-5.0.1.jar,\ + lib/asm-debug-all-4.2.jar,\ + lib/asm-commons-5.0.1.jar,\ + logback.xml,\ + lib/logback-core-1.1.2.jar,\ + lib/logback-classic-1.1.2.jar +source.lib/teavm-core-0.2-SNAPSHOT.jar = +jars.compile.order = .,\ + lib/teavm-core-0.2-SNAPSHOT.jar,\ + lib/teavm-chrome-rdp-0.2-SNAPSHOT.jar +source.lib/teavm-chrome-rdp-0.2-SNAPSHOT.jar = diff --git a/teavm-eclipse-plugin/logback.xml b/teavm-eclipse-plugin/logback.xml new file mode 100644 index 000000000..aea2ddb08 --- /dev/null +++ b/teavm-eclipse-plugin/logback.xml @@ -0,0 +1,10 @@ + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n + + + + + + \ No newline at end of file diff --git a/teavm-eclipse/src/main/resources/plugin.xml b/teavm-eclipse-plugin/plugin.xml similarity index 65% rename from teavm-eclipse/src/main/resources/plugin.xml rename to teavm-eclipse-plugin/plugin.xml index 1debbc4ee..744b84a5d 100644 --- a/teavm-eclipse/src/main/resources/plugin.xml +++ b/teavm-eclipse-plugin/plugin.xml @@ -1,10 +1,11 @@ - + @@ -17,6 +18,12 @@ id="org.teavm.eclipse.debugger.sourceLookup"> + + + + + + + + \ No newline at end of file diff --git a/teavm-eclipse/pom.xml b/teavm-eclipse-plugin/pom.xml similarity index 73% rename from teavm-eclipse/pom.xml rename to teavm-eclipse-plugin/pom.xml index d2c844522..303b0399b 100644 --- a/teavm-eclipse/pom.xml +++ b/teavm-eclipse-plugin/pom.xml @@ -11,13 +11,6 @@ teavm-eclipse bundle - - - swt-repo - https://swt-repo.googlecode.com/svn/repo/ - - - org.teavm @@ -30,14 +23,9 @@ ${project.version} - org.eclipse.core - runtime - 3.9.100-v20131218-1515 - - - org.eclipse.swt - org.eclipse.swt.win32.win32.x86 - 4.2.2 + ch.qos.logback + logback-classic + 1.1.2 @@ -54,6 +42,17 @@ + + org.apache.maven.plugins + maven-dependency-plugin + 2.8 + + dependency:copy-dependencies + + + ${basedir}/lib + + diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java similarity index 100% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java diff --git a/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugModelPresentation.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugModelPresentation.java new file mode 100644 index 000000000..802a04b60 --- /dev/null +++ b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugModelPresentation.java @@ -0,0 +1,52 @@ +package org.teavm.eclipse.debugger; + +import org.eclipse.core.resources.IFile; +import org.eclipse.debug.core.model.ILineBreakpoint; +import org.eclipse.debug.core.model.IValue; +import org.eclipse.debug.ui.IDebugModelPresentation; +import org.eclipse.debug.ui.IValueDetailListener; +import org.eclipse.jdt.ui.JavaUI; +import org.eclipse.jface.viewers.LabelProvider; +import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.part.FileEditorInput; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMDebugModelPresentation extends LabelProvider implements IDebugModelPresentation { + @Override + public String getEditorId(IEditorInput input, Object element) { + if (element instanceof IFile || element instanceof ILineBreakpoint) { + return JavaUI.ID_CU_EDITOR; + } + return null; + } + + @Override + public IEditorInput getEditorInput(Object element) { + if (element instanceof IFile) { + return new FileEditorInput((IFile)element); + } + if (element instanceof ILineBreakpoint) { + return new FileEditorInput((IFile)((ILineBreakpoint)element).getMarker().getResource()); + } + return null; + } + + @Override + public void computeDetail(IValue arg0, IValueDetailListener arg1) { + } + + @Override + public void setAttribute(String arg0, Object arg1) { + } + + @Override + public String getText(Object element) { + if (element instanceof TeaVMStackFrame) { + return ((TeaVMStackFrame)element).getName(); + } + return super.getText(element); + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java similarity index 100% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java similarity index 69% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java index e91da3300..70fc45088 100644 --- a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java +++ b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java @@ -2,19 +2,14 @@ package org.teavm.eclipse.debugger; import java.util.HashMap; import java.util.Map; -import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IMarkerDelta; -import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; 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.IMemoryBlock; -import org.eclipse.debug.core.model.IProcess; -import org.eclipse.debug.core.model.IThread; +import org.eclipse.debug.core.model.*; +import org.eclipse.jdt.debug.core.IJavaLineBreakpoint; import org.teavm.chromerdp.ChromeRDPServer; import org.teavm.debugging.Breakpoint; import org.teavm.debugging.Debugger; @@ -25,12 +20,13 @@ import org.teavm.debugging.DebuggerListener; * @author Alexey Andreev */ @SuppressWarnings("rawtypes") -public class TeaVMDebugTarget implements IDebugTarget { +public class TeaVMDebugTarget implements IDebugTarget, IStep { ILaunch launch; Debugger teavmDebugger; private ChromeRDPServer server; private boolean terminated; private TeaVMDebugProcess process; + private TeaVMThread thread; Map breakpointMap = new HashMap<>(); Map breakpointBackMap = new HashMap<>(); @@ -39,6 +35,11 @@ public class TeaVMDebugTarget implements IDebugTarget { this.teavmDebugger = teavmDebugger; this.server = server; this.process = new TeaVMDebugProcess(launch); + this.thread = new TeaVMThread(this); + DebugPlugin.getDefault().getBreakpointManager().addBreakpointListener(this); + for (IBreakpoint breakpoint : DebugPlugin.getDefault().getBreakpointManager().getBreakpoints()) { + breakpointAdded(breakpoint); + } teavmDebugger.addListener(new DebuggerListener() { @Override public void resumed() { @@ -88,6 +89,7 @@ public class TeaVMDebugTarget implements IDebugTarget { public void terminate() throws DebugException { terminated = true; server.stop(); + fireEvent(new DebugEvent(this, DebugEvent.TERMINATE)); } @Override @@ -98,25 +100,25 @@ public class TeaVMDebugTarget implements IDebugTarget { @Override public void breakpointAdded(IBreakpoint breakpoint) { try { - breakpoint.setRegistered(true); - int line = breakpoint.getMarker().getAttribute(IMarker.LINE_NUMBER, 1); - String fileName = getRelativePath(breakpoint.getMarker().getResource()); - teavmDebugger.createBreakpoint(fileName, line); + if (breakpoint instanceof IJavaLineBreakpoint) { + IJavaLineBreakpoint lineBreakpoint = (IJavaLineBreakpoint)breakpoint; + String fileName = lineBreakpoint.getTypeName().replace('.', '/') + ".java"; + Breakpoint teavmBreakpoint = teavmDebugger.createBreakpoint(fileName, lineBreakpoint.getLineNumber()); + breakpointMap.put(lineBreakpoint, teavmBreakpoint); + breakpointBackMap.put(teavmBreakpoint, lineBreakpoint); + breakpoint.setRegistered(true); + } else { + breakpoint.setRegistered(false); + } } catch (CoreException e) { throw new RuntimeException(e); } } - private String getRelativePath(IResource resource) { - if ((resource.getType() & IResource.PROJECT) != 0 || - (resource.getType() & IResource.VIRTUAL) != 0) { - return ""; - } - return getRelativePath(resource.getParent()) + "/" + resource.getName(); - } - @Override - public void breakpointChanged(IBreakpoint arg0, IMarkerDelta arg1) { + public void breakpointChanged(IBreakpoint breakpoint, IMarkerDelta markerDelta) { + breakpointRemoved(breakpoint, markerDelta); + breakpointAdded(breakpoint); } @Override @@ -189,7 +191,7 @@ public class TeaVMDebugTarget implements IDebugTarget { @Override public boolean isDisconnected() { - return teavmDebugger.isAttached(); + return !teavmDebugger.isAttached(); } @Override @@ -204,7 +206,7 @@ public class TeaVMDebugTarget implements IDebugTarget { @Override public IThread[] getThreads() throws DebugException { - return null; + return new IThread[] { thread }; } @Override @@ -214,11 +216,41 @@ public class TeaVMDebugTarget implements IDebugTarget { @Override public boolean supportsBreakpoint(IBreakpoint breakpoint) { - try { - return breakpoint.getMarker().getAttribute(IMarker.LINE_NUMBER) != null; - } catch (CoreException e) { - // TODO: Log this exception - return false; - } + return breakpoint instanceof IJavaLineBreakpoint; + } + + @Override + public boolean canStepInto() { + return true; + } + + @Override + public boolean canStepOver() { + return true; + } + + @Override + public boolean canStepReturn() { + return true; + } + + @Override + public boolean isStepping() { + 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(); } } diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java similarity index 77% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java index 44503fba5..30d34d0c0 100644 --- a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java +++ b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMLaunchConfigurationDelegate.java @@ -9,7 +9,7 @@ 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.swt.widgets.Display; +import org.eclipse.ui.PlatformUI; import org.teavm.chromerdp.*; import org.teavm.debugging.Debugger; import org.teavm.debugging.URLDebugInformationProvider; @@ -26,14 +26,17 @@ public class TeaVMLaunchConfigurationDelegate implements ILaunchConfigurationDel throw new IllegalArgumentException("Only debug mode supported"); } int port = configuration.getAttribute("teavm-debugger-port", 2357); - ChromeRDPServer server = new ChromeRDPServer(); + final ChromeRDPServer server = new ChromeRDPServer(); server.setPort(port); ChromeRDPDebugger jsDebugger = new ChromeRDPDebugger(); server.setExchangeConsumer(new SynchronousMessageExchange(jsDebugger)); Debugger debugger = new Debugger(jsDebugger, new URLDebugInformationProvider("")); - server.start(); + new Thread() { + @Override public void run() { + server.start(); + } + }.start(); launch.addDebugTarget(new TeaVMDebugTarget(launch, debugger, server)); - monitor.done(); } private static class SynchronousMessageExchange implements ChromeRDPExchangeConsumer, @@ -52,17 +55,21 @@ public class TeaVMLaunchConfigurationDelegate implements ILaunchConfigurationDel debugger.setExchange(this); exchange.addListener(new ChromeRDPExchangeListener() { @Override public void received(final String message) throws IOException { - Display.getCurrent().asyncExec(new Runnable() { - @Override public void run() { - try { - for (ChromeRDPExchangeListener listener : listeners) { - listener.received(message); - } - } catch (IOException e) { - // TODO: add logging - } + postToUIThread(message); + } + }); + } + + private void postToUIThread(final String message) { + PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { + @Override public void run() { + try { + for (ChromeRDPExchangeListener listener : listeners) { + listener.received(message); } - }); + } catch (IOException e) { + // TODO: add logging + } } }); } diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java similarity index 100% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java similarity index 61% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java index 43c43bf73..cff14b8f8 100644 --- a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java +++ b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java @@ -11,11 +11,11 @@ import org.teavm.debugging.SourceLocation; public class TeaVMSourceLookupParticipant extends AbstractSourceLookupParticipant { @Override public String getSourceName(Object object) throws CoreException { - if (object instanceof TeaVMStackFrame) { - TeaVMStackFrame stackFrame = (TeaVMStackFrame)object; - SourceLocation location = stackFrame.callFrame.getLocation(); - return location != null ? location.getFileName() : null; + if (!(object instanceof TeaVMStackFrame)) { + return null; } - return null; + TeaVMStackFrame stackFrame = (TeaVMStackFrame)object; + SourceLocation location = stackFrame.callFrame.getLocation(); + return location != null ? location.getFileName() : null; } } diff --git a/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java new file mode 100644 index 000000000..569022efd --- /dev/null +++ b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMSourcePathComputerDelegate.java @@ -0,0 +1,43 @@ +package org.teavm.eclipse.debugger; + +import java.util.ArrayList; +import java.util.List; +import org.eclipse.core.resources.IFolder; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.sourcelookup.ISourceContainer; +import org.eclipse.debug.core.sourcelookup.ISourcePathComputerDelegate; +import org.eclipse.debug.core.sourcelookup.containers.FolderSourceContainer; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.core.IPackageFragmentRoot; +import org.eclipse.jdt.core.JavaCore; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMSourcePathComputerDelegate implements ISourcePathComputerDelegate { + @Override + public ISourceContainer[] computeSourceContainers(ILaunchConfiguration config, IProgressMonitor monitor) + throws CoreException { + List sourceContainers = new ArrayList<>(); + IProject[] projects = ResourcesPlugin.getWorkspace().getRoot().getProjects(); + for (IProject project : projects) { + if (!project.isOpen()) { + continue; + } + if (project.hasNature(JavaCore.NATURE_ID)) { + IJavaProject javaProject = JavaCore.create(project); + for (IPackageFragmentRoot fragmentRoot : javaProject.getAllPackageFragmentRoots()) { + if (fragmentRoot.getResource() instanceof IFolder) { + sourceContainers.add(new FolderSourceContainer((IFolder)fragmentRoot.getResource(), true)); + } + } + } + } + return sourceContainers.toArray(new ISourceContainer[0]); + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java similarity index 76% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java index f97ffc367..31ec49953 100644 --- a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java +++ b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java @@ -2,11 +2,7 @@ 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.IRegisterGroup; -import org.eclipse.debug.core.model.IStackFrame; -import org.eclipse.debug.core.model.IThread; -import org.eclipse.debug.core.model.IVariable; +import org.eclipse.debug.core.model.*; import org.teavm.debugging.CallFrame; /** @@ -43,17 +39,17 @@ public class TeaVMStackFrame implements IStackFrame { @Override public boolean canStepInto() { - return false; + return thread.getTopStackFrame() == this; } @Override public boolean canStepOver() { - return false; + return thread.getTopStackFrame() == this; } @Override public boolean canStepReturn() { - return false; + return thread.getTopStackFrame() == this; } @Override @@ -63,14 +59,17 @@ public class TeaVMStackFrame implements IStackFrame { @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 @@ -80,20 +79,22 @@ public class TeaVMStackFrame implements IStackFrame { @Override public boolean canSuspend() { - return false; + return thread.getTopStackFrame() == this; } @Override public boolean isSuspended() { - return false; + return thread.isSuspended(); } @Override public void resume() throws DebugException { + thread.resume(); } @Override public void suspend() throws DebugException { + thread.suspend(); } @Override @@ -108,7 +109,7 @@ public class TeaVMStackFrame implements IStackFrame { @Override public String getModelIdentifier() { - return thread.getModelIdentifier(); + return thread.getModelIdentifier() + ".thread"; } @Override @@ -127,8 +128,14 @@ public class TeaVMStackFrame implements IStackFrame { } @Override - public String getName() throws DebugException { - return callFrame.getLocation() != null ? callFrame.getLocation().getFileName() : "unknown"; + 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 diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java similarity index 100% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java similarity index 100% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java similarity index 61% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java index d0181a89b..3c53d4a75 100644 --- a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java +++ b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java @@ -1,12 +1,17 @@ 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; /** * @@ -15,10 +20,52 @@ import org.teavm.debugging.Debugger; public class TeaVMThread implements IThread { private Debugger teavmDebugger; private TeaVMDebugTarget debugTarget; + private TeaVMStackFrame[] stackTrace; public TeaVMThread(TeaVMDebugTarget debugTarget) { this.debugTarget = debugTarget; this.teavmDebugger = debugTarget.teavmDebugger; + this.teavmDebugger.addListener(new DebuggerListener() { + @Override + public void resumed() { + updateStackTrace(); + } + + @Override + public void paused() { + updateStackTrace(); + } + + @Override + public void detached() { + } + + @Override + public void breakpointStatusChanged(Breakpoint breakpoint) { + } + + @Override + public void attached() { + } + }); + } + + private void updateStackTrace() { + if (teavmDebugger.getCallStack() == null) { + stackTrace = null; + } else { + CallFrame[] teavmCallStack = teavmDebugger.getCallStack(); + stackTrace = new TeaVMStackFrame[teavmCallStack.length]; + for (int i = 0; i < teavmCallStack.length; ++i) { + CallFrame teavmFrame = teavmCallStack[i]; + stackTrace[i] = new TeaVMStackFrame(this, teavmFrame); + } + } + fireEvent(new DebugEvent(this, DebugEvent.CHANGE)); + } + + private void fireEvent(DebugEvent event) { + DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event }); } @Override @@ -43,12 +90,12 @@ public class TeaVMThread implements IThread { @Override public boolean canResume() { - return false; + return true; } @Override public boolean canSuspend() { - return false; + return true; } @Override @@ -58,10 +105,12 @@ public class TeaVMThread implements IThread { @Override public void resume() throws DebugException { + teavmDebugger.resume(); } @Override public void suspend() throws DebugException { + teavmDebugger.suspend(); } @Override @@ -131,12 +180,12 @@ public class TeaVMThread implements IThread { @Override public IStackFrame[] getStackFrames() throws DebugException { - return null; + return stackTrace != null ? stackTrace.clone() : new IStackFrame[0]; } @Override - public IStackFrame getTopStackFrame() throws DebugException { - return null; + public IStackFrame getTopStackFrame() { + return stackTrace != null && stackTrace.length > 0 ? stackTrace[0] : null; } @Override diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java similarity index 98% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java index d33ea1315..d232b5552 100644 --- a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java +++ b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java @@ -43,7 +43,7 @@ public class TeaVMTab extends AbstractLaunchConfigurationTab { @Override public String getName() { - return null; + return "TeaVM"; } @Override diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java b/teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java similarity index 100% rename from teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java rename to teavm-eclipse-plugin/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java