feat(api): access node under caret/mouse and jump (PR #1903)

* Access node under caret/mouse and jump
* Apply lint
This commit is contained in:
Yoav Sternberg
2023-06-09 17:50:57 +03:00
committed by GitHub
parent 347d6e2c2e
commit f558203a9d
6 changed files with 217 additions and 0 deletions
@@ -1,5 +1,6 @@
package jadx.gui.plugins.context;
import java.awt.Container;
import java.util.function.Consumer;
import java.util.function.Function;
@@ -14,7 +15,15 @@ import jadx.api.metadata.ICodeNodeRef;
import jadx.api.plugins.gui.ISettingsGroup;
import jadx.api.plugins.gui.JadxGuiContext;
import jadx.api.plugins.gui.JadxGuiSettings;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
import jadx.core.dex.nodes.MethodNode;
import jadx.core.plugins.PluginContext;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.codearea.AbstractCodeArea;
import jadx.gui.ui.codearea.AbstractCodeContentPanel;
import jadx.gui.ui.codearea.CodeArea;
import jadx.gui.utils.JNodeCache;
import jadx.gui.utils.UiUtils;
public class GuiPluginContext implements JadxGuiContext {
@@ -86,4 +95,85 @@ public class GuiPluginContext implements JadxGuiContext {
public @Nullable ISettingsGroup getCustomSettingsGroup() {
return customSettingsGroup;
}
@Nullable
private CodeArea getCodeArea() {
Container contentPane = commonContext.getMainWindow().getTabbedPane().getSelectedContentPanel();
if (contentPane instanceof AbstractCodeContentPanel) {
AbstractCodeArea codeArea = ((AbstractCodeContentPanel) contentPane).getCodeArea();
if (codeArea instanceof CodeArea) {
return (CodeArea) codeArea;
}
}
return null;
}
@Override
public ICodeNodeRef getNodeUnderCaret() {
CodeArea codeArea = getCodeArea();
if (codeArea != null) {
JNode nodeUnderCaret = codeArea.getNodeUnderCaret();
if (nodeUnderCaret != null) {
return nodeUnderCaret.getCodeNodeRef();
}
}
return null;
}
@Override
public ICodeNodeRef getNodeUnderMouse() {
CodeArea codeArea = getCodeArea();
if (codeArea != null) {
JNode nodeUnderMouse = codeArea.getNodeUnderMouse();
if (nodeUnderMouse != null) {
return nodeUnderMouse.getCodeNodeRef();
}
}
return null;
}
@Override
public ICodeNodeRef getEnclosingNodeUnderCaret() {
CodeArea codeArea = getCodeArea();
if (codeArea != null) {
JNode nodeUnderMouse = codeArea.getEnclosingNodeUnderCaret();
if (nodeUnderMouse != null) {
return nodeUnderMouse.getCodeNodeRef();
}
}
return null;
}
@Override
public ICodeNodeRef getEnclosingNodeUnderMouse() {
CodeArea codeArea = getCodeArea();
if (codeArea != null) {
JNode nodeUnderMouse = codeArea.getEnclosingNodeUnderMouse();
if (nodeUnderMouse != null) {
return nodeUnderMouse.getCodeNodeRef();
}
}
return null;
}
@Override
public boolean open(ICodeNodeRef ref) {
JNodeCache cache = commonContext.getMainWindow().getWrapper().getCache().getNodeCache();
JNode node;
if (ref instanceof ClassNode) {
node = cache.makeFrom(((ClassNode) ref).getJavaNode());
} else if (ref instanceof MethodNode) {
node = cache.makeFrom(((MethodNode) ref).getJavaNode());
} else if (ref instanceof FieldNode) {
node = cache.makeFrom(((FieldNode) ref).getJavaNode());
} else {
// Package node - cannot jump to it
// TODO: Var node - might be possible
return false;
}
commonContext.getMainWindow().getTabbedPane().codeJump(node);
return true;
}
}
@@ -213,6 +213,20 @@ public final class CodeArea extends AbstractCodeArea {
return getJNodeAtOffset(start);
}
@Nullable
public JNode getEnclosingNodeUnderCaret() {
int caretPos = getCaretPosition();
Token token = modelToToken(caretPos);
if (token == null) {
return null;
}
int start = adjustOffsetForToken(token);
if (start == -1) {
start = caretPos;
}
return getEnclosingJNodeAtOffset(start);
}
@Nullable
public JNode getNodeUnderMouse() {
Point pos = UiUtils.getMousePosition(this);
@@ -220,6 +234,22 @@ public final class CodeArea extends AbstractCodeArea {
return getJNodeAtOffset(offset);
}
@Nullable
public JNode getEnclosingNodeUnderMouse() {
Point pos = UiUtils.getMousePosition(this);
int offset = adjustOffsetForToken(viewToToken(pos));
return getEnclosingJNodeAtOffset(offset);
}
@Nullable
public JNode getEnclosingJNodeAtOffset(int offset) {
JavaNode javaNode = getEnclosingJavaNode(offset);
if (javaNode != null) {
return convertJavaNode(javaNode);
}
return null;
}
@Nullable
public JNode getJNodeAtOffset(int offset) {
JavaNode javaNode = getJavaNodeAtOffset(offset);
@@ -253,6 +283,15 @@ public final class CodeArea extends AbstractCodeArea {
}
}
public JavaNode getEnclosingJavaNode(int offset) {
try {
return getJadxWrapper().getDecompiler().getEnclosingNode(getCodeInfo(), offset);
} catch (Exception e) {
LOG.error("Can't get java node by offset: {}", offset, e);
return null;
}
}
public JavaClass getJavaClassIfAtPos(int pos) {
try {
ICodeInfo codeInfo = getCodeInfo();