Skip to content

Commit 0f61e0e

Browse files
committed
dlv debugger: navigate to source and inline debugger
1 parent 9f099db commit 0f61e0e

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

src/com/goide/dlv/DlvXValue.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,29 @@
1818

1919
import com.goide.dlv.protocol.DlvApi;
2020
import com.goide.dlv.protocol.DlvRequest;
21+
import com.goide.psi.GoNamedElement;
22+
import com.goide.psi.GoTopLevelDeclaration;
2123
import com.intellij.icons.AllIcons;
24+
import com.intellij.lang.ASTNode;
25+
import com.intellij.openapi.application.ApplicationManager;
26+
import com.intellij.openapi.editor.Editor;
27+
import com.intellij.openapi.fileEditor.FileEditorManager;
28+
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
29+
import com.intellij.openapi.project.Project;
30+
import com.intellij.openapi.util.Comparing;
31+
import com.intellij.openapi.util.Condition;
2232
import com.intellij.openapi.util.text.StringUtil;
33+
import com.intellij.openapi.vfs.VirtualFile;
34+
import com.intellij.psi.PsiDocumentManager;
35+
import com.intellij.psi.PsiElement;
36+
import com.intellij.psi.PsiFile;
37+
import com.intellij.psi.SyntaxTraverser;
38+
import com.intellij.psi.util.PsiTreeUtil;
2339
import com.intellij.util.Consumer;
40+
import com.intellij.util.ThreeState;
41+
import com.intellij.xdebugger.XDebugSession;
42+
import com.intellij.xdebugger.XDebuggerUtil;
43+
import com.intellij.xdebugger.XSourcePosition;
2444
import com.intellij.xdebugger.frame.*;
2545
import com.intellij.xdebugger.frame.presentation.XNumericValuePresentation;
2646
import com.intellij.xdebugger.frame.presentation.XRegularValuePresentation;
@@ -30,6 +50,7 @@
3050
import org.jetbrains.annotations.Nullable;
3151

3252
import javax.swing.*;
53+
import java.util.Iterator;
3354
import java.util.regex.Pattern;
3455

3556
class DlvXValue extends XNamedValue {
@@ -118,4 +139,64 @@ public void renderValue(@NotNull XValueTextRenderer renderer) {
118139
return new XRegularValuePresentation(StringUtil.startsWith(value, prefix) ? value.replaceFirst(Pattern.quote(prefix), "") : value,
119140
type);
120141
}
142+
143+
@Nullable
144+
private static PsiElement findTargetElement(@NotNull Project project,
145+
@NotNull XSourcePosition position,
146+
@NotNull Editor editor,
147+
@NotNull final String name) {
148+
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
149+
if (file == null || !file.getVirtualFile().equals(position.getFile())) return null;
150+
ASTNode leafElement = file.getNode().findLeafElementAt(position.getOffset());
151+
if (leafElement == null) return null;
152+
GoTopLevelDeclaration topLevel = PsiTreeUtil.getTopmostParentOfType(leafElement.getPsi(), GoTopLevelDeclaration.class);
153+
SyntaxTraverser<PsiElement> traverser = SyntaxTraverser.psiTraverser(topLevel)
154+
.filter(new Condition<PsiElement>() {
155+
@Override
156+
public boolean value(PsiElement e) {
157+
return e instanceof GoNamedElement && Comparing.equal(name, ((GoNamedElement)e).getName());
158+
}
159+
});
160+
Iterator<PsiElement> iterator = traverser.iterator();
161+
return iterator.hasNext() ? iterator.next() : null;
162+
}
163+
164+
@Override
165+
public void computeSourcePosition(@NotNull final XNavigatable navigatable) {
166+
ApplicationManager.getApplication().invokeLater(new Runnable() {
167+
@Override
168+
public void run() {
169+
navigatable.setSourcePosition(findPosition());
170+
}
171+
172+
@Nullable
173+
private XSourcePosition findPosition() {
174+
XDebugSession debugSession = myProcess.getSession();
175+
if (debugSession == null) return null;
176+
XStackFrame stackFrame = debugSession.getCurrentStackFrame();
177+
if (stackFrame == null) return null;
178+
Project project = debugSession.getProject();
179+
XSourcePosition position = debugSession.getCurrentPosition();
180+
Editor editor = ((FileEditorManagerImpl)FileEditorManager.getInstance(project)).getSelectedTextEditor(true);
181+
if (editor == null || position == null) return null;
182+
String name = myName.startsWith("&") ? myName.replaceFirst("&\\w+", "") : myName;
183+
PsiElement resolved = findTargetElement(project, position, editor, name);
184+
if (resolved == null) return null;
185+
VirtualFile virtualFile = resolved.getContainingFile().getVirtualFile();
186+
return XDebuggerUtil.getInstance().createPositionByOffset(virtualFile, resolved.getTextOffset());
187+
}
188+
});
189+
}
190+
191+
@NotNull
192+
@Override
193+
public ThreeState computeInlineDebuggerData(@NotNull final XInlineDebuggerDataCallback callback) {
194+
computeSourcePosition(new XNavigatable() {
195+
@Override
196+
public void setSourcePosition(@Nullable XSourcePosition sourcePosition) {
197+
callback.computed(sourcePosition);
198+
}
199+
});
200+
return ThreeState.YES;
201+
}
121202
}

0 commit comments

Comments
 (0)