<extensions defaultExtensionNs="Pythonid">
<pyDebugValueTransformer implementation="com.jetbrains.python.edu.debugger.PyEduDebugTransformer"/>
+ <pyFramesTransformer implementation="com.jetbrains.python.edu.debugger.PyEduFramesTransformer"/>
</extensions>
<actions>
package com.jetbrains.python.edu.debugger;
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
+import com.intellij.execution.ExecutionResult;
import com.intellij.execution.configurations.RunProfile;
+import com.intellij.execution.process.ProcessHandler;
+import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.util.containers.Predicate;
+import com.intellij.xdebugger.XDebugSession;
import com.intellij.xdebugger.XDebuggerManager;
import com.intellij.xdebugger.breakpoints.XBreakpointManager;
import com.intellij.xdebugger.breakpoints.XBreakpointProperties;
import com.intellij.xdebugger.impl.breakpoints.LineBreakpointState;
import com.intellij.xdebugger.impl.breakpoints.XBreakpointManagerImpl;
import com.intellij.xdebugger.impl.breakpoints.XLineBreakpointImpl;
-import com.jetbrains.python.debugger.PyDebugProcess;
-import com.jetbrains.python.debugger.PyDebugRunner;
-import com.jetbrains.python.debugger.PyLineBreakpointType;
-import com.jetbrains.python.debugger.PySourcePosition;
+import com.jetbrains.python.debugger.*;
import com.jetbrains.python.documentation.DocStringUtil;
import com.jetbrains.python.edu.PyEduUtils;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.PyExpressionStatement;
import com.jetbrains.python.psi.PyImportStatement;
+import com.jetbrains.python.run.PythonCommandLineState;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
+import java.net.ServerSocket;
import java.util.List;
public class PyEduDebugRunner extends PyDebugRunner {
return executorId.equals(PyEduDebugExecutor.ID);
}
+ @NotNull
+ @Override
+ protected PyDebugProcess createDebugProcess(@NotNull XDebugSession session,
+ ServerSocket serverSocket,
+ ExecutionResult result,
+ PythonCommandLineState pyState) {
+
+ return new PyEduDebugProcess(session, serverSocket, result.getExecutionConsole(), result.getProcessHandler(),
+ pyState.isMultiprocessDebug());
+ }
+
@Override
protected void initDebugProcess(String name, PyDebugProcess pyDebugProcess) {
VirtualFile file = VfsUtil.findFileByIoFile(new File(name), true);
}
return false;
}
+
+ private class PyEduDebugProcess extends PyDebugProcess {
+ public PyEduDebugProcess(@NotNull XDebugSession session,
+ @NotNull ServerSocket serverSocket,
+ @NotNull ExecutionConsole executionConsole,
+ @Nullable ProcessHandler processHandler, boolean multiProcess) {
+ super(session, serverSocket, executionConsole, processHandler, multiProcess);
+ }
+
+ @Override
+ public PyStackFrame createStackFrame(PyStackFrameInfo frameInfo) {
+ return new PyEduStackFrame(getSession().getProject(), this, frameInfo,
+ getPositionConverter().convertFromPython(frameInfo.getPosition()));
+ }
+ }
}
\ No newline at end of file
--- /dev/null
+package com.jetbrains.python.edu.debugger;
+
+import com.jetbrains.python.PythonHelpersLocator;
+import com.jetbrains.python.debugger.PyDebugRunner;
+import com.jetbrains.python.debugger.PyFramesTransformer;
+import com.jetbrains.python.debugger.PyStackFrameInfo;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class PyEduFramesTransformer implements PyFramesTransformer {
+ @Nullable
+ @Override
+ public List<PyStackFrameInfo> transformFrames(@Nullable List<PyStackFrameInfo> frames) {
+ if (frames == null) {
+ return null;
+ }
+ String debugger = PythonHelpersLocator.getHelperPath(PyDebugRunner.DEBUGGER_MAIN);
+ List<PyStackFrameInfo> newFrames = new ArrayList<PyStackFrameInfo>();
+ for (PyStackFrameInfo frame : frames) {
+ String file = frame.getPosition().getFile();
+ if (!debugger.equals(file)) {
+ newFrames.add(frame);
+ }
+ }
+ return newFrames;
+ }
+}
--- /dev/null
+package com.jetbrains.python.edu.debugger;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.ColoredTextContainer;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.xdebugger.XSourcePosition;
+import com.jetbrains.python.debugger.PyFrameAccessor;
+import com.jetbrains.python.debugger.PyStackFrame;
+import com.jetbrains.python.debugger.PyStackFrameInfo;
+import org.jetbrains.annotations.NotNull;
+
+public class PyEduStackFrame extends PyStackFrame {
+ public static final String MODULE = "<module>";
+ public static final String GLOBAL_FRAME = "Global Frame";
+ private final PyStackFrameInfo myFrameInfo;
+ private final XSourcePosition myPosition;
+
+ public PyEduStackFrame(@NotNull Project project,
+ @NotNull PyFrameAccessor debugProcess,
+ @NotNull PyStackFrameInfo frameInfo,
+ XSourcePosition position) {
+ super(project, debugProcess, frameInfo, position);
+ myFrameInfo = frameInfo;
+ myPosition = position;
+ }
+
+ @Override
+ public void customizePresentation(@NotNull ColoredTextContainer component) {
+ component.setIcon(AllIcons.Debugger.StackFrame);
+ if (myPosition == null) {
+ component.append("<frame not available>", SimpleTextAttributes.GRAY_ATTRIBUTES);
+ return;
+ }
+
+ final VirtualFile file = myPosition.getFile();
+
+ String frameName = myFrameInfo.getName();
+ component.setIcon(MODULE.equals(frameName) ? AllIcons.FileTypes.Text : AllIcons.Nodes.Field);
+ SimpleTextAttributes regularAttributes = SimpleTextAttributes.REGULAR_ATTRIBUTES;
+ if (MODULE.equals(frameName)) {
+ component.append(GLOBAL_FRAME, regularAttributes);
+ component.append(" (" + file.getName() + ")", getGrayAttributes(regularAttributes));
+ }
+ else {
+ component
+ .append(MODULE.equals(frameName) ? GLOBAL_FRAME : frameName, regularAttributes);
+ }
+ }
+}
--- /dev/null
+package com.jetbrains.python.debugger;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+public interface PyFramesTransformer {
+ ExtensionPointName<PyFramesTransformer> EP_NAME = ExtensionPointName.create("Pythonid.pyFramesTransformer");
+
+ @Nullable
+ List<PyStackFrameInfo> transformFrames(@Nullable List<PyStackFrameInfo> frames);
+}
package com.jetbrains.python.debugger;
+import com.intellij.openapi.extensions.Extensions;
import com.jetbrains.python.debugger.pydev.AbstractCommand;
import org.jetbrains.annotations.Nullable;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
String message) {
myId = id;
myName = name;
- myFrames = (frames != null && frames.size() > 0 ? Collections.unmodifiableList(frames) : null);
+ myFrames = prepareFrames(frames);
myStopReason = stopReason;
myMessage = message;
}
+ private static List<PyStackFrameInfo> prepareFrames(List<PyStackFrameInfo> frames) {
+ if (frames == null) {
+ return null;
+ }
+ List<PyStackFrameInfo> framesCopy = new ArrayList<PyStackFrameInfo>(frames);
+ for (PyFramesTransformer transformer: Extensions.getExtensions(PyFramesTransformer.EP_NAME)) {
+ framesCopy = transformer.transformFrames(framesCopy);
+ }
+ return framesCopy != null && framesCopy.size() > 0 ? Collections.unmodifiableList(framesCopy) : null;
+ }
+
public String getId() {
return myId;
}
public synchronized void updateState(final State state, final List<PyStackFrameInfo> frames) {
myState = state;
- myFrames = (frames != null && frames.size() > 0 ? Collections.unmodifiableList(frames) : null);
+ myFrames = prepareFrames(frames);
}
<extensionPoint qualifiedName="Pythonid.consoleOptionsProvider" interface="com.jetbrains.python.console.PyConsoleOptionsProvider"/>
<extensionPoint qualifiedName="Pythonid.pyRootTypeProvider" interface="com.jetbrains.python.module.PyRootTypeProvider"/>
<extensionPoint qualifiedName="Pythonid.pyDebugValueTransformer" interface="com.jetbrains.python.debugger.PyDebugValueTransformer"/>
+ <extensionPoint qualifiedName="Pythonid.pyFramesTransformer" interface="com.jetbrains.python.debugger.PyFramesTransformer"/>
</extensionPoints>
<extensions defaultExtensionNs="Pythonid">
@NotNull
public XDebugProcess start(@NotNull final XDebugSession session) {
PyDebugProcess pyDebugProcess =
- new PyDebugProcess(session, serverSocket, result.getExecutionConsole(), result.getProcessHandler(),
- pyState.isMultiprocessDebug());
+ createDebugProcess(session, serverSocket, result, pyState);
createConsoleCommunicationAndSetupActions(environment.getProject(), result, pyDebugProcess, session);
initDebugProcess(((PythonRunConfiguration)environment.getRunProfile()).getScriptName(), pyDebugProcess);
});
}
+ @NotNull
+ protected PyDebugProcess createDebugProcess(@NotNull XDebugSession session,
+ ServerSocket serverSocket,
+ ExecutionResult result,
+ PythonCommandLineState pyState) {
+ return new PyDebugProcess(session, serverSocket, result.getExecutionConsole(), result.getProcessHandler(),
+ pyState.isMultiprocessDebug());
+ }
+
protected void initDebugProcess(String name, PyDebugProcess pyDebugProcess) {
}
return attributes;
}
else {
- return (attributes.getStyle() & SimpleTextAttributes.STYLE_ITALIC) != 0
- ? SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES : SimpleTextAttributes.GRAYED_ATTRIBUTES;
+ return getGrayAttributes(attributes);
}
}
+ protected static SimpleTextAttributes getGrayAttributes(SimpleTextAttributes attributes) {
+ return (attributes.getStyle() & SimpleTextAttributes.STYLE_ITALIC) != 0
+ ? SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES : SimpleTextAttributes.GRAYED_ATTRIBUTES;
+ }
+
@Override
public void computeChildren(@NotNull final XCompositeNode node) {
if (node.isObsolete()) return;