Add TeaVM debug server run configuration

This commit is contained in:
Alexey Andreev 2016-04-27 22:53:21 +03:00
parent b99e032327
commit 40e06a573c
10 changed files with 265 additions and 27 deletions

View File

@ -33,11 +33,23 @@
<groupId>org.teavm</groupId>
<artifactId>teavm-tooling</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-chrome-rdp</artifactId>
<version>${project.version}</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
@ -60,6 +72,10 @@
<pattern>org.objectweb.asm</pattern>
<shadedPattern>org.teavm.asm</shadedPattern>
</relocation>
<relocation>
<pattern>org.objectweb.asm</pattern>
<shadedPattern>org.teavm.asm</shadedPattern>
</relocation>
</relocations>
</configuration>
</execution>

View File

@ -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<? extends RunConfiguration> 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;
}
}

View File

@ -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 };
}
}

View File

@ -32,11 +32,14 @@ import org.teavm.debugging.information.URLDebugInformationProvider;
public class TeaVMDebugProcess extends XDebugProcess {
public static final Key<Breakpoint> 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());

View File

@ -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<RunnerSettings> {
@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());
}
}

View File

@ -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());
}
}

View File

@ -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<TeaVMDebugConfiguration> {
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;
}
}

View File

@ -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);
}
}

View File

@ -31,6 +31,7 @@
serviceImplementation="org.teavm.idea.TeaVMConfigurationStorage"/>
<compileServer.plugin classpath="jps/teavm-jps-plugin.jar;teavm-all.jar"/>
<buildProcess.parametersProvider implementation="org.teavm.idea.TeaVMJPSConfigurator"/>
<configurationType implementation="org.teavm.idea.debug.TeaVMDebugConfigurationType"/>
<programRunner implementation="org.teavm.idea.debug.TeaVMDebugRunner"/>
</extensions>

Binary file not shown.

After

Width:  |  Height:  |  Size: 713 B