refactor: add method info caching to speed up initial loading
This commit is contained in:
@@ -11,6 +11,8 @@ public class InfoStorage {
|
||||
private final Map<FieldInfo, FieldInfo> fields = new HashMap<>();
|
||||
// use only one MethodInfo instance
|
||||
private final Map<MethodInfo, MethodInfo> uniqueMethods = new HashMap<>();
|
||||
// can contain same method with different ids (from different dex files)
|
||||
private final Map<Integer, MethodInfo> methods = new HashMap<>();
|
||||
|
||||
public ClassInfo getCls(ArgType type) {
|
||||
return classes.get(type);
|
||||
@@ -23,6 +25,18 @@ public class InfoStorage {
|
||||
}
|
||||
}
|
||||
|
||||
public MethodInfo getByUniqId(int id) {
|
||||
synchronized (methods) {
|
||||
return methods.get(id);
|
||||
}
|
||||
}
|
||||
|
||||
public void putByUniqId(int id, MethodInfo mth) {
|
||||
synchronized (methods) {
|
||||
methods.put(id, mth);
|
||||
}
|
||||
}
|
||||
|
||||
public MethodInfo putMethod(MethodInfo newMth) {
|
||||
synchronized (uniqueMethods) {
|
||||
MethodInfo prev = uniqueMethods.get(newMth);
|
||||
|
||||
@@ -5,7 +5,7 @@ import java.util.Objects;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.IMethodData;
|
||||
import jadx.api.plugins.input.data.IMethodRef;
|
||||
import jadx.core.codegen.TypeGen;
|
||||
import jadx.core.dex.instructions.args.ArgType;
|
||||
import jadx.core.dex.nodes.RootNode;
|
||||
@@ -31,18 +31,27 @@ public final class MethodInfo implements Comparable<MethodInfo> {
|
||||
this.shortId = makeShortId(name, argTypes, retType);
|
||||
}
|
||||
|
||||
public static MethodInfo fromData(RootNode root, IMethodData methodData) {
|
||||
ArgType parentClsType = ArgType.parse(methodData.getParentClassType());
|
||||
public static MethodInfo fromRef(RootNode root, IMethodRef methodRef) {
|
||||
InfoStorage infoStorage = root.getInfoStorage();
|
||||
int uniqId = methodRef.getUniqId();
|
||||
MethodInfo prevMth = infoStorage.getByUniqId(uniqId);
|
||||
if (prevMth != null) {
|
||||
return prevMth;
|
||||
}
|
||||
methodRef.load();
|
||||
ArgType parentClsType = ArgType.parse(methodRef.getParentClassType());
|
||||
ClassInfo parentClass = ClassInfo.fromType(root, parentClsType);
|
||||
ArgType returnType = ArgType.parse(methodData.getReturnType());
|
||||
List<ArgType> args = Utils.collectionMap(methodData.getArgTypes(), ArgType::parse);
|
||||
MethodInfo newMth = new MethodInfo(parentClass, methodData.getName(), args, returnType);
|
||||
return root.getInfoStorage().putMethod(newMth);
|
||||
ArgType returnType = ArgType.parse(methodRef.getReturnType());
|
||||
List<ArgType> args = Utils.collectionMap(methodRef.getArgTypes(), ArgType::parse);
|
||||
MethodInfo newMth = new MethodInfo(parentClass, methodRef.getName(), args, returnType);
|
||||
MethodInfo uniqMth = infoStorage.putMethod(newMth);
|
||||
infoStorage.putByUniqId(uniqId, uniqMth);
|
||||
return uniqMth;
|
||||
}
|
||||
|
||||
public static MethodInfo fromDetails(RootNode rootNode, ClassInfo declClass, String name, List<ArgType> args, ArgType retType) {
|
||||
public static MethodInfo fromDetails(RootNode root, ClassInfo declClass, String name, List<ArgType> args, ArgType retType) {
|
||||
MethodInfo newMth = new MethodInfo(declClass, name, args, retType);
|
||||
return rootNode.getInfoStorage().putMethod(newMth);
|
||||
return root.getInfoStorage().putMethod(newMth);
|
||||
}
|
||||
|
||||
public String makeSignature(boolean includeRetType) {
|
||||
|
||||
@@ -521,8 +521,8 @@ public class InsnDecoder {
|
||||
}
|
||||
|
||||
private InsnNode invoke(InsnData insn, InvokeType type, boolean isRange) {
|
||||
MethodInfo mth = MethodInfo.fromData(root, insn.getIndexAsMethod());
|
||||
return new InvokeNode(mth, insn, type, isRange);
|
||||
MethodInfo mthInfo = MethodInfo.fromRef(root, insn.getIndexAsMethod());
|
||||
return new InvokeNode(mthInfo, insn, type, isRange);
|
||||
}
|
||||
|
||||
private InsnNode arrayGet(InsnData insn, ArgType argType) {
|
||||
|
||||
@@ -81,8 +81,8 @@ public class ClassNode extends NotificationAttrNode implements ILoadable, ICodeN
|
||||
public ClassNode(RootNode root, IClassData cls) {
|
||||
this.root = root;
|
||||
this.clsInfo = ClassInfo.fromType(root, ArgType.object(cls.getType()));
|
||||
initialLoad(cls);
|
||||
this.clsData = cls.copy();
|
||||
initialLoad(clsData);
|
||||
}
|
||||
|
||||
private void initialLoad(IClassData cls) {
|
||||
|
||||
@@ -82,8 +82,8 @@ public class MethodNode extends NotificationAttrNode implements IMethodDetails,
|
||||
return methodNode;
|
||||
}
|
||||
|
||||
public MethodNode(ClassNode classNode, IMethodData mthData) {
|
||||
this.mthInfo = MethodInfo.fromData(classNode.root(), mthData);
|
||||
private MethodNode(ClassNode classNode, IMethodData mthData) {
|
||||
this.mthInfo = MethodInfo.fromRef(classNode.root(), mthData.getMethodRef());
|
||||
this.parentClass = classNode;
|
||||
this.accFlags = new AccessInfo(mthData.getAccessFlags(), AFType.METHOD);
|
||||
this.methodIsVirtual = !mthData.isDirect();
|
||||
|
||||
@@ -104,7 +104,7 @@ public class UsageInfoVisitor extends AbstractVisitor {
|
||||
|
||||
case METHOD_REF:
|
||||
insnData.decode();
|
||||
MethodNode methodNode = root.resolveMethod(MethodInfo.fromData(root, insnData.getIndexAsMethod()));
|
||||
MethodNode methodNode = root.resolveMethod(MethodInfo.fromRef(root, insnData.getIndexAsMethod()));
|
||||
if (methodNode != null) {
|
||||
usageInfo.methodUse(mth, methodNode);
|
||||
}
|
||||
|
||||
+15
-1
@@ -24,6 +24,8 @@ import jadx.plugins.input.dex.sections.DexConsts;
|
||||
public class DexFileLoader {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(DexFileLoader.class);
|
||||
|
||||
private static int dexUniqId = 1;
|
||||
|
||||
public static List<DexReader> collectDexFiles(List<Path> pathsList) {
|
||||
return pathsList.stream()
|
||||
.map(Path::toFile)
|
||||
@@ -52,7 +54,7 @@ public class DexFileLoader {
|
||||
}
|
||||
if (isStartWithBytes(magic, DexConsts.DEX_FILE_MAGIC)) {
|
||||
in.reset();
|
||||
DexReader dexReader = new DexReader(inputFileName, readAllBytes(in));
|
||||
DexReader dexReader = new DexReader(getNextUniqId(), inputFileName, readAllBytes(in));
|
||||
return Collections.singletonList(dexReader);
|
||||
}
|
||||
if (file != null && isStartWithBytes(magic, DexConsts.ZIP_FILE_MAGIC)) {
|
||||
@@ -97,4 +99,16 @@ public class DexFileLoader {
|
||||
private static byte[] readAllBytes(InputStream in) throws IOException {
|
||||
return ByteStreams.toByteArray(in);
|
||||
}
|
||||
|
||||
private static int getNextUniqId() {
|
||||
dexUniqId++;
|
||||
if (dexUniqId >= 0xFFFF) {
|
||||
resetDexUniqId();
|
||||
}
|
||||
return dexUniqId;
|
||||
}
|
||||
|
||||
public static void resetDexUniqId() {
|
||||
dexUniqId = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,10 @@ import jadx.api.plugins.input.data.impl.EmptyLoadResult;
|
||||
|
||||
public class DexInputPlugin implements JadxInputPlugin {
|
||||
|
||||
public DexInputPlugin() {
|
||||
DexFileLoader.resetDexUniqId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JadxPluginInfo getPluginInfo() {
|
||||
return new JadxPluginInfo("dex-input", "DexInput", "Load .dex and .apk files");
|
||||
|
||||
@@ -10,12 +10,13 @@ import jadx.plugins.input.dex.sections.SectionReader;
|
||||
import jadx.plugins.input.dex.sections.annotations.AnnotationsParser;
|
||||
|
||||
public class DexReader {
|
||||
|
||||
private final int uniqId;
|
||||
private final String inputFileName;
|
||||
private final ByteBuffer buf;
|
||||
private final DexHeader header;
|
||||
|
||||
public DexReader(String inputFileName, byte[] content) {
|
||||
public DexReader(int uniqId, String inputFileName, byte[] content) {
|
||||
this.uniqId = uniqId;
|
||||
this.inputFileName = inputFileName;
|
||||
this.buf = ByteBuffer.wrap(content);
|
||||
this.header = new DexHeader(new SectionReader(this, 0));
|
||||
@@ -48,6 +49,10 @@ public class DexReader {
|
||||
return inputFileName;
|
||||
}
|
||||
|
||||
public int getUniqId() {
|
||||
return uniqId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return inputFileName;
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@ package jadx.plugins.input.dex.insns;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.IFieldData;
|
||||
import jadx.api.plugins.input.data.IMethodData;
|
||||
import jadx.api.plugins.input.data.IMethodRef;
|
||||
import jadx.api.plugins.input.insns.InsnData;
|
||||
import jadx.api.plugins.input.insns.InsnIndexType;
|
||||
import jadx.api.plugins.input.insns.Opcode;
|
||||
@@ -106,8 +106,8 @@ public class DexInsnData implements InsnData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IMethodData getIndexAsMethod() {
|
||||
return externalReader.getMethodData(index);
|
||||
public IMethodRef getIndexAsMethod() {
|
||||
return externalReader.getMethodRef(index);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
+5
-2
@@ -127,10 +127,10 @@ public class DexClassData implements IClassData {
|
||||
|
||||
private void visitMethods(Consumer<IMethodData> mthConsumer, SectionReader data, int directMthCount, int virtualMthCount) {
|
||||
DexMethodData methodData = new DexMethodData(annotationsParser);
|
||||
methodData.setMethodRef(new DexMethodRef());
|
||||
Map<Integer, Integer> annotationOffsetMap = annotationsParser.readMethodsAnnotationOffsetMap();
|
||||
Map<Integer, Integer> paramsAnnOffsetMap = annotationsParser.readMethodParamsAnnRefOffsetMap();
|
||||
|
||||
methodData.setParentClassType(getType());
|
||||
methodData.setDirect(true);
|
||||
readMethods(mthConsumer, data, methodData, directMthCount, annotationOffsetMap, paramsAnnOffsetMap);
|
||||
methodData.setDirect(false);
|
||||
@@ -145,7 +145,10 @@ public class DexClassData implements IClassData {
|
||||
mthIdx += data.readUleb128();
|
||||
int accFlags = data.readUleb128();
|
||||
int codeOff = data.readUleb128();
|
||||
in.fillMethodData(methodData, mthIdx);
|
||||
|
||||
DexMethodRef methodRef = methodData.getMethodRef();
|
||||
methodRef.reset();
|
||||
in.initMethodRef(mthIdx, methodRef);
|
||||
methodData.setAccessFlags(accFlags);
|
||||
if (codeOff == 0) {
|
||||
methodData.setCodeReader(null);
|
||||
|
||||
+7
-38
@@ -9,16 +9,13 @@ import jadx.api.plugins.input.data.IMethodData;
|
||||
import jadx.api.plugins.input.data.annotations.IAnnotation;
|
||||
import jadx.plugins.input.dex.sections.annotations.AnnotationsParser;
|
||||
import jadx.plugins.input.dex.smali.SmaliPrinter;
|
||||
import jadx.plugins.input.dex.utils.Utils;
|
||||
|
||||
public class DexMethodData implements IMethodData {
|
||||
@Nullable
|
||||
private final AnnotationsParser annotationsParser;
|
||||
|
||||
private String parentClassType;
|
||||
private String returnType;
|
||||
private List<String> argTypes;
|
||||
private String name;
|
||||
private DexMethodRef methodRef;
|
||||
|
||||
private int accessFlags;
|
||||
private boolean isDirect;
|
||||
private int annotationsOffset;
|
||||
@@ -32,21 +29,12 @@ public class DexMethodData implements IMethodData {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentClassType() {
|
||||
return parentClassType;
|
||||
public DexMethodRef getMethodRef() {
|
||||
return methodRef;
|
||||
}
|
||||
|
||||
public void setParentClassType(String parentClassType) {
|
||||
this.parentClassType = parentClassType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
public void setMethodRef(DexMethodRef methodRef) {
|
||||
this.methodRef = methodRef;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -58,24 +46,6 @@ public class DexMethodData implements IMethodData {
|
||||
this.accessFlags = accessFlags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public void setReturnType(String returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArgTypes() {
|
||||
return argTypes;
|
||||
}
|
||||
|
||||
public void setArgTypes(List<String> argTypes) {
|
||||
this.argTypes = argTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDirect() {
|
||||
return isDirect;
|
||||
@@ -127,7 +97,6 @@ public class DexMethodData implements IMethodData {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getParentClassType() + "->" + getName()
|
||||
+ '(' + Utils.listToStr(getArgTypes()) + ")" + getReturnType();
|
||||
return getMethodRef().toString();
|
||||
}
|
||||
}
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
package jadx.plugins.input.dex.sections;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jadx.api.plugins.input.data.IMethodRef;
|
||||
import jadx.plugins.input.dex.DexReader;
|
||||
import jadx.plugins.input.dex.utils.Utils;
|
||||
|
||||
public class DexMethodRef implements IMethodRef {
|
||||
|
||||
private int uniqId;
|
||||
private String name;
|
||||
private String parentClassType;
|
||||
private String returnType;
|
||||
private List<String> argTypes;
|
||||
|
||||
// lazy loading info
|
||||
private int dexIdx;
|
||||
private SectionReader sectionReader;
|
||||
|
||||
public void initUniqId(DexReader dexReader, int idx) {
|
||||
this.uniqId = (dexReader.getUniqId() & 0xFFFF) << 16 | (idx & 0xFFFF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load() {
|
||||
if (sectionReader != null) {
|
||||
sectionReader.loadMethodRef(this, dexIdx);
|
||||
sectionReader = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void setDexIdx(int dexIdx) {
|
||||
this.dexIdx = dexIdx;
|
||||
}
|
||||
|
||||
public void setSectionReader(SectionReader sectionReader) {
|
||||
this.sectionReader = sectionReader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getUniqId() {
|
||||
return uniqId;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
name = null;
|
||||
parentClassType = null;
|
||||
returnType = null;
|
||||
argTypes = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParentClassType() {
|
||||
return parentClassType;
|
||||
}
|
||||
|
||||
public void setParentClassType(String parentClassType) {
|
||||
this.parentClassType = parentClassType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
public void setReturnType(String returnType) {
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArgTypes() {
|
||||
return argTypes;
|
||||
}
|
||||
|
||||
public void setArgTypes(List<String> argTypes) {
|
||||
this.argTypes = argTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (name == null) {
|
||||
// not loaded
|
||||
return Integer.toHexString(uniqId);
|
||||
}
|
||||
return getParentClassType() + "->" + getName() + '(' + Utils.listToStr(getArgTypes()) + ")" + getReturnType();
|
||||
}
|
||||
}
|
||||
+22
-16
@@ -10,7 +10,6 @@ import java.util.List;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.IFieldData;
|
||||
import jadx.api.plugins.input.data.IMethodData;
|
||||
import jadx.plugins.input.dex.DexReader;
|
||||
import jadx.plugins.input.dex.utils.Leb128;
|
||||
import jadx.plugins.input.dex.utils.MUtf8;
|
||||
@@ -175,23 +174,29 @@ public class SectionReader {
|
||||
return classTypeIdx;
|
||||
}
|
||||
|
||||
public IMethodData getMethodData(int idx) {
|
||||
DexMethodData methodData = new DexMethodData(null);
|
||||
int clsTypeIdx = fillMethodData(methodData, idx);
|
||||
methodData.setParentClassType(getType(clsTypeIdx));
|
||||
return methodData;
|
||||
public DexMethodRef getMethodRef(int idx) {
|
||||
DexMethodRef methodRef = new DexMethodRef();
|
||||
initMethodRef(idx, methodRef);
|
||||
return methodRef;
|
||||
}
|
||||
|
||||
public int fillMethodData(DexMethodData methodData, int idx) {
|
||||
int methodIdsOff = dexReader.getHeader().getMethodIdsOff();
|
||||
public void initMethodRef(int idx, DexMethodRef methodRef) {
|
||||
methodRef.initUniqId(dexReader, idx);
|
||||
methodRef.setDexIdx(idx);
|
||||
methodRef.setSectionReader(this);
|
||||
}
|
||||
|
||||
public void loadMethodRef(DexMethodRef methodRef, int idx) {
|
||||
DexHeader header = dexReader.getHeader();
|
||||
int methodIdsOff = header.getMethodIdsOff();
|
||||
absPos(methodIdsOff + idx * 8);
|
||||
int classTypeIdx = readUShort();
|
||||
int protoIdx = readUShort();
|
||||
int nameIdx = readInt();
|
||||
|
||||
int protoIdsOff = dexReader.getHeader().getProtoIdsOff();
|
||||
int protoIdsOff = header.getProtoIdsOff();
|
||||
absPos(protoIdsOff + protoIdx * 12);
|
||||
int shortyIdx = readInt();
|
||||
skip(4); // shortyIdx
|
||||
int returnTypeIdx = readInt();
|
||||
int paramsOff = readInt();
|
||||
|
||||
@@ -201,18 +206,19 @@ public class SectionReader {
|
||||
} else {
|
||||
argTypes = absPos(paramsOff).readTypeList();
|
||||
}
|
||||
methodData.setName(getString(nameIdx));
|
||||
methodData.setReturnType(getType(returnTypeIdx));
|
||||
methodData.setArgTypes(argTypes);
|
||||
return classTypeIdx;
|
||||
methodRef.setParentClassType(getType(classTypeIdx));
|
||||
methodRef.setName(getString(nameIdx));
|
||||
methodRef.setReturnType(getType(returnTypeIdx));
|
||||
methodRef.setArgTypes(argTypes);
|
||||
}
|
||||
|
||||
public List<String> getMethodParamTypes(int idx) {
|
||||
int methodIdsOff = dexReader.getHeader().getMethodIdsOff();
|
||||
DexHeader header = dexReader.getHeader();
|
||||
int methodIdsOff = header.getMethodIdsOff();
|
||||
absPos(methodIdsOff + idx * 8 + 2);
|
||||
int protoIdx = readUShort();
|
||||
|
||||
int protoIdsOff = dexReader.getHeader().getProtoIdsOff();
|
||||
int protoIdsOff = header.getProtoIdsOff();
|
||||
absPos(protoIdsOff + protoIdx * 12 + 8);
|
||||
int paramsOff = readInt();
|
||||
|
||||
|
||||
+1
-1
@@ -63,7 +63,7 @@ public class EncodedValueParser {
|
||||
return new EncodedValue(EncodedType.ENCODED_TYPE, ext.getType(parseUnsignedInt(in, size)));
|
||||
|
||||
case ENCODED_METHOD:
|
||||
return new EncodedValue(EncodedType.ENCODED_METHOD, ext.getMethodData(parseUnsignedInt(in, size)));
|
||||
return new EncodedValue(EncodedType.ENCODED_METHOD, ext.getMethodRef(parseUnsignedInt(in, size)));
|
||||
|
||||
case ENCODED_FIELD:
|
||||
case ENCODED_ENUM:
|
||||
|
||||
+7
-3
@@ -3,6 +3,7 @@ package jadx.plugins.input.dex.smali;
|
||||
import jadx.api.plugins.input.data.AccessFlags;
|
||||
import jadx.api.plugins.input.data.ICodeReader;
|
||||
import jadx.plugins.input.dex.sections.DexMethodData;
|
||||
import jadx.plugins.input.dex.sections.DexMethodRef;
|
||||
|
||||
import static jadx.api.plugins.input.data.AccessFlagsScope.METHOD;
|
||||
|
||||
@@ -13,9 +14,12 @@ public class SmaliPrinter {
|
||||
SmaliCodeWriter codeWriter = new SmaliCodeWriter();
|
||||
codeWriter.startLine(".method ");
|
||||
codeWriter.add(AccessFlags.format(mth.getAccessFlags(), METHOD));
|
||||
codeWriter.add(mth.getName());
|
||||
codeWriter.add('(').addArgs(mth.getArgTypes()).add(')');
|
||||
codeWriter.add(mth.getReturnType());
|
||||
|
||||
DexMethodRef methodRef = mth.getMethodRef();
|
||||
methodRef.load();
|
||||
codeWriter.add(methodRef.getName());
|
||||
codeWriter.add('(').addArgs(methodRef.getArgTypes()).add(')');
|
||||
codeWriter.add(methodRef.getReturnType());
|
||||
codeWriter.incIndent();
|
||||
|
||||
ICodeReader codeReader = mth.getCodeReader();
|
||||
|
||||
@@ -6,6 +6,9 @@ import java.util.List;
|
||||
public class Utils {
|
||||
|
||||
public static <T> String listToStr(List<T> collection) {
|
||||
if (collection == null) {
|
||||
return "null";
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Iterator<T> it = collection.iterator();
|
||||
if (it.hasNext()) {
|
||||
|
||||
+1
-6
@@ -7,16 +7,11 @@ import org.jetbrains.annotations.Nullable;
|
||||
import jadx.api.plugins.input.data.annotations.IAnnotation;
|
||||
|
||||
public interface IMethodData {
|
||||
String getParentClassType();
|
||||
|
||||
String getName();
|
||||
IMethodRef getMethodRef();
|
||||
|
||||
int getAccessFlags();
|
||||
|
||||
String getReturnType();
|
||||
|
||||
List<String> getArgTypes();
|
||||
|
||||
boolean isDirect();
|
||||
|
||||
@Nullable
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
package jadx.api.plugins.input.data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IMethodRef {
|
||||
|
||||
int getUniqId();
|
||||
|
||||
/**
|
||||
* Lazy loading for method info, until load() is called only getUniqId() can be used
|
||||
*/
|
||||
void load();
|
||||
|
||||
String getParentClassType();
|
||||
|
||||
String getName();
|
||||
|
||||
String getReturnType();
|
||||
|
||||
List<String> getArgTypes();
|
||||
}
|
||||
+2
-2
@@ -3,7 +3,7 @@ package jadx.api.plugins.input.insns;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import jadx.api.plugins.input.data.IFieldData;
|
||||
import jadx.api.plugins.input.data.IMethodData;
|
||||
import jadx.api.plugins.input.data.IMethodRef;
|
||||
import jadx.api.plugins.input.insns.custom.ICustomPayload;
|
||||
|
||||
public interface InsnData {
|
||||
@@ -34,7 +34,7 @@ public interface InsnData {
|
||||
|
||||
IFieldData getIndexAsField();
|
||||
|
||||
IMethodData getIndexAsMethod();
|
||||
IMethodRef getIndexAsMethod();
|
||||
|
||||
@Nullable
|
||||
ICustomPayload getPayload();
|
||||
|
||||
Reference in New Issue
Block a user