customized frames list
authorliana.bakradze <liana.bakradze@jetbrains.com>
Sun, 26 Jul 2015 19:35:59 +0000 (22:35 +0300)
committerliana.bakradze <liana.bakradze@jetbrains.com>
Sun, 26 Jul 2015 19:35:59 +0000 (22:35 +0300)
python/edu/src/META-INF/PyCharmEduPlugin.xml
python/edu/src/com/jetbrains/python/edu/debugger/PyEduDebugRunner.java
python/edu/src/com/jetbrains/python/edu/debugger/PyEduFramesTransformer.java [new file with mode: 0644]
python/edu/src/com/jetbrains/python/edu/debugger/PyEduStackFrame.java [new file with mode: 0644]
python/pydevSrc/com/jetbrains/python/debugger/PyFramesTransformer.java [new file with mode: 0644]
python/pydevSrc/com/jetbrains/python/debugger/PyThreadInfo.java
python/src/META-INF/python-core.xml
python/src/com/jetbrains/python/debugger/PyDebugRunner.java
python/src/com/jetbrains/python/debugger/PyStackFrame.java

index 749418f21e8b0862540699bc411e67850512b5a3..b676ee5fd53c79d9c1e8046be2bda9f5aa2dbe23 100644 (file)
@@ -36,6 +36,7 @@
 
   <extensions defaultExtensionNs="Pythonid">
     <pyDebugValueTransformer implementation="com.jetbrains.python.edu.debugger.PyEduDebugTransformer"/>
+    <pyFramesTransformer implementation="com.jetbrains.python.edu.debugger.PyEduFramesTransformer"/>
   </extensions>
 
   <actions>
index 23a5068df1c946a1cc774c909306b67639567053..3e358292c309736f3adb08194a85331632b3ea06 100644 (file)
@@ -1,7 +1,10 @@
 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;
@@ -9,25 +12,25 @@ import com.intellij.openapi.vfs.VfsUtil;
 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 {
@@ -47,6 +50,17 @@ 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);
@@ -87,4 +101,19 @@ public class PyEduDebugRunner extends PyDebugRunner {
     }
     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
diff --git a/python/edu/src/com/jetbrains/python/edu/debugger/PyEduFramesTransformer.java b/python/edu/src/com/jetbrains/python/edu/debugger/PyEduFramesTransformer.java
new file mode 100644 (file)
index 0000000..e83a1e3
--- /dev/null
@@ -0,0 +1,29 @@
+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;
+  }
+}
diff --git a/python/edu/src/com/jetbrains/python/edu/debugger/PyEduStackFrame.java b/python/edu/src/com/jetbrains/python/edu/debugger/PyEduStackFrame.java
new file mode 100644 (file)
index 0000000..ca3b63b
--- /dev/null
@@ -0,0 +1,51 @@
+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);
+    }
+  }
+}
diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyFramesTransformer.java b/python/pydevSrc/com/jetbrains/python/debugger/PyFramesTransformer.java
new file mode 100644 (file)
index 0000000..302edef
--- /dev/null
@@ -0,0 +1,13 @@
+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);
+}
index d7a2d5fe187cd5d61f4b6a07f076170b1c3e1acf..f48c27bc226c4604f486d3bfdcde90e358395673 100644 (file)
@@ -1,8 +1,10 @@
 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;
 
@@ -26,11 +28,22 @@ public class PyThreadInfo {
                       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;
   }
@@ -63,7 +76,7 @@ public class PyThreadInfo {
 
   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);
   }
 
 
index a4d701bb8528d6bff01ff01dc35f87b3230eab6d..aa537166a6626b883ae5f4b178b893ba2ae7e0fe 100644 (file)
     <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">
index abd7f429e5c7fe211684343902f097048cc355fd..2c1454ca285af9b450d43813ef190abab3cb5628 100644 (file)
@@ -98,8 +98,7 @@ public class PyDebugRunner extends GenericProgramRunner {
         @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);
@@ -108,6 +107,15 @@ public class PyDebugRunner extends GenericProgramRunner {
       });
   }
 
+  @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) {
   }
 
index 3d2d3326c7079ac40507873ef155317af0e8a2d7..80cce5540e6ffe9be6814d8ac454f34721b003d9 100644 (file)
@@ -97,11 +97,15 @@ public class PyStackFrame extends XStackFrame {
       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;