From 40e06a573c33c4c39ca6024e7037c15264d7a9fc Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Wed, 27 Apr 2016 22:53:21 +0300 Subject: [PATCH] Add TeaVM debug server run configuration --- tools/idea/jps-plugin/pom.xml | 16 +++++ ...tion.java => TeaVMDebugConfiguration.java} | 23 ++++-- .../debug/TeaVMDebugConfigurationType.java | 43 +++++++++++ .../teavm/idea/debug/TeaVMDebugProcess.java | 19 +++-- .../teavm/idea/debug/TeaVMDebugRunner.java | 25 +++---- .../org/teavm/idea/debug/TeaVMRunState.java | 55 ++++++++++++++ .../debug/ui/TeaVMDebugSettingsEditor.java | 42 +++++++++++ .../debug/ui/TeaVMDebugSettingsPanel.java | 68 ++++++++++++++++++ .../src/main/resources/META-INF/plugin.xml | 1 + tools/idea/src/main/resources/teavm-16.png | Bin 0 -> 713 bytes 10 files changed, 265 insertions(+), 27 deletions(-) rename tools/idea/src/main/java/org/teavm/idea/debug/{TeaVMDebugRunConfiguration.java => TeaVMDebugConfiguration.java} (69%) create mode 100644 tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugConfigurationType.java create mode 100644 tools/idea/src/main/java/org/teavm/idea/debug/TeaVMRunState.java create mode 100644 tools/idea/src/main/java/org/teavm/idea/debug/ui/TeaVMDebugSettingsEditor.java create mode 100644 tools/idea/src/main/java/org/teavm/idea/debug/ui/TeaVMDebugSettingsPanel.java create mode 100644 tools/idea/src/main/resources/teavm-16.png diff --git a/tools/idea/jps-plugin/pom.xml b/tools/idea/jps-plugin/pom.xml index da1c688c9..a330432ce 100644 --- a/tools/idea/jps-plugin/pom.xml +++ b/tools/idea/jps-plugin/pom.xml @@ -33,11 +33,23 @@ org.teavm teavm-tooling ${project.version} + + + org.slf4j + slf4j-api + + org.teavm teavm-chrome-rdp ${project.version} + + + org.slf4j + slf4j-api + + @@ -60,6 +72,10 @@ org.objectweb.asm org.teavm.asm + + org.objectweb.asm + org.teavm.asm + diff --git a/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugRunConfiguration.java b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugConfiguration.java similarity index 69% rename from tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugRunConfiguration.java rename to tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugConfiguration.java index 32fccaf80..676e5e545 100644 --- a/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugRunConfiguration.java +++ b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugConfiguration.java @@ -22,26 +22,39 @@ import com.intellij.execution.configurations.LocatableConfigurationBase; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.RunConfigurationWithSuppressedDefaultRunAction; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.teavm.idea.debug.ui.TeaVMDebugSettingsEditor; -public class TeaVMDebugRunConfiguration extends LocatableConfigurationBase { - public TeaVMDebugRunConfiguration(Project project, @NotNull ConfigurationFactory factory, String name) { - super(project, factory, name); +public class TeaVMDebugConfiguration extends LocatableConfigurationBase + implements RunConfigurationWithSuppressedDefaultRunAction { + private int port = 2357; + + public TeaVMDebugConfiguration(Project project, @NotNull ConfigurationFactory factory) { + super(project, factory, "TeaVM debug server"); } @NotNull @Override public SettingsEditor getConfigurationEditor() { - return null; + return new TeaVMDebugSettingsEditor(); } @Nullable @Override public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws ExecutionException { - return null; + return new TeaVMRunState(environment, port); + } + + public int getPort() { + return port; + } + + public void setPort(int port) { + this.port = port; } } diff --git a/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugConfigurationType.java b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugConfigurationType.java new file mode 100644 index 000000000..366ac975b --- /dev/null +++ b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugConfigurationType.java @@ -0,0 +1,43 @@ +/* + * Copyright 2016 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.debug; + +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationTypeBase; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.IconLoader; +import org.jetbrains.annotations.NotNull; + +public class TeaVMDebugConfigurationType extends ConfigurationTypeBase { + public TeaVMDebugConfigurationType() { + super("TeaVMDebugConfiguration", "TeaVM debug server", "Debug server that expects connection from browser " + + "agent", IconLoader.getIcon("/teavm-16.png")); + } + + private final ConfigurationFactory factory = new ConfigurationFactory(this) { + @NotNull + @Override + public RunConfiguration createTemplateConfiguration(@NotNull Project project) { + return new TeaVMDebugConfiguration(project, this); + } + }; + + @Override + public ConfigurationFactory[] getConfigurationFactories() { + return new ConfigurationFactory[] { factory }; + } +} diff --git a/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugProcess.java b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugProcess.java index cfacd5407..ceb73c1fd 100644 --- a/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugProcess.java +++ b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugProcess.java @@ -32,11 +32,14 @@ import org.teavm.debugging.information.URLDebugInformationProvider; public class TeaVMDebugProcess extends XDebugProcess { public static final Key INNER_BREAKPOINT_KEY = new Key<>("TeaVM breakpoint"); private TeaVMDebuggerEditorsProvider editorsProvider; - private Debugger innerDebugger; - private TeaVMLineBreakpointHandler breakpointHandler; + private final Debugger innerDebugger; + private final TeaVMLineBreakpointHandler breakpointHandler; + private final int port; + private ChromeRDPServer debugServer; - public TeaVMDebugProcess(@NotNull XDebugSession session) { + public TeaVMDebugProcess(@NotNull XDebugSession session, int port) { super(session); + this.port = port; innerDebugger = initDebugger(); innerDebugger.addListener(new DebuggerListener() { @Override @@ -66,12 +69,13 @@ public class TeaVMDebugProcess extends XDebugProcess { } private Debugger initDebugger() { - ChromeRDPServer debugServer = new ChromeRDPServer(); - debugServer.setPort(2357); + debugServer = new ChromeRDPServer(); + debugServer.setPort(port); ChromeRDPDebugger chromeDebugger = new ChromeRDPDebugger(); debugServer.setExchangeConsumer(chromeDebugger); editorsProvider = new TeaVMDebuggerEditorsProvider(); + new Thread(debugServer::start).start(); return new Debugger(chromeDebugger, new URLDebugInformationProvider("")); } @@ -101,6 +105,11 @@ public class TeaVMDebugProcess extends XDebugProcess { innerDebugger.resume(); } + @Override + public void stop() { + debugServer.stop(); + } + @Override public void runToPosition(@NotNull XSourcePosition position) { innerDebugger.continueToLocation(position.getFile().getPath(), position.getLine()); diff --git a/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugRunner.java b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugRunner.java index 79f2327d7..069413609 100644 --- a/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugRunner.java +++ b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMDebugRunner.java @@ -16,18 +16,15 @@ package org.teavm.idea.debug; import com.intellij.execution.ExecutionException; +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.executors.DefaultDebugExecutor; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.GenericProgramRunner; +import com.intellij.execution.runners.RunContentBuilder; import com.intellij.execution.ui.RunContentDescriptor; -import com.intellij.openapi.fileEditor.FileDocumentManager; -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; @@ -40,24 +37,18 @@ public class TeaVMDebugRunner extends GenericProgramRunner { @Override public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) { - return !DefaultDebugExecutor.EXECUTOR_ID.equals(executorId); + return DefaultDebugExecutor.EXECUTOR_ID.equals(executorId) && profile instanceof TeaVMDebugConfiguration; } @Nullable @Override protected RunContentDescriptor doExecute(@NotNull RunProfileState state, @NotNull ExecutionEnvironment environment) throws ExecutionException { - FileDocumentManager.getInstance().saveAllDocuments(); + ExecutionResult executionResult = state.execute(environment.getExecutor(), environment.getRunner()); + if (executionResult == null) { + return null; + } - XDebuggerManager debuggerManager = XDebuggerManager.getInstance(environment.getProject()); - debuggerManager.startSession(environment, new XDebugProcessStarter() { - @NotNull - @Override - public XDebugProcess start(@NotNull XDebugSession session) throws ExecutionException { - return new TeaVMDebugProcess(session); - } - }); - - return super.doExecute(state, environment); + return new RunContentBuilder(executionResult, environment).showRunContent(environment.getContentToReuse()); } } diff --git a/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMRunState.java b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMRunState.java new file mode 100644 index 000000000..e29ce337a --- /dev/null +++ b/tools/idea/src/main/java/org/teavm/idea/debug/TeaVMRunState.java @@ -0,0 +1,55 @@ +/* + * Copyright 2016 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.debug; + +import com.intellij.execution.DefaultExecutionResult; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ProgramRunner; +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; + +class TeaVMRunState implements RunProfileState { + private final ExecutionEnvironment environment; + private final int port; + + public TeaVMRunState(ExecutionEnvironment executionEnvironment, int port) { + this.environment = executionEnvironment; + this.port = port; + } + + @Nullable + @Override + public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException { + XDebuggerManager debuggerManager = XDebuggerManager.getInstance(environment.getProject()); + XDebugSession session = debuggerManager.startSession(environment, new XDebugProcessStarter() { + @NotNull + @Override + public XDebugProcess start(@NotNull XDebugSession session) throws ExecutionException { + return new TeaVMDebugProcess(session, port); + } + }); + + return new DefaultExecutionResult(session.getConsoleView(), session.getDebugProcess().getProcessHandler()); + } +} diff --git a/tools/idea/src/main/java/org/teavm/idea/debug/ui/TeaVMDebugSettingsEditor.java b/tools/idea/src/main/java/org/teavm/idea/debug/ui/TeaVMDebugSettingsEditor.java new file mode 100644 index 000000000..9395784ce --- /dev/null +++ b/tools/idea/src/main/java/org/teavm/idea/debug/ui/TeaVMDebugSettingsEditor.java @@ -0,0 +1,42 @@ +/* + * Copyright 2016 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.debug.ui; + +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditor; +import javax.swing.JComponent; +import org.jetbrains.annotations.NotNull; +import org.teavm.idea.debug.TeaVMDebugConfiguration; + +public class TeaVMDebugSettingsEditor extends SettingsEditor { + private final TeaVMDebugSettingsPanel panel = new TeaVMDebugSettingsPanel(); + + @Override + protected void resetEditorFrom(TeaVMDebugConfiguration s) { + panel.load(s); + } + + @Override + protected void applyEditorTo(TeaVMDebugConfiguration s) throws ConfigurationException { + panel.save(s); + } + + @NotNull + @Override + protected JComponent createEditor() { + return panel; + } +} diff --git a/tools/idea/src/main/java/org/teavm/idea/debug/ui/TeaVMDebugSettingsPanel.java b/tools/idea/src/main/java/org/teavm/idea/debug/ui/TeaVMDebugSettingsPanel.java new file mode 100644 index 000000000..f9b5e4d02 --- /dev/null +++ b/tools/idea/src/main/java/org/teavm/idea/debug/ui/TeaVMDebugSettingsPanel.java @@ -0,0 +1,68 @@ +/* + * Copyright 2016 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.debug.ui; + +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.ui.components.JBLabel; +import com.intellij.ui.components.JBTextField; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import javax.swing.JPanel; +import org.teavm.idea.debug.TeaVMDebugConfiguration; + +class TeaVMDebugSettingsPanel extends JPanel { + private final JBTextField portField = new JBTextField(); + + public TeaVMDebugSettingsPanel() { + GridBagConstraints labelConstraints = new GridBagConstraints(); + labelConstraints.gridwidth = GridBagConstraints.REMAINDER; + labelConstraints.anchor = GridBagConstraints.BASELINE_LEADING; + labelConstraints.weightx = 1; + labelConstraints.weighty = 1; + labelConstraints.insets.left = 5; + labelConstraints.insets.right = 5; + + GridBagConstraints descriptionConstraints = (GridBagConstraints) labelConstraints.clone(); + descriptionConstraints.fill = GridBagConstraints.BOTH; + descriptionConstraints.anchor = GridBagConstraints.BASELINE_LEADING; + descriptionConstraints.insets.top = 3; + + setLayout(new GridBagLayout()); + + add(bold(new JBLabel("Listen port:")), labelConstraints); + add(portField); + } + + public void load(TeaVMDebugConfiguration runConfiguration) { + portField.setText(String.valueOf(runConfiguration.getPort())); + } + + private static JBLabel bold(JBLabel label) { + label.setFont(label.getFont().deriveFont(Font.BOLD)); + return label; + } + + public void save(TeaVMDebugConfiguration runConfiguration) throws ConfigurationException { + int port; + try { + port = Integer.parseInt(portField.getText()); + } catch (NumberFormatException e) { + throw new ConfigurationException("Port is not a number"); + } + runConfiguration.setPort(port); + } +} diff --git a/tools/idea/src/main/resources/META-INF/plugin.xml b/tools/idea/src/main/resources/META-INF/plugin.xml index 4bddb9f23..7cea7813b 100644 --- a/tools/idea/src/main/resources/META-INF/plugin.xml +++ b/tools/idea/src/main/resources/META-INF/plugin.xml @@ -31,6 +31,7 @@ serviceImplementation="org.teavm.idea.TeaVMConfigurationStorage"/> + diff --git a/tools/idea/src/main/resources/teavm-16.png b/tools/idea/src/main/resources/teavm-16.png new file mode 100644 index 0000000000000000000000000000000000000000..4afead66beceb92f32dce28de5a6918d92ccd47a GIT binary patch literal 713 zcmV;)0yh1LP)x zK~y-)os-W?R8bVizvtfj-o0(HAZpIQM+`o_o#(Gvl!1_CUBk z7Tg}3Xmp2}A<#e~i#swy7i6AZ;0QGY5a>x^!i5bmrhO^_fcA;Z0KLf!i%sp*#fAXw z(`96V+=znifDtZDYM-R==z&*Mqq*}=tJ@}Cd;MbKPylI~^*SV~Q4CXbh!n0d;kMI4 zH*~vbDzC+9rlgLMgE{hsiT@R*JKPOG!l6~KL>gd_LlB9??x(ogJmTo`QnJYj?&~4U z2FnN(GuHE$oX*TSnfd-ST(luSGrd9%+$v%#`~d){EF{?dOsc$=q&DO!D2xLVU@HZ{ zbJ4FfmN`P}P17O_O`jaksaEe)y(O6^=uRQ+HWR0KCnVj~MoQ^mO9V?i8!X$I%6c^w z8iHJ)ueT48t=0i5PwNU8E#Qn4XV3jnBY@Rkkmp|WU2`&1M4G?x%0JA2Eb0bu}hT7m(OBnd?L zQr+Nh^)YgUhr+;i9X|^#4Z<|oH(Hsenu|`7+l%oZ8)0()B3aBAuDDW5gO#7}4**o5 z2JpHZuwuzE+d4q|G)fL~*+GT%-z#|a^(AaAf4~6<&}||sG(D;VgiG_eF-L)p_%wz< vx)yug4uNr1`!q;q5cf#X4E{ql