diff --git a/tools/chrome-rdp/pom.xml b/tools/chrome-rdp/pom.xml
index bad58b2e5..25cc8589f 100644
--- a/tools/chrome-rdp/pom.xml
+++ b/tools/chrome-rdp/pom.xml
@@ -54,7 +54,6 @@
com.fasterxml.jackson.core
jackson-databind
- true
diff --git a/tools/chrome-rdp/src/main/js/chrome/contentscript.js b/tools/chrome-rdp/src/main/js/chrome/contentscript.js
new file mode 100644
index 000000000..4e5149a5a
--- /dev/null
+++ b/tools/chrome-rdp/src/main/js/chrome/contentscript.js
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2018 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.
+ */
+
+window.addEventListener("message", function(event) {
+ if (event.source !== window) {
+ return;
+ }
+
+ var data = event.data;
+ if (typeof data.teavmDebugger !== "undefined") {
+ chrome.runtime.sendMessage({ command: "debug", port: data.teavmDebugger.port });
+ }
+}, false);
+window.postMessage({ teavmDebuggerRequest: true }, "*");
\ No newline at end of file
diff --git a/tools/chrome-rdp/src/main/js/chrome/main.js b/tools/chrome-rdp/src/main/js/chrome/main.js
index 1279ba1fa..7209a6969 100644
--- a/tools/chrome-rdp/src/main/js/chrome/main.js
+++ b/tools/chrome-rdp/src/main/js/chrome/main.js
@@ -1,15 +1,16 @@
debuggerAgentMap = {};
chrome.browserAction.onClicked.addListener(function(tab) {
- new DebuggerAgent(tab).attach();
+ new DebuggerAgent(tab, 2357).attach();
});
-function DebuggerAgent(tab) {
+function DebuggerAgent(tab, port) {
this.pendingMessages = [];
this.connection = null;
this.tab = null;
this.debuggee = { tabId : tab.id };
this.attachedToDebugger = false;
this.messageBuffer = "";
+ this.port = port;
debuggerAgentMap[tab.id] = this;
}
DebuggerAgent.MAX_MESSAGE_SIZE = 65534;
@@ -20,12 +21,12 @@ DebuggerAgent.prototype.attach = function() {
}.bind(this, this.connectToServer.bind(this)));
};
DebuggerAgent.prototype.connectToServer = function() {
- this.connection = new WebSocket("ws://localhost:2357/");
+ this.connection = new WebSocket("ws://localhost:" + this.port + "/");
this.connection.onmessage = function(event) {
var str = event.data;
var ctl = str.substring(0, 1);
this.messageBuffer += str.substring(1);
- if (ctl == '.') {
+ if (ctl === '.') {
this.receiveMessage(JSON.parse(this.messageBuffer));
this.messageBuffer = "";
}
@@ -95,4 +96,10 @@ chrome.debugger.onDetach.addListener(function(source) {
agent.attachedToDebugger = false;
agent.disconnect();
}
+});
+
+chrome.runtime.onMessage.addListener(function(message, sender, callback) {
+ if (message.command === "debug") {
+ new DebuggerAgent(sender.tab, message.port).attach();
+ }
});
\ No newline at end of file
diff --git a/tools/chrome-rdp/src/main/js/chrome/manifest.json b/tools/chrome-rdp/src/main/js/chrome/manifest.json
index c9931916d..5972d3972 100644
--- a/tools/chrome-rdp/src/main/js/chrome/manifest.json
+++ b/tools/chrome-rdp/src/main/js/chrome/manifest.json
@@ -3,9 +3,9 @@
"name": "TeaVM debugger agent",
"description": "TeaVM debugger agent, that sends RDP commands over WebSocket",
- "version": "0.2",
+ "version": "0.6.0",
- "permissions" : ["debugger", "activeTab", "tabs"],
+ "permissions" : ["debugger", "activeTab", "tabs", "*://*/*"],
"browser_action" : {
"default_icon": "teavm-16.png",
@@ -14,5 +14,12 @@
"background": {
"scripts": ["main.js"]
- }
+ },
+
+ "content_scripts": [
+ {
+ "matches": ["http://*/*", "https://*/*", "file://*/*"],
+ "js": ["contentscript.js"]
+ }
+ ]
}
\ No newline at end of file
diff --git a/tools/devserver/src/main/java/org/teavm/devserver/CodeServlet.java b/tools/devserver/src/main/java/org/teavm/devserver/CodeServlet.java
index 608bb8895..5c4eee0d9 100644
--- a/tools/devserver/src/main/java/org/teavm/devserver/CodeServlet.java
+++ b/tools/devserver/src/main/java/org/teavm/devserver/CodeServlet.java
@@ -79,6 +79,7 @@ public class CodeServlet extends HttpServlet {
private boolean indicator;
private boolean automaticallyReloaded;
private int port;
+ private int debugPort;
private Map> sourceFileCache = new HashMap<>();
@@ -138,6 +139,10 @@ public class CodeServlet extends HttpServlet {
this.port = port;
}
+ public void setDebugPort(int debugPort) {
+ this.debugPort = debugPort;
+ }
+
public void setAutomaticallyReloaded(boolean automaticallyReloaded) {
this.automaticallyReloaded = automaticallyReloaded;
}
@@ -450,10 +455,6 @@ public class CodeServlet extends HttpServlet {
}
private void addIndicator() {
- if (!indicator) {
- return;
- }
-
String script = getIndicatorScript(false);
try (Writer writer = new OutputStreamWriter(buildTarget.appendToResource(fileName), StandardCharsets.UTF_8)) {
writer.append("\n");
@@ -472,6 +473,8 @@ public class CodeServlet extends HttpServlet {
script = script.replace("BOOT_FLAG", Boolean.toString(boot));
script = script.replace("RELOAD_FLAG", Boolean.toString(automaticallyReloaded));
script = script.replace("FILE_NAME", "http://localhost:" + port + pathToFile + fileName);
+ script = script.replace("INDICATOR_FLAG", Boolean.toString(indicator));
+ script = script.replace("DEBUG_PORT", Integer.toString(debugPort));
return script;
} catch (IOException e) {
throw new RuntimeException("IO error occurred writing debug information", e);
diff --git a/tools/devserver/src/main/java/org/teavm/devserver/DevServer.java b/tools/devserver/src/main/java/org/teavm/devserver/DevServer.java
index c7b499f6d..a30a58a6a 100644
--- a/tools/devserver/src/main/java/org/teavm/devserver/DevServer.java
+++ b/tools/devserver/src/main/java/org/teavm/devserver/DevServer.java
@@ -46,6 +46,7 @@ public class DevServer {
private Server server;
private int port = 9090;
+ private int debugPort;
public void setMainClass(String mainClass) {
this.mainClass = mainClass;
@@ -59,6 +60,10 @@ public class DevServer {
this.port = port;
}
+ public void setDebugPort(int debugPort) {
+ this.debugPort = debugPort;
+ }
+
public void setPathToFile(String pathToFile) {
if (!pathToFile.startsWith("/")) {
pathToFile = "/" + pathToFile;
@@ -122,6 +127,7 @@ public class DevServer {
servlet.setIndicator(indicator);
servlet.setAutomaticallyReloaded(reloadedAutomatically);
servlet.setPort(port);
+ servlet.setDebugPort(debugPort);
for (DevServerListener listener : listeners) {
servlet.addListener(listener);
}
diff --git a/tools/devserver/src/main/resources/org/teavm/devserver/indicator.js b/tools/devserver/src/main/resources/org/teavm/devserver/indicator.js
index 539041f3c..c330209c0 100644
--- a/tools/devserver/src/main/resources/org/teavm/devserver/indicator.js
+++ b/tools/devserver/src/main/resources/org/teavm/devserver/indicator.js
@@ -16,6 +16,8 @@
(function () {
var boot = BOOT_FLAG;
var reload = RELOAD_FLAG;
+ var indicatorVisible = INDICATOR_FLAG;
+ var debugPort = DEBUG_PORT;
function createWebSocket() {
var loc = window.location;
@@ -121,10 +123,12 @@
document.body.appendChild(indicator.container);
}
- if (document.body) {
- onLoad();
- } else {
- window.addEventListener("load", onLoad);
+ if (indicatorVisible) {
+ if (document.body) {
+ onLoad();
+ } else {
+ window.addEventListener("load", onLoad);
+ }
}
function startMain() {
@@ -164,4 +168,17 @@
if (boot) {
indicator.show("File is not ready, about to compile");
}
+
+ if (debugPort > 0) {
+ function connectDebugAgent(event) {
+ if (event.source !== window) {
+ return;
+ }
+ var data = event.data;
+ if (typeof data.teavmDebuggerRequest !== "undefined") {
+ window.postMessage({teavmDebugger: {port: debugPort}}, "*");
+ }
+ }
+ window.addEventListener("message", connectDebugAgent);
+ }
})();
\ No newline at end of file
diff --git a/tools/idea/idea-artifacts/dep-pom.xml b/tools/idea/idea-artifacts/dep-pom.xml
index f564b4289..7ce219eb0 100644
--- a/tools/idea/idea-artifacts/dep-pom.xml
+++ b/tools/idea/idea-artifacts/dep-pom.xml
@@ -94,7 +94,7 @@
+ dest="${basedir}/dependencies/scala.zip" skipexisting="true"/>
diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/debug/TeaVMDebugProcess.java b/tools/idea/plugin/src/main/java/org/teavm/idea/debug/TeaVMDebugProcess.java
index 1abe59711..c9f8ffc9a 100644
--- a/tools/idea/plugin/src/main/java/org/teavm/idea/debug/TeaVMDebugProcess.java
+++ b/tools/idea/plugin/src/main/java/org/teavm/idea/debug/TeaVMDebugProcess.java
@@ -16,6 +16,8 @@
package org.teavm.idea.debug;
import com.intellij.debugger.ui.breakpoints.JavaLineBreakpointType;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.extensions.ExtensionPoint;
import com.intellij.openapi.extensions.Extensions;
@@ -49,6 +51,7 @@ public class TeaVMDebugProcess extends XDebugProcess {
private final int port;
private ChromeRDPServer debugServer;
ConcurrentMap> breakpointMap = new ConcurrentHashMap<>();
+ public ExecutionConsole console;
public TeaVMDebugProcess(@NotNull XDebugSession session, int port) {
super(session);
@@ -188,4 +191,10 @@ public class TeaVMDebugProcess extends XDebugProcess {
public XBreakpointHandler>[] getBreakpointHandlers() {
return breakpointHandlers.toArray(new XBreakpointHandler>[0]);
}
+
+ @NotNull
+ @Override
+ public ExecutionConsole createConsole() {
+ return console != null ? console : super.createConsole();
+ }
}
diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/DevServerConfiguration.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/DevServerConfiguration.java
index 656ce43ff..e332883b0 100644
--- a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/DevServerConfiguration.java
+++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/DevServerConfiguration.java
@@ -26,4 +26,5 @@ public class DevServerConfiguration {
public int port;
public String pathToFile;
public String fileName;
+ public int debugPort;
}
diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/DevServerRunner.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/DevServerRunner.java
index ac0ffff1e..fc9c87c23 100644
--- a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/DevServerRunner.java
+++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/DevServerRunner.java
@@ -125,6 +125,9 @@ public class DevServerRunner extends UnicastRemoteObject implements DevServerMan
case "-f":
server.setFileName(args[++i]);
break;
+ case "-P":
+ server.setDebugPort(Integer.parseInt(args[++i]));
+ break;
}
}
server.setClassPath(classPath.toArray(new String[0]));
@@ -179,6 +182,11 @@ public class DevServerRunner extends UnicastRemoteObject implements DevServerMan
arguments.add(entry);
}
+ if (options.debugPort > 0) {
+ arguments.add("-P");
+ arguments.add(Integer.toString(options.debugPort));
+ }
+
ProcessBuilder builder = new ProcessBuilder(arguments.toArray(new String[0]));
Process process = builder.start();
BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream(),
diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunState.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunState.java
index 2641eec53..b8a4056bf 100644
--- a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunState.java
+++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunState.java
@@ -21,12 +21,11 @@ import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.SearchScopeProvider;
+import com.intellij.execution.executors.DefaultDebugExecutor;
import com.intellij.execution.filters.TextConsoleBuilder;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
-import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.ProgramRunner;
-import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.util.JavaParametersUtil;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.project.Project;
@@ -36,24 +35,24 @@ import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import java.io.IOException;
-import java.io.OutputStream;
+import java.net.Socket;
import java.util.Arrays;
import java.util.Objects;
+import java.util.Random;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import org.teavm.idea.DaemonUtil;
-import org.teavm.idea.DevServerRunnerListener;
import org.teavm.idea.devserver.ui.TeaVMDevServerConsole;
public class TeaVMDevServerRunState implements RunProfileState {
private final TeaVMDevServerConfiguration configuration;
private final TextConsoleBuilder consoleBuilder;
+ private final Project project;
public TeaVMDevServerRunState(@NotNull ExecutionEnvironment environment,
@NotNull TeaVMDevServerConfiguration configuration) {
this.configuration = configuration;
- Project project = environment.getProject();
+ project = environment.getProject();
GlobalSearchScope searchScope = SearchScopeProvider.createSearchScope(project, environment.getRunProfile());
consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project, searchScope);
}
@@ -83,15 +82,44 @@ public class TeaVMDevServerRunState implements RunProfileState {
config.mainClass = configuration.getMainClass();
config.maxHeap = configuration.getMaxHeap();
+ if (executor.getId().equals(DefaultDebugExecutor.EXECUTOR_ID)) {
+ config.debugPort = choosePort();
+ }
+
+ TeaVMProcessHandler processHandler;
+ ExecutionResult executionResult;
try {
TeaVMDevServerConsole console = new TeaVMDevServerConsole(consoleBuilder.getConsole());
- ProcessHandlerImpl processHandler = new ProcessHandlerImpl(config, console);
+ processHandler = new TeaVMProcessHandler(config, console);
console.getUnderlyingConsole().attachToProcess(processHandler);
processHandler.start();
- return new DefaultExecutionResult(console, processHandler);
+ executionResult = new DefaultExecutionResult(console, processHandler);
} catch (IOException e) {
throw new ExecutionException(e);
}
+
+ return executionResult;
+ }
+
+ private int choosePort() {
+ Random random = new Random();
+ int minPort = 10000;
+ int maxPort = 1 << 16;
+ for (int i = 0; i < 20; ++i) {
+ int port = minPort + random.nextInt(maxPort - minPort);
+ if (isPortAvailable(port)) {
+ return port;
+ }
+ }
+ throw new RuntimeException("Could not find available port");
+ }
+
+ private boolean isPortAvailable(int port) {
+ try (Socket ignored = new Socket("localhost", port)) {
+ return false;
+ } catch (IOException ignored) {
+ return true;
+ }
}
private String path(VirtualFile file) {
@@ -103,63 +131,4 @@ public class TeaVMDevServerRunState implements RunProfileState {
}
return file.getCanonicalPath();
}
-
- class ProcessHandlerImpl extends ProcessHandler implements DevServerRunnerListener {
- private DevServerConfiguration config;
- private TeaVMDevServerConsole console;
- private DevServerInfo info;
-
- ProcessHandlerImpl(DevServerConfiguration config, TeaVMDevServerConsole console) {
- this.config = config;
- this.console = console;
- }
-
- void start() throws IOException {
- info = DevServerRunner.start(DaemonUtil.detectClassPath().toArray(new String[0]), config, this);
- console.setServerManager(info.server);
- startNotify();
- }
-
- @Override
- protected void destroyProcessImpl() {
- info.process.destroy();
- }
-
- @Override
- protected void detachProcessImpl() {
- try {
- info.server.stop();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- @Override
- public boolean detachIsDefault() {
- return true;
- }
-
- @Nullable
- @Override
- public OutputStream getProcessInput() {
- return null;
- }
-
-
- @Override
- public void error(String text) {
- console.getUnderlyingConsole().print(text + System.lineSeparator(), ConsoleViewContentType.ERROR_OUTPUT);
- }
-
- @Override
- public void info(String text) {
- console.getUnderlyingConsole().print(text + System.lineSeparator(), ConsoleViewContentType.NORMAL_OUTPUT);
- }
-
- @Override
- public void stopped(int code) {
- console.stop();
- notifyProcessTerminated(code);
- }
- }
}
diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunner.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunner.java
index 588f8e554..2ed37ea36 100644
--- a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunner.java
+++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMDevServerRunner.java
@@ -20,11 +20,21 @@ import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.configurations.RunnerSettings;
+import com.intellij.execution.process.ProcessAdapter;
+import com.intellij.execution.process.ProcessEvent;
+import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ExecutionEnvironment;
import com.intellij.execution.runners.GenericProgramRunner;
+import com.intellij.execution.runners.RunContentBuilder;
+import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.xdebugger.XDebugProcess;
+import com.intellij.xdebugger.XDebugProcessStarter;
+import com.intellij.xdebugger.XDebugSession;
+import com.intellij.xdebugger.XDebuggerManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import org.teavm.idea.debug.TeaVMDebugProcess;
public class TeaVMDevServerRunner extends GenericProgramRunner {
@NotNull
@@ -47,6 +57,32 @@ public class TeaVMDevServerRunner extends GenericProgramRunner {
return null;
}
- return null;
+ RunContentDescriptor runContent = new RunContentBuilder(executionResult, environment).showRunContent(null);
+ int debugPort = ((TeaVMProcessHandler) executionResult.getProcessHandler()).config.debugPort;
+ ExecutionConsole console = runContent.getExecutionConsole();
+ ProcessHandler processHandler = runContent.getProcessHandler();
+ if (debugPort > 0) {
+ XDebuggerManager debuggerManager = XDebuggerManager.getInstance(environment.getProject());
+ XDebugSession debugSession = debuggerManager.startSession(environment, new XDebugProcessStarter() {
+ @NotNull
+ @Override
+ public XDebugProcess start(@NotNull XDebugSession session) {
+ TeaVMDebugProcess debugProcess = new TeaVMDebugProcess(session, debugPort);
+ debugProcess.console = console;
+ return debugProcess;
+ }
+ });
+ runContent = debugSession.getRunContentDescriptor();
+
+ ProcessHandler debugProcessHandler = debugSession.getDebugProcess().getProcessHandler();
+ debugProcessHandler.addProcessListener(new ProcessAdapter() {
+ @Override
+ public void processTerminated(@NotNull ProcessEvent event) {
+ processHandler.destroyProcess();
+ }
+ });
+ }
+
+ return runContent;
}
}
diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMProcessHandler.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMProcessHandler.java
new file mode 100644
index 000000000..a82c30410
--- /dev/null
+++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/TeaVMProcessHandler.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2018 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.idea.devserver;
+
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.ui.ConsoleViewContentType;
+import java.io.IOException;
+import java.io.OutputStream;
+import org.jetbrains.annotations.Nullable;
+import org.teavm.idea.DaemonUtil;
+import org.teavm.idea.DevServerRunnerListener;
+import org.teavm.idea.devserver.ui.TeaVMDevServerConsole;
+
+class TeaVMProcessHandler extends ProcessHandler implements DevServerRunnerListener {
+ DevServerConfiguration config;
+ private TeaVMDevServerConsole console;
+ private DevServerInfo info;
+
+ TeaVMProcessHandler(DevServerConfiguration config, TeaVMDevServerConsole console) {
+ this.config = config;
+ this.console = console;
+ }
+
+ void start() throws IOException {
+ info = DevServerRunner.start(DaemonUtil.detectClassPath().toArray(new String[0]), config, this);
+ console.setServerManager(info.server);
+ startNotify();
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> info.process.destroy()));
+ }
+
+ @Override
+ protected void destroyProcessImpl() {
+ info.process.destroy();
+ }
+
+ @Override
+ protected void detachProcessImpl() {
+ try {
+ info.server.stop();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public boolean detachIsDefault() {
+ return true;
+ }
+
+ @Nullable
+ @Override
+ public OutputStream getProcessInput() {
+ return null;
+ }
+
+
+ @Override
+ public void error(String text) {
+ console.getUnderlyingConsole().print(text + System.lineSeparator(), ConsoleViewContentType.ERROR_OUTPUT);
+ }
+
+ @Override
+ public void info(String text) {
+ console.getUnderlyingConsole().print(text + System.lineSeparator(), ConsoleViewContentType.NORMAL_OUTPUT);
+ }
+
+ @Override
+ public void stopped(int code) {
+ console.stop();
+ notifyProcessTerminated(code);
+ }
+}
diff --git a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerConsole.java b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerConsole.java
index 4c03ee508..c9e4665cc 100644
--- a/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerConsole.java
+++ b/tools/idea/plugin/src/main/java/org/teavm/idea/devserver/ui/TeaVMDevServerConsole.java
@@ -15,8 +15,12 @@
*/
package org.teavm.idea.devserver.ui;
+import com.intellij.execution.filters.Filter;
+import com.intellij.execution.filters.HyperlinkInfo;
+import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.ConsoleView;
-import com.intellij.execution.ui.ExecutionConsole;
+import com.intellij.execution.ui.ConsoleViewContentType;
+import com.intellij.openapi.actionSystem.AnAction;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.rmi.RemoteException;
@@ -26,11 +30,13 @@ import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.teavm.idea.devserver.DevServerBuildResult;
import org.teavm.idea.devserver.DevServerManager;
import org.teavm.idea.devserver.DevServerManagerListener;
-public class TeaVMDevServerConsole extends JPanel implements ExecutionConsole {
+public class TeaVMDevServerConsole extends JPanel implements ConsoleView {
private ConsoleView underlyingConsole;
private DevServerManager serverManager;
private ServerListenerImpl serverListener;
@@ -135,6 +141,82 @@ public class TeaVMDevServerConsole extends JPanel implements ExecutionConsole {
rebuildButton.setEnabled(false);
}
+ @Override
+ public void print(@NotNull String s, @NotNull ConsoleViewContentType consoleViewContentType) {
+ underlyingConsole.print(s, consoleViewContentType);
+ }
+
+ @Override
+ public void clear() {
+ underlyingConsole.clear();
+ }
+
+ @Override
+ public void scrollTo(int i) {
+ underlyingConsole.scrollTo(i);
+ }
+
+ @Override
+ public void attachToProcess(ProcessHandler processHandler) {
+ underlyingConsole.attachToProcess(processHandler);
+ }
+
+ @Override
+ public void setOutputPaused(boolean b) {
+ underlyingConsole.setOutputPaused(b);
+ }
+
+ @Override
+ public boolean isOutputPaused() {
+ return underlyingConsole.isOutputPaused();
+ }
+
+ @Override
+ public boolean hasDeferredOutput() {
+ return underlyingConsole.hasDeferredOutput();
+ }
+
+ @Override
+ public void performWhenNoDeferredOutput(@NotNull Runnable runnable) {
+ underlyingConsole.performWhenNoDeferredOutput(runnable);
+ }
+
+ @Override
+ public void setHelpId(@NotNull String s) {
+ underlyingConsole.setHelpId(s);
+ }
+
+ @Override
+ public void addMessageFilter(@NotNull Filter filter) {
+ underlyingConsole.addMessageFilter(filter);
+ }
+
+ @Override
+ public void printHyperlink(@NotNull String s, @Nullable HyperlinkInfo hyperlinkInfo) {
+ underlyingConsole.printHyperlink(s, hyperlinkInfo);
+ }
+
+ @Override
+ public int getContentSize() {
+ return underlyingConsole.getContentSize();
+ }
+
+ @Override
+ public boolean canPause() {
+ return underlyingConsole.canPause();
+ }
+
+ @NotNull
+ @Override
+ public AnAction[] createConsoleActions() {
+ return underlyingConsole.createConsoleActions();
+ }
+
+ @Override
+ public void allowHeavyFilters() {
+ underlyingConsole.allowHeavyFilters();
+ }
+
class ServerListenerImpl extends UnicastRemoteObject implements DevServerManagerListener {
private NumberFormat percentFormat = NumberFormat.getPercentInstance();