feat(plugins): add method to open usage dialog
This commit is contained in:
@@ -83,6 +83,11 @@ public interface JadxGuiContext {
|
||||
*/
|
||||
boolean open(ICodeNodeRef ref);
|
||||
|
||||
/**
|
||||
* Open usage dialog for a node
|
||||
*/
|
||||
void openUsageDialog(ICodeNodeRef ref);
|
||||
|
||||
/**
|
||||
* Reload code in active tab
|
||||
*/
|
||||
|
||||
@@ -22,18 +22,15 @@ import jadx.api.plugins.events.types.NodeRenamedByUser;
|
||||
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.core.utils.exceptions.JadxRuntimeException;
|
||||
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.ui.dialog.UsageDialog;
|
||||
import jadx.gui.ui.panel.ContentPanel;
|
||||
import jadx.gui.utils.IconsCache;
|
||||
import jadx.gui.utils.JNodeCache;
|
||||
import jadx.gui.utils.UiUtils;
|
||||
|
||||
public class GuiPluginContext implements JadxGuiContext {
|
||||
@@ -183,24 +180,19 @@ public class GuiPluginContext implements JadxGuiContext {
|
||||
|
||||
@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().getTabsController().codeJump(node);
|
||||
commonContext.getMainWindow().getTabsController().codeJump(getJNodeFromRef(ref));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void openUsageDialog(ICodeNodeRef ref) {
|
||||
UsageDialog.open(commonContext.getMainWindow(), getJNodeFromRef(ref));
|
||||
}
|
||||
|
||||
private JNode getJNodeFromRef(ICodeNodeRef ref) {
|
||||
return commonContext.getMainWindow().getCacheObject().getNodeCache().makeFrom(ref);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reloadActiveTab() {
|
||||
UiUtils.uiRun(() -> {
|
||||
|
||||
@@ -254,9 +254,9 @@ public class MainWindow extends JFrame implements ExportProjectDialog.ExportProj
|
||||
|
||||
public MainWindow(JadxSettings settings) {
|
||||
this.settings = settings;
|
||||
this.cacheObject = new CacheObject();
|
||||
this.project = new JadxProject(this);
|
||||
this.wrapper = new JadxWrapper(this);
|
||||
this.cacheObject = new CacheObject(wrapper);
|
||||
this.liveReloadWorker = new LiveReloadWorker(this);
|
||||
this.renameMappings = new RenameMappingsGui(this);
|
||||
this.cacheManager = new CacheManager(settings);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package jadx.gui.ui.codearea;
|
||||
|
||||
import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.ui.MainWindow;
|
||||
import jadx.gui.ui.action.ActionModel;
|
||||
import jadx.gui.ui.dialog.UsageDialog;
|
||||
|
||||
@@ -14,15 +13,6 @@ public final class FindUsageAction extends JNodeAction {
|
||||
|
||||
@Override
|
||||
public void runAction(JNode node) {
|
||||
MainWindow mw = getCodeArea().getMainWindow();
|
||||
UsageDialog usageDialog = new UsageDialog(mw, node);
|
||||
mw.addLoadListener(loaded -> {
|
||||
if (!loaded) {
|
||||
usageDialog.dispose();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
usageDialog.setVisible(true);
|
||||
UsageDialog.open(getCodeArea().getMainWindow(), node);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,19 @@ public class UsageDialog extends CommonSearchDialog {
|
||||
|
||||
private transient List<CodeNode> usageList;
|
||||
|
||||
public UsageDialog(MainWindow mainWindow, JNode node) {
|
||||
public static void open(MainWindow mainWindow, JNode node) {
|
||||
UsageDialog usageDialog = new UsageDialog(mainWindow, node);
|
||||
mainWindow.addLoadListener(loaded -> {
|
||||
if (!loaded) {
|
||||
usageDialog.dispose();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
usageDialog.setVisible(true);
|
||||
}
|
||||
|
||||
private UsageDialog(MainWindow mainWindow, JNode node) {
|
||||
super(mainWindow, NLS.str("usage_dialog.title"));
|
||||
this.node = node;
|
||||
|
||||
|
||||
@@ -8,10 +8,12 @@ import java.util.Set;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.JavaClass;
|
||||
import jadx.gui.JadxWrapper;
|
||||
import jadx.gui.ui.dialog.SearchDialog;
|
||||
import jadx.gui.utils.pkgs.PackageHelper;
|
||||
|
||||
public class CacheObject {
|
||||
private final JadxWrapper wrapper;
|
||||
|
||||
private String lastSearch;
|
||||
private JNodeCache jNodeCache;
|
||||
@@ -23,13 +25,14 @@ public class CacheObject {
|
||||
|
||||
private volatile boolean fullDecompilationFinished;
|
||||
|
||||
public CacheObject() {
|
||||
public CacheObject(JadxWrapper wrapper) {
|
||||
this.wrapper = wrapper;
|
||||
reset();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
lastSearch = null;
|
||||
jNodeCache = new JNodeCache();
|
||||
jNodeCache = new JNodeCache(wrapper);
|
||||
lastSearchOptions = new HashMap<>();
|
||||
lastSearchPackage = null;
|
||||
decompileBatches = null;
|
||||
|
||||
@@ -8,7 +8,9 @@ import jadx.api.JavaField;
|
||||
import jadx.api.JavaMethod;
|
||||
import jadx.api.JavaNode;
|
||||
import jadx.api.JavaVariable;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
import jadx.gui.JadxWrapper;
|
||||
import jadx.gui.treemodel.JClass;
|
||||
import jadx.gui.treemodel.JField;
|
||||
import jadx.gui.treemodel.JMethod;
|
||||
@@ -16,36 +18,48 @@ import jadx.gui.treemodel.JNode;
|
||||
import jadx.gui.treemodel.JVariable;
|
||||
|
||||
public class JNodeCache {
|
||||
private final JadxWrapper wrapper;
|
||||
private final Map<ICodeNodeRef, JNode> cache = new ConcurrentHashMap<>();
|
||||
|
||||
private final Map<JavaNode, JNode> cache = new ConcurrentHashMap<>();
|
||||
public JNodeCache(JadxWrapper wrapper) {
|
||||
this.wrapper = wrapper;
|
||||
}
|
||||
|
||||
public JNode makeFrom(ICodeNodeRef nodeRef) {
|
||||
if (nodeRef == null) {
|
||||
return null;
|
||||
}
|
||||
// don't use 'computeIfAbsent' method here, it will cause 'Recursive update' exception
|
||||
JNode jNode = cache.get(nodeRef);
|
||||
if (jNode == null || jNode.getJavaNode().getCodeNodeRef() != nodeRef) {
|
||||
jNode = convert(nodeRef);
|
||||
cache.put(nodeRef, jNode);
|
||||
}
|
||||
return jNode;
|
||||
}
|
||||
|
||||
public JNode makeFrom(JavaNode javaNode) {
|
||||
if (javaNode == null) {
|
||||
return null;
|
||||
}
|
||||
// don't use 'computeIfAbsent' method here, it will cause 'Recursive update' exception
|
||||
JNode jNode = cache.get(javaNode);
|
||||
if (jNode == null || jNode.getJavaNode() != javaNode) {
|
||||
jNode = convert(javaNode);
|
||||
cache.put(javaNode, jNode);
|
||||
}
|
||||
return jNode;
|
||||
return makeFrom(javaNode.getCodeNodeRef());
|
||||
}
|
||||
|
||||
public JClass makeFrom(JavaClass javaCls) {
|
||||
if (javaCls == null) {
|
||||
return null;
|
||||
}
|
||||
JClass jCls = (JClass) cache.get(javaCls);
|
||||
ICodeNodeRef nodeRef = javaCls.getCodeNodeRef();
|
||||
JClass jCls = (JClass) cache.get(nodeRef);
|
||||
if (jCls == null || jCls.getCls() != javaCls) {
|
||||
jCls = convert(javaCls);
|
||||
cache.put(javaCls, jCls);
|
||||
cache.put(nodeRef, jCls);
|
||||
}
|
||||
return jCls;
|
||||
}
|
||||
|
||||
public void remove(JavaNode javaNode) {
|
||||
cache.remove(javaNode);
|
||||
cache.remove(javaNode.getCodeNodeRef());
|
||||
}
|
||||
|
||||
public void removeWholeClass(JavaClass javaCls) {
|
||||
@@ -64,12 +78,17 @@ public class JNodeCache {
|
||||
return new JClass(cls, makeFrom(parentCls));
|
||||
}
|
||||
|
||||
private JNode convert(ICodeNodeRef nodeRef) {
|
||||
JavaNode javaNode = wrapper.getDecompiler().getJavaNodeByRef(nodeRef);
|
||||
return convert(javaNode);
|
||||
}
|
||||
|
||||
private JNode convert(JavaNode node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
if (node instanceof JavaClass) {
|
||||
return convert(((JavaClass) node));
|
||||
return convert((JavaClass) node);
|
||||
}
|
||||
if (node instanceof JavaMethod) {
|
||||
return new JMethod((JavaMethod) node, makeFrom(node.getDeclaringClass()));
|
||||
|
||||
Reference in New Issue
Block a user