First attempt to create a TeaVM eclipse plugin

This commit is contained in:
konsoletyper 2014-07-30 23:32:42 +04:00
parent 25789825fc
commit 4b43cbce55
9 changed files with 342 additions and 1 deletions

View File

@ -83,6 +83,17 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
</plugin> </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>org.teavm.chromerdp</Export-Package>
<Bundle-SymbolicName>teavm-chrome-rdp</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>
</project> </project>

View File

@ -33,6 +33,7 @@ import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainer
public class ChromeRDPServer { public class ChromeRDPServer {
private int port = 2357; private int port = 2357;
private ChromeRDPExchangeConsumer exchangeConsumer; private ChromeRDPExchangeConsumer exchangeConsumer;
private Server server;
public int getPort() { public int getPort() {
return port; return port;
@ -51,7 +52,7 @@ public class ChromeRDPServer {
} }
public void start() { public void start() {
final Server server = new Server(); server = new Server();
ServerConnector connector = new ServerConnector(server); ServerConnector connector = new ServerConnector(server);
connector.setPort(port); connector.setPort(port);
server.addConnector(connector); server.addConnector(connector);
@ -71,6 +72,14 @@ public class ChromeRDPServer {
} }
} }
public void stop() {
try {
server.stop();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private class RPDEndpointConfig implements ServerEndpointConfig { private class RPDEndpointConfig implements ServerEndpointConfig {
private Map<String, Object> userProperties = new HashMap<>(); private Map<String, Object> userProperties = new HashMap<>();

View File

@ -24,6 +24,8 @@
</parent> </parent>
<artifactId>teavm-core</artifactId> <artifactId>teavm-core</artifactId>
<packaging>bundle</packaging>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
@ -75,6 +77,17 @@
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId> <artifactId>maven-javadoc-plugin</artifactId>
</plugin> </plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>org.teavm.*</Export-Package>
<Bundle-SymbolicName>teavm-core</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

4
teavm-eclipse/.gitignore vendored Normal file
View File

@ -0,0 +1,4 @@
/.settings
/target
/.classpath
/.project

View File

@ -0,0 +1,11 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: TeaVM eclipse support
Bundle-SymbolicName: teavm-eclipse;singleton:=true
Bundle-Version: 0.2.0
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Require-Bundle: org.eclipse.debug.core;bundle-version="3.8.0",
org.eclipse.debug.ui;bundle-version="3.9.0",
org.eclipse.core.runtime;bundle-version="3.9.0",
org.eclipse.swt;bundle-version="3.102.0",
org.eclipse.jdt.debug;bundle-version="3.8.0"

View File

@ -0,0 +1,4 @@
source.. = src/main/java/
output.. = target/
bin.includes = META-INF/,\
.

5
teavm-eclipse/plugin.xml Normal file
View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<plugin id="org.teavm.eclipse" name="TeaVM plugin" version="1.0">
</plugin>

View File

@ -0,0 +1,199 @@
package org.teavm.eclipse.debugger;
import org.eclipse.core.resources.IMarkerDelta;
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.ILineBreakpoint;
import org.eclipse.debug.core.model.IMemoryBlock;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.teavm.chromerdp.ChromeRDPServer;
import org.teavm.debugging.Breakpoint;
import org.teavm.debugging.Debugger;
import org.teavm.debugging.DebuggerListener;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
@SuppressWarnings("rawtypes")
public class TeaVMDebugTarget implements IDebugTarget {
private ILaunch launch;
private Debugger teavmDebugger;
private ChromeRDPServer server;
private boolean terminated;
public TeaVMDebugTarget(ILaunch launch, Debugger teavmDebugger, ChromeRDPServer server) {
this.launch = launch;
this.teavmDebugger = teavmDebugger;
this.server = server;
teavmDebugger.addListener(new DebuggerListener() {
@Override
public void resumed() {
fireEvent(new DebugEvent(TeaVMDebugTarget.this, DebugEvent.RESUME));
}
@Override
public void paused() {
fireEvent(new DebugEvent(TeaVMDebugTarget.this, DebugEvent.SUSPEND));
}
@Override
public void detached() {
fireEvent(new DebugEvent(TeaVMDebugTarget.this, DebugEvent.CHANGE));
}
@Override
public void breakpointStatusChanged(Breakpoint breakpoint) {
}
@Override
public void attached() {
fireEvent(new DebugEvent(TeaVMDebugTarget.this, DebugEvent.CHANGE));
}
});
}
private void fireEvent(DebugEvent event) {
DebugPlugin.getDefault().fireDebugEventSet(new DebugEvent[] { event });
}
@Override
public boolean canTerminate() {
return true;
}
@Override
public boolean isTerminated() {
return terminated;
}
@Override
public void terminate() throws DebugException {
terminated = true;
server.stop();
}
@Override
public Object getAdapter(Class arg0) {
return null;
}
@Override
public void breakpointAdded(IBreakpoint breakpoint) {
if (!(breakpoint instanceof ILineBreakpoint)) {
return;
}
IJavaLineBreakpoint lineBreakpoint = (IJavaLineBreakpoint)breakpoint;
try {
lineBreakpoint.setRegistered(true);
String fileName = lineBreakpoint.getTypeName().replace('.', '/') + ".java";
teavmDebugger.createBreakpoint(fileName, lineBreakpoint.getLineNumber());
} catch (CoreException e) {
throw new RuntimeException(e);
}
}
@Override
public void breakpointChanged(IBreakpoint arg0, IMarkerDelta arg1) {
}
@Override
public void breakpointRemoved(IBreakpoint arg0, IMarkerDelta arg1) {
}
@Override
public boolean canResume() {
return true;
}
@Override
public boolean canSuspend() {
return true;
}
@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 IMemoryBlock getMemoryBlock(long arg0, long arg1) throws DebugException {
return null;
}
@Override
public boolean supportsStorageRetrieval() {
return false;
}
@Override
public IDebugTarget getDebugTarget() {
return this;
}
@Override
public ILaunch getLaunch() {
return launch;
}
@Override
public String getModelIdentifier() {
return "";
}
@Override
public boolean canDisconnect() {
return true;
}
@Override
public void disconnect() throws DebugException {
}
@Override
public boolean isDisconnected() {
return teavmDebugger.isAttached();
}
@Override
public String getName() throws DebugException {
return "TeaVM debugger";
}
@Override
public IProcess getProcess() {
return null;
}
@Override
public IThread[] getThreads() throws DebugException {
return null;
}
@Override
public boolean hasThreads() throws DebugException {
return false;
}
@Override
public boolean supportsBreakpoint(IBreakpoint breakpoint) {
return breakpoint instanceof IJavaLineBreakpoint;
}
}

View File

@ -0,0 +1,85 @@
package org.teavm.eclipse.debugger;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.runtime.CoreException;
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.swt.widgets.Display;
import org.teavm.chromerdp.*;
import org.teavm.debugging.Debugger;
import org.teavm.debugging.URLDebugInformationProvider;
/**
*
* @author Alexey Andreev <konsoletyper@gmail.com>
*/
public class TeaVMLaunchConfigurationDelegate implements ILaunchConfigurationDelegate {
@Override
public void launch(ILaunchConfiguration configuration, String mode, ILaunch launch, IProgressMonitor monitor)
throws CoreException {
if (!mode.equals(ILaunchManager.DEBUG_MODE)) {
throw new IllegalArgumentException("Only debug mode supported");
}
int port = configuration.getAttribute("teavm-debugger-port", 2357);
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();
launch.addDebugTarget(new TeaVMDebugTarget(launch, debugger, server));
monitor.done();
}
private static class SynchronousMessageExchange implements ChromeRDPExchangeConsumer,
ChromeRDPExchange {
private List<ChromeRDPExchangeListener> listeners = new ArrayList<>();
private ChromeRDPDebugger debugger;
private ChromeRDPExchange exchange;
public SynchronousMessageExchange(ChromeRDPDebugger debugger) {
this.debugger = debugger;
}
@Override
public void setExchange(ChromeRDPExchange exchange) {
this.exchange = exchange;
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
}
}
});
}
});
}
@Override
public void send(String message) {
exchange.send(message);
}
@Override
public void addListener(ChromeRDPExchangeListener listener) {
listeners.add(listener);
}
@Override
public void removeListener(ChromeRDPExchangeListener listener) {
listeners.remove(listener);
}
}
}