Navigate to type source for Python debugger variables.

This commit is contained in:
Dmitry Trofimov
2015-01-08 17:24:50 +01:00
parent e663becc44
commit f1fcfcb1a1
5 changed files with 93 additions and 27 deletions
@@ -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
@@ -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));
}
}
@@ -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);
}
@@ -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;
}
@@ -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;
}
}