Start implementing TeaVM debugger

This commit is contained in:
Alexey Andreev 2016-04-26 22:48:53 +03:00
parent a2ebaf7d18
commit b99e032327
9 changed files with 330 additions and 1 deletions

3
.gitignore vendored
View File

@ -8,4 +8,5 @@
target
.idea/libraries/Maven__*
.idea/uiDesigner.xml
.idea/workspace.xml
.idea/workspace.xml
.idea/dictionaries/

6
.idea/scala_compiler.xml Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ScalaCompilerConfiguration">
<profile name="Maven 1" modules="teavm-samples-scala" />
</component>
</project>

View File

@ -34,6 +34,11 @@
<artifactId>teavm-tooling</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.teavm</groupId>
<artifactId>teavm-chrome-rdp</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,114 @@
/*
* 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.openapi.util.Key;
import com.intellij.xdebugger.XDebugProcess;
import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XSourcePosition;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import org.jetbrains.annotations.NotNull;
import org.teavm.chromerdp.ChromeRDPDebugger;
import org.teavm.chromerdp.ChromeRDPServer;
import org.teavm.debugging.Breakpoint;
import org.teavm.debugging.Debugger;
import org.teavm.debugging.DebuggerListener;
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;
public TeaVMDebugProcess(@NotNull XDebugSession session) {
super(session);
innerDebugger = initDebugger();
innerDebugger.addListener(new DebuggerListener() {
@Override
public void resumed() {
session.resume();
}
@Override
public void paused() {
session.pause();
}
@Override
public void breakpointStatusChanged(Breakpoint breakpoint) {
}
@Override
public void attached() {
}
@Override
public void detached() {
}
});
breakpointHandler = new TeaVMLineBreakpointHandler(innerDebugger);
}
private Debugger initDebugger() {
ChromeRDPServer debugServer = new ChromeRDPServer();
debugServer.setPort(2357);
ChromeRDPDebugger chromeDebugger = new ChromeRDPDebugger();
debugServer.setExchangeConsumer(chromeDebugger);
editorsProvider = new TeaVMDebuggerEditorsProvider();
return new Debugger(chromeDebugger, new URLDebugInformationProvider(""));
}
@NotNull
@Override
public XDebuggerEditorsProvider getEditorsProvider() {
return editorsProvider;
}
@Override
public void startStepOver() {
innerDebugger.stepOver();
}
@Override
public void startStepInto() {
innerDebugger.stepInto();
}
@Override
public void startStepOut() {
innerDebugger.stepOut();
}
@Override
public void resume() {
innerDebugger.resume();
}
@Override
public void runToPosition(@NotNull XSourcePosition position) {
innerDebugger.continueToLocation(position.getFile().getPath(), position.getLine());
}
@NotNull
@Override
public XBreakpointHandler<?>[] getBreakpointHandlers() {
return new XBreakpointHandler[] { breakpointHandler };
}
}

View File

@ -0,0 +1,47 @@
/*
* 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.ExecutionException;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.ConfigurationFactory;
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.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class TeaVMDebugRunConfiguration extends LocatableConfigurationBase {
public TeaVMDebugRunConfiguration(Project project, @NotNull ConfigurationFactory factory, String name) {
super(project, factory, name);
}
@NotNull
@Override
public SettingsEditor<? extends RunConfiguration> getConfigurationEditor() {
return null;
}
@Nullable
@Override
public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment environment) throws
ExecutionException {
return null;
}
}

View File

@ -0,0 +1,63 @@
/*
* 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.ExecutionException;
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.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;
public class TeaVMDebugRunner extends GenericProgramRunner<RunnerSettings> {
@NotNull
@Override
public String getRunnerId() {
return "TeaVMDebugRunner";
}
@Override
public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) {
return !DefaultDebugExecutor.EXECUTOR_ID.equals(executorId);
}
@Nullable
@Override
protected RunContentDescriptor doExecute(@NotNull RunProfileState state,
@NotNull ExecutionEnvironment environment) throws ExecutionException {
FileDocumentManager.getInstance().saveAllDocuments();
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);
}
}

View File

@ -0,0 +1,41 @@
/*
* 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.ide.highlighter.JavaFileType;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.psi.JavaCodeFragmentFactory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProviderBase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class TeaVMDebuggerEditorsProvider extends XDebuggerEditorsProviderBase {
@NotNull
@Override
public FileType getFileType() {
return JavaFileType.INSTANCE;
}
@Override
protected PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text,
@Nullable PsiElement context, boolean isPhysical) {
return JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment(text, context, null,
isPhysical);
}
}

View File

@ -0,0 +1,51 @@
/*
* 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.debugger.ui.breakpoints.JavaLineBreakpointType;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
import com.intellij.xdebugger.breakpoints.XLineBreakpoint;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.java.debugger.breakpoints.properties.JavaLineBreakpointProperties;
import org.teavm.debugging.Breakpoint;
import org.teavm.debugging.Debugger;
public class TeaVMLineBreakpointHandler extends XBreakpointHandler<XLineBreakpoint<JavaLineBreakpointProperties>> {
private Debugger innerDebugger;
@SuppressWarnings("unchecked")
public TeaVMLineBreakpointHandler(Debugger innerDebugger) {
super(JavaLineBreakpointType.class);
this.innerDebugger = innerDebugger;
}
@Override
public void registerBreakpoint(@NotNull XLineBreakpoint<JavaLineBreakpointProperties> breakpoint) {
Breakpoint innerBreakpoint = innerDebugger.createBreakpoint(breakpoint.getShortFilePath(),
breakpoint.getLine());
breakpoint.putUserData(TeaVMDebugProcess.INNER_BREAKPOINT_KEY, innerBreakpoint);
}
@Override
public void unregisterBreakpoint(@NotNull XLineBreakpoint<JavaLineBreakpointProperties> breakpoint,
boolean temporary) {
Breakpoint innerBreakpoint = breakpoint.getUserData(TeaVMDebugProcess.INNER_BREAKPOINT_KEY);
if (innerBreakpoint != null) {
breakpoint.putUserData(TeaVMDebugProcess.INNER_BREAKPOINT_KEY, null);
innerBreakpoint.destroy();
}
}
}

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"/>
<programRunner implementation="org.teavm.idea.debug.TeaVMDebugRunner"/>
</extensions>
<extensions defaultExtensionNs="org.jetbrains.idea.maven">