feat: add events support (#1832)
This commit is contained in:
@@ -29,6 +29,7 @@ import jadx.api.metadata.annotations.NodeDeclareRef;
|
||||
import jadx.api.metadata.annotations.VarNode;
|
||||
import jadx.api.metadata.annotations.VarRef;
|
||||
import jadx.api.plugins.JadxPlugin;
|
||||
import jadx.api.plugins.events.IJadxEvents;
|
||||
import jadx.api.plugins.input.ICodeLoader;
|
||||
import jadx.api.plugins.input.JadxCodeInput;
|
||||
import jadx.api.plugins.pass.JadxPass;
|
||||
@@ -44,6 +45,7 @@ import jadx.core.dex.nodes.RootNode;
|
||||
import jadx.core.dex.visitors.SaveCode;
|
||||
import jadx.core.export.ExportGradleTask;
|
||||
import jadx.core.plugins.JadxPluginManager;
|
||||
import jadx.core.plugins.events.JadxEventsImpl;
|
||||
import jadx.core.utils.DecompilerScheduler;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
@@ -94,6 +96,7 @@ public final class JadxDecompiler implements Closeable {
|
||||
private ProtoXMLParser protoXmlParser;
|
||||
|
||||
private final IDecompileScheduler decompileScheduler = new DecompilerScheduler();
|
||||
private final JadxEventsImpl events = new JadxEventsImpl();
|
||||
|
||||
private final List<ICodeLoader> customCodeLoaders = new ArrayList<>();
|
||||
private final Map<JadxPassType, List<JadxPass>> customPasses = new HashMap<>();
|
||||
@@ -129,6 +132,7 @@ public final class JadxDecompiler implements Closeable {
|
||||
LOG.info("reloading (passes only) ...");
|
||||
customPasses.clear();
|
||||
root.resetPasses();
|
||||
events.reset();
|
||||
loadPlugins();
|
||||
root.mergePasses(customPasses);
|
||||
root.restartVisitors();
|
||||
@@ -159,6 +163,7 @@ public final class JadxDecompiler implements Closeable {
|
||||
resources = null;
|
||||
binaryXmlParser = null;
|
||||
protoXmlParser = null;
|
||||
events.reset();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -660,6 +665,10 @@ public final class JadxDecompiler implements Closeable {
|
||||
return decompileScheduler;
|
||||
}
|
||||
|
||||
public IJadxEvents events() {
|
||||
return events;
|
||||
}
|
||||
|
||||
public void addCustomCodeLoader(ICodeLoader customCodeLoader) {
|
||||
customCodeLoaders.add(customCodeLoader);
|
||||
}
|
||||
|
||||
@@ -99,6 +99,11 @@ public final class JavaClass implements JavaNode {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICodeNodeRef getCodeNodeRef() {
|
||||
return cls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal API. Not Stable!
|
||||
*/
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.List;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
|
||||
import jadx.api.metadata.ICodeAnnotation;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.core.dex.info.AccessInfo;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.nodes.FieldNode;
|
||||
@@ -74,6 +75,11 @@ public final class JavaField implements JavaNode {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICodeNodeRef getCodeNodeRef() {
|
||||
return field;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal API. Not Stable!
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.api.metadata.ICodeAnnotation;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.core.dex.attributes.AType;
|
||||
import jadx.core.dex.attributes.nodes.MethodOverrideAttr;
|
||||
import jadx.core.dex.info.AccessInfo;
|
||||
@@ -116,6 +117,11 @@ public final class JavaMethod implements JavaNode {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICodeNodeRef getCodeNodeRef() {
|
||||
return mth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal API. Not Stable!
|
||||
*/
|
||||
|
||||
@@ -3,9 +3,12 @@ package jadx.api;
|
||||
import java.util.List;
|
||||
|
||||
import jadx.api.metadata.ICodeAnnotation;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
|
||||
public interface JavaNode {
|
||||
|
||||
ICodeNodeRef getCodeNodeRef();
|
||||
|
||||
String getName();
|
||||
|
||||
String getFullName();
|
||||
|
||||
@@ -8,6 +8,7 @@ import org.jetbrains.annotations.ApiStatus.Internal;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import jadx.api.metadata.ICodeAnnotation;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.core.dex.info.PackageInfo;
|
||||
import jadx.core.dex.nodes.PackageNode;
|
||||
|
||||
@@ -75,6 +76,11 @@ public final class JavaPackage implements JavaNode, Comparable<JavaPackage> {
|
||||
return !Objects.equals(parent, aliasParent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICodeNodeRef getCodeNodeRef() {
|
||||
return pkgNode;
|
||||
}
|
||||
|
||||
@Internal
|
||||
public PackageNode getPkgNode() {
|
||||
return pkgNode;
|
||||
|
||||
@@ -7,6 +7,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.metadata.ICodeAnnotation;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.api.metadata.annotations.VarNode;
|
||||
import jadx.api.metadata.annotations.VarRef;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
@@ -37,6 +38,11 @@ public class JavaVariable implements JavaNode {
|
||||
return varNode.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICodeNodeRef getCodeNodeRef() {
|
||||
return varNode;
|
||||
}
|
||||
|
||||
@ApiStatus.Internal
|
||||
public VarNode getVarNode() {
|
||||
return varNode;
|
||||
|
||||
@@ -6,6 +6,7 @@ public interface ICodeAnnotation {
|
||||
CLASS,
|
||||
FIELD,
|
||||
METHOD,
|
||||
PKG,
|
||||
VAR,
|
||||
VAR_REF,
|
||||
DECLARATION,
|
||||
|
||||
@@ -6,6 +6,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.JadxArgs;
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.api.plugins.events.IJadxEvents;
|
||||
import jadx.api.plugins.gui.JadxGuiContext;
|
||||
import jadx.api.plugins.input.JadxCodeInput;
|
||||
import jadx.api.plugins.options.JadxPluginOptions;
|
||||
@@ -30,6 +31,11 @@ public interface JadxPluginContext {
|
||||
*/
|
||||
void registerInputsHashSupplier(Supplier<String> supplier);
|
||||
|
||||
/**
|
||||
* Subscribe and send events
|
||||
*/
|
||||
IJadxEvents events();
|
||||
|
||||
@Nullable
|
||||
JadxGuiContext getGuiContext();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
package jadx.api.plugins.events;
|
||||
|
||||
public interface IJadxEvent {
|
||||
|
||||
JadxEventType<? extends IJadxEvent> getType();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package jadx.api.plugins.events;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public interface IJadxEvents {
|
||||
|
||||
/**
|
||||
* Send an event object.
|
||||
* For public event types check {@link JadxEvents} class.
|
||||
*/
|
||||
void send(IJadxEvent event);
|
||||
|
||||
/**
|
||||
* Register listener for specific event.
|
||||
* For public event types check {@link JadxEvents} class.
|
||||
*/
|
||||
<E extends IJadxEvent> void addListener(JadxEventType<E> eventType, Consumer<E> listener);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package jadx.api.plugins.events;
|
||||
|
||||
public abstract class JadxEventType<T extends IJadxEvent> {
|
||||
|
||||
public static <E extends IJadxEvent> JadxEventType<E> create() {
|
||||
return new JadxEventType<>() {
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package jadx.api.plugins.events;
|
||||
|
||||
import jadx.api.plugins.events.types.NodeRenamedByUser;
|
||||
|
||||
import static jadx.api.plugins.events.JadxEventType.create;
|
||||
|
||||
/**
|
||||
* Typed and extendable enumeration of event types
|
||||
*/
|
||||
public class JadxEvents {
|
||||
|
||||
/**
|
||||
* Notify about renames done by user (GUI only).
|
||||
*/
|
||||
public static final JadxEventType<NodeRenamedByUser> NODE_RENAMED_BY_USER = create();
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package jadx.api.plugins.events.types;
|
||||
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.api.plugins.events.IJadxEvent;
|
||||
import jadx.api.plugins.events.JadxEventType;
|
||||
import jadx.api.plugins.events.JadxEvents;
|
||||
|
||||
public class NodeRenamedByUser implements IJadxEvent {
|
||||
|
||||
private final ICodeNodeRef node;
|
||||
private final String oldName;
|
||||
private final String newName;
|
||||
|
||||
public NodeRenamedByUser(ICodeNodeRef node, String oldName, String newName) {
|
||||
this.node = node;
|
||||
this.oldName = oldName;
|
||||
this.newName = newName;
|
||||
}
|
||||
|
||||
public ICodeNodeRef getNode() {
|
||||
return node;
|
||||
}
|
||||
|
||||
public String getOldName() {
|
||||
return oldName;
|
||||
}
|
||||
|
||||
public String getNewName() {
|
||||
return newName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JadxEventType<NodeRenamedByUser> getType() {
|
||||
return JadxEvents.NODE_RENAMED_BY_USER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NodeRenamedByUser{" + node + ", '" + oldName + "' -> '" + newName + "'}";
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ public class Consts {
|
||||
public static final boolean DEBUG_EXC_HANDLERS = false;
|
||||
public static final boolean DEBUG_FINALLY = false;
|
||||
public static final boolean DEBUG_ATTRIBUTES = false;
|
||||
public static final boolean DEBUG_EVENTS = true;
|
||||
|
||||
public static final String CLASS_OBJECT = "java.lang.Object";
|
||||
public static final String CLASS_STRING = "java.lang.String";
|
||||
|
||||
@@ -8,11 +8,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.JavaPackage;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.core.dex.attributes.nodes.LineAttrNode;
|
||||
import jadx.core.dex.info.PackageInfo;
|
||||
|
||||
import static jadx.core.utils.StringUtils.containsChar;
|
||||
|
||||
public class PackageNode implements IPackageUpdate, IDexNode, Comparable<PackageNode> {
|
||||
public class PackageNode extends LineAttrNode
|
||||
implements IPackageUpdate, IDexNode, ICodeNodeRef, Comparable<PackageNode> {
|
||||
|
||||
private final RootNode root;
|
||||
private final PackageInfo pkgInfo;
|
||||
@@ -194,6 +197,11 @@ public class PackageNode implements IPackageUpdate, IDexNode, Comparable<Package
|
||||
return "package";
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnType getAnnType() {
|
||||
return AnnType.PKG;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RootNode root() {
|
||||
return root;
|
||||
|
||||
@@ -12,6 +12,7 @@ import jadx.api.JadxDecompiler;
|
||||
import jadx.api.plugins.JadxPlugin;
|
||||
import jadx.api.plugins.JadxPluginContext;
|
||||
import jadx.api.plugins.JadxPluginInfo;
|
||||
import jadx.api.plugins.events.IJadxEvents;
|
||||
import jadx.api.plugins.gui.JadxGuiContext;
|
||||
import jadx.api.plugins.input.JadxCodeInput;
|
||||
import jadx.api.plugins.options.JadxPluginOptions;
|
||||
@@ -95,6 +96,11 @@ public class PluginContext implements JadxPluginContext, Comparable<PluginContex
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public IJadxEvents events() {
|
||||
return decompiler.events();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable JadxGuiContext getGuiContext() {
|
||||
return guiContext;
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package jadx.core.plugins.events;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import jadx.api.plugins.events.IJadxEvent;
|
||||
import jadx.api.plugins.events.IJadxEvents;
|
||||
import jadx.api.plugins.events.JadxEventType;
|
||||
import jadx.core.Consts;
|
||||
|
||||
public class JadxEventsImpl implements IJadxEvents {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(JadxEventsImpl.class);
|
||||
|
||||
private final JadxEventsManager manager = new JadxEventsManager();
|
||||
|
||||
@Override
|
||||
public void send(IJadxEvent event) {
|
||||
if (Consts.DEBUG_EVENTS) {
|
||||
LOG.debug("Sending event: {}", event);
|
||||
}
|
||||
manager.send(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends IJadxEvent> void addListener(JadxEventType<E> eventType, Consumer<E> listener) {
|
||||
manager.addListener(eventType, listener);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
manager.reset();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package jadx.core.plugins.events;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import jadx.api.plugins.events.IJadxEvent;
|
||||
import jadx.api.plugins.events.JadxEventType;
|
||||
|
||||
/**
|
||||
* Handle events sending and receiving
|
||||
*/
|
||||
public class JadxEventsManager {
|
||||
|
||||
private final Map<JadxEventType<?>, List<Consumer<IJadxEvent>>> listeners = new IdentityHashMap<>();
|
||||
|
||||
private final ExecutorService eventsThreadPool;
|
||||
|
||||
public JadxEventsManager() {
|
||||
// TODO: allow to change threading strategy
|
||||
this.eventsThreadPool = Executors.newSingleThreadExecutor(makeThreadFactory());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public synchronized <E extends IJadxEvent> void addListener(JadxEventType<E> eventType, Consumer<E> listener) {
|
||||
listeners.computeIfAbsent(eventType, et -> new ArrayList<>())
|
||||
.add((Consumer<IJadxEvent>) listener);
|
||||
}
|
||||
|
||||
public synchronized void send(IJadxEvent event) {
|
||||
List<Consumer<IJadxEvent>> consumers = listeners.get(event.getType());
|
||||
if (consumers != null) {
|
||||
for (Consumer<IJadxEvent> consumer : consumers) {
|
||||
eventsThreadPool.execute(() -> consumer.accept(event));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void reset() {
|
||||
listeners.clear();
|
||||
}
|
||||
|
||||
private static ThreadFactory makeThreadFactory() {
|
||||
return new ThreadFactory() {
|
||||
private final AtomicInteger threadNumber = new AtomicInteger(0);
|
||||
|
||||
@Override
|
||||
public Thread newThread(@NotNull Runnable r) {
|
||||
return new Thread(r, "jadx-events-thread-" + threadNumber.incrementAndGet());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package jadx.gui.events;
|
||||
|
||||
import jadx.api.plugins.events.JadxEventType;
|
||||
import jadx.gui.events.types.TreeUpdate;
|
||||
|
||||
import static jadx.api.plugins.events.JadxEventType.create;
|
||||
|
||||
public class JadxGuiEvents {
|
||||
|
||||
public static final JadxEventType<TreeUpdate> TREE_UPDATE = create();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package jadx.gui.events.types;
|
||||
|
||||
import jadx.api.plugins.events.IJadxEvent;
|
||||
import jadx.api.plugins.events.JadxEventType;
|
||||
import jadx.gui.events.JadxGuiEvents;
|
||||
import jadx.gui.treemodel.JRoot;
|
||||
|
||||
public class TreeUpdate implements IJadxEvent {
|
||||
|
||||
private final JRoot jRoot;
|
||||
|
||||
public TreeUpdate(JRoot jRoot) {
|
||||
this.jRoot = jRoot;
|
||||
}
|
||||
|
||||
public JRoot getJRoot() {
|
||||
return jRoot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JadxEventType<TreeUpdate> getType() {
|
||||
return JadxGuiEvents.TREE_UPDATE;
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import jadx.gui.ui.MainWindow;
|
||||
|
||||
public interface JRenameNode {
|
||||
|
||||
JavaNode getJavaNode();
|
||||
|
||||
String getTitle();
|
||||
|
||||
String getName();
|
||||
|
||||
@@ -78,11 +78,14 @@ import org.slf4j.LoggerFactory;
|
||||
import ch.qos.logback.classic.Level;
|
||||
|
||||
import jadx.api.JadxArgs;
|
||||
import jadx.api.JadxDecompiler;
|
||||
import jadx.api.JavaNode;
|
||||
import jadx.api.ResourceFile;
|
||||
import jadx.api.plugins.events.IJadxEvents;
|
||||
import jadx.api.plugins.utils.CommonFileUtils;
|
||||
import jadx.core.Jadx;
|
||||
import jadx.core.export.TemplateFile;
|
||||
import jadx.core.plugins.events.JadxEventsImpl;
|
||||
import jadx.core.utils.ListUtils;
|
||||
import jadx.core.utils.StringUtils;
|
||||
import jadx.core.utils.exceptions.JadxRuntimeException;
|
||||
@@ -1639,4 +1642,15 @@ public class MainWindow extends JFrame {
|
||||
public RenameMappingsGui getRenameMappings() {
|
||||
return renameMappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Events instance if decompiler not yet available
|
||||
*/
|
||||
private final IJadxEvents fallbackEvents = new JadxEventsImpl();
|
||||
|
||||
public IJadxEvents events() {
|
||||
return wrapper.getCurrentDecompiler()
|
||||
.map(JadxDecompiler::events)
|
||||
.orElse(fallbackEvents);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,6 +34,8 @@ import org.slf4j.LoggerFactory;
|
||||
import jadx.api.JavaNode;
|
||||
import jadx.api.data.ICodeRename;
|
||||
import jadx.api.data.impl.JadxCodeData;
|
||||
import jadx.api.metadata.ICodeNodeRef;
|
||||
import jadx.api.plugins.events.types.NodeRenamedByUser;
|
||||
import jadx.core.utils.Utils;
|
||||
import jadx.gui.jobs.TaskStatus;
|
||||
import jadx.gui.settings.JadxProject;
|
||||
@@ -126,13 +128,21 @@ public class RenameDialog extends JDialog {
|
||||
private void processRename(String newName, Set<ICodeRename> renames) {
|
||||
ICodeRename rename = node.buildCodeRename(newName, renames);
|
||||
renames.remove(rename);
|
||||
String oldName = node.getName();
|
||||
if (newName.isEmpty()) {
|
||||
node.removeAlias();
|
||||
sendRenameEvent(oldName, node.getJavaNode().getName());
|
||||
} else {
|
||||
renames.add(rename);
|
||||
sendRenameEvent(oldName, newName);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendRenameEvent(String oldName, String newName) {
|
||||
ICodeNodeRef nodeRef = node.getJavaNode().getCodeNodeRef();
|
||||
mainWindow.events().send(new NodeRenamedByUser(nodeRef, oldName, newName));
|
||||
}
|
||||
|
||||
private void updateCodeRenames(Consumer<Set<ICodeRename>> updater) {
|
||||
JadxProject project = mainWindow.getProject();
|
||||
JadxCodeData codeData = project.getCodeData();
|
||||
|
||||
@@ -35,6 +35,11 @@ public class JRenamePackage implements JRenameNode {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaNode getJavaNode() {
|
||||
return refPkg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getTitle() {
|
||||
return fullName;
|
||||
|
||||
@@ -22,6 +22,7 @@ sourceSets {
|
||||
main {
|
||||
kotlin.srcDirs(
|
||||
"scripts",
|
||||
"scripts/gui",
|
||||
"context"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import jadx.api.plugins.events.JadxEvents
|
||||
|
||||
/**
|
||||
* Log events
|
||||
*/
|
||||
|
||||
val jadx = getJadxInstance()
|
||||
|
||||
jadx.events.addListener(JadxEvents.NODE_RENAMED_BY_USER) { rename ->
|
||||
log.info { "Rename from '${rename.oldName}' to '${rename.newName}' for node ${rename.node}" }
|
||||
}
|
||||
+4
@@ -7,6 +7,7 @@ import jadx.api.JadxArgs
|
||||
import jadx.api.JadxDecompiler
|
||||
import jadx.api.JavaClass
|
||||
import jadx.api.plugins.JadxPluginContext
|
||||
import jadx.api.plugins.events.IJadxEvents
|
||||
import jadx.api.plugins.pass.JadxPass
|
||||
import jadx.plugins.script.runtime.data.Debug
|
||||
import jadx.plugins.script.runtime.data.Decompile
|
||||
@@ -50,6 +51,9 @@ class JadxScriptInstance(
|
||||
val gui: Gui by lazy { Gui(this, scriptData.pluginContext.guiContext) }
|
||||
val debug: Debug by lazy { Debug(this) }
|
||||
|
||||
val events: IJadxEvents
|
||||
get() = scriptData.pluginContext.events()
|
||||
|
||||
val args: JadxArgs
|
||||
get() = decompiler.args
|
||||
|
||||
|
||||
Reference in New Issue
Block a user