diff --git a/teavm-chrome-rdp/pom.xml b/teavm-chrome-rdp/pom.xml index 3d2c429be..88b8be965 100644 --- a/teavm-chrome-rdp/pom.xml +++ b/teavm-chrome-rdp/pom.xml @@ -24,6 +24,8 @@ teavm-chrome-rdp + bundle + TeaVM debugging backend for Google Chrome RDP TeaVM debugging backend for Google Chrome RDP diff --git a/teavm-eclipse/META-INF/MANIFEST.MF b/teavm-eclipse/META-INF/MANIFEST.MF deleted file mode 100644 index dd2fd6e7e..000000000 --- a/teavm-eclipse/META-INF/MANIFEST.MF +++ /dev/null @@ -1,11 +0,0 @@ -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" diff --git a/teavm-eclipse/build.properties b/teavm-eclipse/build.properties deleted file mode 100644 index b506aa447..000000000 --- a/teavm-eclipse/build.properties +++ /dev/null @@ -1,4 +0,0 @@ -source.. = src/main/java/ -output.. = target/ -bin.includes = META-INF/,\ - . diff --git a/teavm-eclipse/plugin.xml b/teavm-eclipse/plugin.xml deleted file mode 100644 index 2bf043fd6..000000000 --- a/teavm-eclipse/plugin.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/teavm-eclipse/pom.xml b/teavm-eclipse/pom.xml new file mode 100644 index 000000000..d2c844522 --- /dev/null +++ b/teavm-eclipse/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + + org.teavm + teavm + 0.2-SNAPSHOT + + teavm-eclipse + bundle + + + + swt-repo + https://swt-repo.googlecode.com/svn/repo/ + + + + + + org.teavm + teavm-core + ${project.version} + + + org.teavm + teavm-chrome-rdp + ${project.version} + + + org.eclipse.core + runtime + 3.9.100-v20131218-1515 + + + org.eclipse.swt + org.eclipse.swt.win32.win32.x86 + 4.2.2 + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + org.teavm.eclipse.* + teavm-eclipse + + + + + + + \ No newline at end of file diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java new file mode 100644 index 000000000..0b6d5d4d5 --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/TeaVMEclipsePlugin.java @@ -0,0 +1,19 @@ +package org.teavm.eclipse; + +import org.eclipse.core.runtime.Plugin; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMEclipsePlugin extends Plugin { + private static TeaVMEclipsePlugin defaultInstance; + + public TeaVMEclipsePlugin() { + defaultInstance = this; + } + + public static TeaVMEclipsePlugin getDefault() { + return defaultInstance; + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java new file mode 100644 index 000000000..066ad68da --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugProcess.java @@ -0,0 +1,72 @@ +package org.teavm.eclipse.debugger; + +import java.util.HashMap; +import java.util.Map; +import org.eclipse.debug.core.DebugException; +import org.eclipse.debug.core.ILaunch; +import org.eclipse.debug.core.model.IProcess; +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 TeaVMDebugProcess(ILaunch launch) { + this.launch = launch; + } + + @Override + public Object getAdapter(Class arg0) { + return null; + } + + @Override + public boolean canTerminate() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public void terminate() throws DebugException { + } + + @Override + public String getAttribute(String attr) { + return attributes.get(attr); + } + + @Override + public int getExitValue() throws DebugException { + return 0; + } + + @Override + public String getLabel() { + return "TeaVM debug process"; + } + + @Override + public ILaunch getLaunch() { + return launch; + } + + @Override + public IStreamsProxy getStreamsProxy() { + return streamsProxy; + } + + @Override + public void setAttribute(String attr, String value) { + attributes.put(attr, value); + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java index 72004b57d..e91da3300 100644 --- a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMDebugTarget.java @@ -1,6 +1,10 @@ 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; @@ -8,11 +12,9 @@ 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; @@ -24,15 +26,19 @@ import org.teavm.debugging.DebuggerListener; */ @SuppressWarnings("rawtypes") public class TeaVMDebugTarget implements IDebugTarget { - private ILaunch launch; - private Debugger teavmDebugger; + ILaunch launch; + Debugger teavmDebugger; private ChromeRDPServer server; private boolean terminated; + private TeaVMDebugProcess process; + Map breakpointMap = new HashMap<>(); + Map breakpointBackMap = new HashMap<>(); public TeaVMDebugTarget(ILaunch launch, Debugger teavmDebugger, ChromeRDPServer server) { this.launch = launch; this.teavmDebugger = teavmDebugger; this.server = server; + this.process = new TeaVMDebugProcess(launch); teavmDebugger.addListener(new DebuggerListener() { @Override public void resumed() { @@ -50,7 +56,11 @@ public class TeaVMDebugTarget implements IDebugTarget { } @Override - public void breakpointStatusChanged(Breakpoint breakpoint) { + public void breakpointStatusChanged(Breakpoint teavmBreakpoint) { + IBreakpoint breakpoint = breakpointBackMap.get(teavmBreakpoint); + if (breakpoint != null) { + fireEvent(new DebugEvent(breakpoint, DebugEvent.CHANGE)); + } } @Override @@ -87,25 +97,35 @@ public class TeaVMDebugTarget implements IDebugTarget { @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()); + breakpoint.setRegistered(true); + int line = breakpoint.getMarker().getAttribute(IMarker.LINE_NUMBER, 1); + String fileName = getRelativePath(breakpoint.getMarker().getResource()); + teavmDebugger.createBreakpoint(fileName, line); } 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) { } @Override - public void breakpointRemoved(IBreakpoint arg0, IMarkerDelta arg1) { + public void breakpointRemoved(IBreakpoint breakpoint, IMarkerDelta markerDelta) { + Breakpoint teavmBreakpoint = breakpointMap.remove(breakpoint); + if (teavmBreakpoint != null) { + teavmBreakpoint.destroy(); + breakpointBackMap.remove(teavmBreakpoint); + } } @Override @@ -155,7 +175,7 @@ public class TeaVMDebugTarget implements IDebugTarget { @Override public String getModelIdentifier() { - return ""; + return "org.teavm.eclipse.debugger"; } @Override @@ -179,7 +199,7 @@ public class TeaVMDebugTarget implements IDebugTarget { @Override public IProcess getProcess() { - return null; + return process; } @Override @@ -189,11 +209,16 @@ public class TeaVMDebugTarget implements IDebugTarget { @Override public boolean hasThreads() throws DebugException { - return false; + return true; } @Override public boolean supportsBreakpoint(IBreakpoint breakpoint) { - return breakpoint instanceof IJavaLineBreakpoint; + try { + return breakpoint.getMarker().getAttribute(IMarker.LINE_NUMBER) != null; + } catch (CoreException e) { + // TODO: Log this exception + return false; + } } } diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java new file mode 100644 index 000000000..4018547c7 --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupDirector.java @@ -0,0 +1,15 @@ +package org.teavm.eclipse.debugger; + +import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupDirector; +import org.eclipse.debug.core.sourcelookup.ISourceLookupParticipant; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMSourceLookupDirector extends AbstractSourceLookupDirector { + @Override + public void initializeParticipants() { + addParticipants(new ISourceLookupParticipant[] { new TeaVMSourceLookupParticipant() }); + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java new file mode 100644 index 000000000..43c43bf73 --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMSourceLookupParticipant.java @@ -0,0 +1,21 @@ +package org.teavm.eclipse.debugger; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant; +import org.teavm.debugging.SourceLocation; + +/** + * + * @author Alexey Andreev + */ +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; + } + return null; + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java new file mode 100644 index 000000000..f97ffc367 --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStackFrame.java @@ -0,0 +1,158 @@ +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.teavm.debugging.CallFrame; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMStackFrame implements IStackFrame { + private TeaVMThread thread; + CallFrame callFrame; + + public TeaVMStackFrame(TeaVMThread thread, CallFrame callFrame) { + this.thread = thread; + this.callFrame = callFrame; + } + + @Override + public boolean canTerminate() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public void terminate() throws DebugException { + } + + @Override + public Object getAdapter(@SuppressWarnings("rawtypes") Class type) { + return null; + } + + @Override + public boolean canStepInto() { + return false; + } + + @Override + public boolean canStepOver() { + return false; + } + + @Override + public boolean canStepReturn() { + return false; + } + + @Override + public boolean isStepping() { + return false; + } + + @Override + public void stepInto() throws DebugException { + } + + @Override + public void stepOver() throws DebugException { + } + + @Override + public void stepReturn() throws DebugException { + } + + @Override + public boolean canResume() { + return false; + } + + @Override + public boolean canSuspend() { + return false; + } + + @Override + public boolean isSuspended() { + return false; + } + + @Override + public void resume() throws DebugException { + } + + @Override + public void suspend() throws DebugException { + } + + @Override + public IDebugTarget getDebugTarget() { + return thread.getDebugTarget(); + } + + @Override + public ILaunch getLaunch() { + return thread.getLaunch(); + } + + @Override + public String getModelIdentifier() { + return thread.getModelIdentifier(); + } + + @Override + public int getCharEnd() throws DebugException { + return -1; + } + + @Override + public int getCharStart() throws DebugException { + return -1; + } + + @Override + public int getLineNumber() throws DebugException { + return callFrame.getLocation() != null ? callFrame.getLocation().getLine() : -1; + } + + @Override + public String getName() throws DebugException { + return callFrame.getLocation() != null ? callFrame.getLocation().getFileName() : "unknown"; + } + + @Override + public IRegisterGroup[] getRegisterGroups() throws DebugException { + return null; + } + + @Override + public IThread getThread() { + return thread; + } + + @Override + public IVariable[] getVariables() throws DebugException { + return new IVariable[0]; + } + + @Override + public boolean hasRegisterGroups() throws DebugException { + return false; + } + + @Override + public boolean hasVariables() throws DebugException { + return true; + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java new file mode 100644 index 000000000..152fd0fb4 --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamMonitor.java @@ -0,0 +1,23 @@ +package org.teavm.eclipse.debugger; + +import org.eclipse.debug.core.IStreamListener; +import org.eclipse.debug.core.model.IStreamMonitor; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMStreamMonitor implements IStreamMonitor { + @Override + public void addListener(IStreamListener listener) { + } + + @Override + public String getContents() { + return ""; + } + + @Override + public void removeListener(IStreamListener arg0) { + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java new file mode 100644 index 000000000..51975a5de --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMStreamsProxy.java @@ -0,0 +1,26 @@ +package org.teavm.eclipse.debugger; + +import java.io.IOException; +import org.eclipse.debug.core.model.IStreamMonitor; +import org.eclipse.debug.core.model.IStreamsProxy; + +/** + * + * @author Alexey Andreev + */ +// TODO: implement interaction with browser console +public class TeaVMStreamsProxy implements IStreamsProxy { + @Override + public IStreamMonitor getErrorStreamMonitor() { + return new TeaVMStreamMonitor(); + } + + @Override + public IStreamMonitor getOutputStreamMonitor() { + return new TeaVMStreamMonitor(); + } + + @Override + public void write(String text) throws IOException { + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java new file mode 100644 index 000000000..d0181a89b --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/TeaVMThread.java @@ -0,0 +1,146 @@ +package org.teavm.eclipse.debugger; + +import org.eclipse.debug.core.DebugException; +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.Debugger; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMThread implements IThread { + private Debugger teavmDebugger; + private TeaVMDebugTarget debugTarget; + + public TeaVMThread(TeaVMDebugTarget debugTarget) { + this.debugTarget = debugTarget; + this.teavmDebugger = debugTarget.teavmDebugger; + } + + @Override + public boolean canTerminate() { + return false; + } + + @Override + public boolean isTerminated() { + return false; + } + + @Override + public void terminate() throws DebugException { + } + + @SuppressWarnings("rawtypes") + @Override + public Object getAdapter(Class type) { + return null; + } + + @Override + public boolean canResume() { + return false; + } + + @Override + public boolean canSuspend() { + return false; + } + + @Override + public boolean isSuspended() { + return teavmDebugger.isSuspended(); + } + + @Override + public void resume() throws DebugException { + } + + @Override + public void suspend() throws DebugException { + } + + @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 { + 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 debugTarget.getModelIdentifier(); + } + + @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 { + return 0; + } + + @Override + public IStackFrame[] getStackFrames() throws DebugException { + return null; + } + + @Override + public IStackFrame getTopStackFrame() throws DebugException { + return null; + } + + @Override + public boolean hasStackFrames() throws DebugException { + return true; + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java new file mode 100644 index 000000000..d33ea1315 --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTab.java @@ -0,0 +1,68 @@ +package org.teavm.eclipse.debugger.ui; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.debug.core.ILaunchConfiguration; +import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy; +import org.eclipse.debug.ui.AbstractLaunchConfigurationTab; +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ModifyEvent; +import org.eclipse.swt.events.ModifyListener; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Text; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMTab extends AbstractLaunchConfigurationTab { + private Text portField; + + @Override + public void createControl(Composite container) { + Composite root = new Composite(container, SWT.NONE); + GridLayout layout = new GridLayout(); + layout.verticalSpacing = 6; + layout.numColumns = 2; + root.setLayout(layout); + + Label portLabel = new Label(root, SWT.NONE); + portLabel.setText("&Port"); + portLabel.setLayoutData(new GridData(GridData.BEGINNING)); + + portField = new Text(root, SWT.SINGLE | SWT.BORDER); + portField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + portField.addModifyListener(new ModifyListener() { + @Override public void modifyText(ModifyEvent event) { + updateLaunchConfigurationDialog(); + } + }); + } + + @Override + public String getName() { + return null; + } + + @Override + public void initializeFrom(ILaunchConfiguration configuration) { + try { + int attr = configuration.getAttribute("teavm-debugger-port", 2357); + portField.setText(String.valueOf(attr)); + } catch (CoreException e) { + throw new RuntimeException(e); + } + } + + @Override + public void performApply(ILaunchConfigurationWorkingCopy configuration) { + configuration.setAttribute("teavm-debugger-port", Integer.parseInt(portField.getText())); + } + + @Override + public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { + configuration.setAttribute("teavm-debugger-port", 2357); + } +} diff --git a/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java new file mode 100644 index 000000000..1e67f7abe --- /dev/null +++ b/teavm-eclipse/src/main/java/org/teavm/eclipse/debugger/ui/TeaVMTabGroup.java @@ -0,0 +1,18 @@ +package org.teavm.eclipse.debugger.ui; + +import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup; +import org.eclipse.debug.ui.CommonTab; +import org.eclipse.debug.ui.ILaunchConfigurationDialog; +import org.eclipse.debug.ui.ILaunchConfigurationTab; +import org.eclipse.debug.ui.sourcelookup.SourceLookupTab; + +/** + * + * @author Alexey Andreev + */ +public class TeaVMTabGroup extends AbstractLaunchConfigurationTabGroup { + @Override + public void createTabs(ILaunchConfigurationDialog dialog, String mode) { + setTabs(new ILaunchConfigurationTab[] { new TeaVMTab(), new SourceLookupTab(), new CommonTab() }); + } +} diff --git a/teavm-eclipse/src/main/resources/plugin.xml b/teavm-eclipse/src/main/resources/plugin.xml new file mode 100644 index 000000000..1debbc4ee --- /dev/null +++ b/teavm-eclipse/src/main/resources/plugin.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + \ No newline at end of file