diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XSourcePositionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XSourcePositionImpl.java index 4703e91a7b7d..c11e8f5547cb 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XSourcePositionImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XSourcePositionImpl.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.impl.http.HttpVirtualFile; import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; import com.intellij.testFramework.LightVirtualFile; import com.intellij.xdebugger.XSourcePosition; import org.jetbrains.annotations.NotNull; @@ -71,6 +72,17 @@ public class XSourcePositionImpl implements XSourcePosition { return new XSourcePositionImpl(file, line, offset); } + @Nullable + public static XSourcePositionImpl createByElement(@Nullable PsiElement element) { + if (element == null) return null; + + VirtualFile file = element.getContainingFile().getVirtualFile(); + + if (file == null) return null; + + return createByOffset(file, element.getTextOffset()); + } + /** * do not call this method from plugins, use {@link com.intellij.xdebugger.XDebuggerUtil#createPosition(com.intellij.openapi.vfs.VirtualFile, int)} instead */ @@ -106,7 +118,9 @@ public class XSourcePositionImpl implements XSourcePosition { @NotNull public static OpenFileDescriptor createOpenFileDescriptor(@NotNull Project project, @NotNull XSourcePosition position) { - return position.getOffset() != -1 ? new OpenFileDescriptor(project, position.getFile(), position.getOffset()) : new OpenFileDescriptor(project, position.getFile(), position.getLine(), 0); + return position.getOffset() != -1 + ? new OpenFileDescriptor(project, position.getFile(), position.getOffset()) + : new OpenFileDescriptor(project, position.getFile(), position.getLine(), 0); } @Override diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java index 8ea49a309339..b713616424b1 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PyDebugValue.java @@ -236,8 +236,23 @@ public class PyDebugValue extends XNamedValue { myId = id; } + @Override + public boolean canNavigateToSource() { + return true; + } + @Override public void computeSourcePosition(@NotNull XNavigatable navigatable) { - navigatable.setSourcePosition(myFrameAccessor.getSourcePosition(myName)); + navigatable.setSourcePosition(myFrameAccessor.getSourcePositionForName(myName)); + } + + @Override + public boolean canNavigateToTypeSource() { + return true; + } + + @Override + public void computeTypeSourcePosition(@NotNull XNavigatable navigatable) { + navigatable.setSourcePosition(myFrameAccessor.getSourcePositionForType(myType)); } } diff --git a/python/pydevSrc/com/jetbrains/python/debugger/PyFrameAccessor.java b/python/pydevSrc/com/jetbrains/python/debugger/PyFrameAccessor.java index abfbf77828eb..bd6d5449a51d 100644 --- a/python/pydevSrc/com/jetbrains/python/debugger/PyFrameAccessor.java +++ b/python/pydevSrc/com/jetbrains/python/debugger/PyFrameAccessor.java @@ -25,5 +25,8 @@ public interface PyFrameAccessor { ArrayChunk getArrayItems(PyDebugValue var, int rowOffset, int colOffset, int rows, int cols, String format) throws PyDebuggerException; @Nullable - XSourcePosition getSourcePosition(String name); + XSourcePosition getSourcePositionForName(String name); + + @Nullable + XSourcePosition getSourcePositionForType(String type); } diff --git a/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java b/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java index 49ab942e2bb9..013c2fa323af 100644 --- a/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java +++ b/python/src/com/jetbrains/python/console/PydevConsoleCommunication.java @@ -572,7 +572,13 @@ public class PydevConsoleCommunication extends AbstractConsoleCommunication impl @Nullable @Override - public XSourcePosition getSourcePosition(String name) { + public XSourcePosition getSourcePositionForName(String name) { + return null; + } + + @Nullable + @Override + public XSourcePosition getSourcePositionForType(String type) { return null; } diff --git a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java index 09d0f5531f69..6cbae17aca64 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugProcess.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugProcess.java @@ -37,7 +37,6 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.pom.Navigatable; import com.intellij.psi.*; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.util.PsiTreeUtil; @@ -59,6 +58,9 @@ import com.jetbrains.python.console.pydev.PydevCompletionVariant; import com.jetbrains.python.debugger.pydev.*; import com.jetbrains.python.psi.PyFunction; import com.jetbrains.python.psi.resolve.PyResolveUtil; +import com.jetbrains.python.psi.types.PyClassType; +import com.jetbrains.python.psi.types.PyType; +import com.jetbrains.python.psi.types.PyTypeParser; import com.jetbrains.python.run.PythonProcessHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -816,27 +818,12 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr @Nullable @Override - public XSourcePosition getSourcePosition(String name) { + public XSourcePosition getSourcePositionForName(String name) { XSourcePosition currentPosition = getCurrentFrameSourcePosition(); - if (currentPosition == null) { - return null; - } + final PsiFile file = getPsiFile(currentPosition); - VirtualFile virtualFile = currentPosition.getFile(); - - final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); - if (document == null) { - return null; - } - final FileViewProvider viewProvider = PsiManager.getInstance(getProject()).findViewProvider(virtualFile); - if (viewProvider == null) { - return null; - } - final PsiFile file = viewProvider.getPsi(PythonLanguage.getInstance()); - if (file == null) { - return null; - } + if (file == null) return null; PsiElement currentElement = file.findElementAt(currentPosition.getOffset()); @@ -865,9 +852,50 @@ public class PyDebugProcess extends XDebugProcess implements IPyDebugProcess, Pr } }, currentElement, name, null); - return elementRef.isNull() - ? - null - : XSourcePositionImpl.createByOffset(elementRef.get().getContainingFile().getVirtualFile(), elementRef.get().getTextOffset()); + return elementRef.isNull() ? null + : XSourcePositionImpl.createByElement(elementRef.get()); + } + + @Nullable + private PsiFile getPsiFile(XSourcePosition currentPosition) { + if (currentPosition == null) { + return null; + } + + VirtualFile virtualFile = currentPosition.getFile(); + + final Document document = FileDocumentManager.getInstance().getDocument(virtualFile); + if (document == null) { + return null; + } + final FileViewProvider viewProvider = PsiManager.getInstance(getProject()).findViewProvider(virtualFile); + if (viewProvider == null) { + return null; + } + final PsiFile file = viewProvider.getPsi(PythonLanguage.getInstance()); + if (file == null) { + return null; + } + return file; + } + + + @Nullable + @Override + public XSourcePosition getSourcePositionForType(String typeName) { + XSourcePosition currentPosition = getCurrentFrameSourcePosition(); + + final PsiFile file = getPsiFile(currentPosition); + + if (file == null) return null; + + + PyType type = PyTypeParser.getTypeByName(file, typeName); + + if (type instanceof PyClassType) { + return XSourcePositionImpl.createByElement(((PyClassType)type).getPyClass()); + } + + return null; } }