From c1292dff75104250960faac387b0b742599bbb26 Mon Sep 17 00:00:00 2001 From: Skylot Date: Sun, 29 Mar 2015 15:15:56 +0300 Subject: [PATCH] core refactor: don't use static field in ArgType class --- .../core/dex/instructions/FillArrayNode.java | 5 ++- .../core/dex/instructions/args/ArgType.java | 42 ++++++++----------- .../dex/instructions/args/LiteralArg.java | 2 +- .../core/dex/instructions/args/Typed.java | 10 +++-- .../java/jadx/core/dex/nodes/RootNode.java | 10 +++-- .../core/dex/visitors/ConstInlineVisitor.java | 30 ++++++------- .../jadx/core/dex/visitors/ModVisitor.java | 6 +-- .../core/dex/visitors/SimplifyVisitor.java | 2 +- .../visitors/regions/LoopRegionVisitor.java | 7 ++-- .../typeinference/FinishTypeInference.java | 4 +- .../typeinference/PostTypeInference.java | 22 +++++----- .../typeinference/SelectTypeVisitor.java | 11 ++--- .../visitors/typeinference/TypeInference.java | 8 ++-- .../tests/functional/JadxClasspathTest.java | 18 +++++--- .../jadx/tests/functional/TypeMergeTest.java | 13 +++++- 15 files changed, 108 insertions(+), 82 deletions(-) diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayNode.java b/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayNode.java index ab821f863..82df854e9 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/FillArrayNode.java @@ -4,6 +4,7 @@ import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.LiteralArg; import jadx.core.dex.instructions.args.PrimitiveType; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.InsnNode; import jadx.core.utils.exceptions.JadxRuntimeException; @@ -57,8 +58,8 @@ public final class FillArrayNode extends InsnNode { return elemType; } - public void mergeElementType(ArgType foundElemType) { - ArgType r = ArgType.merge(elemType, foundElemType); + public void mergeElementType(DexNode dex, ArgType foundElemType) { + ArgType r = ArgType.merge(dex, elemType, foundElemType); if (r != null) { elemType = r; } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java index 69ce659e3..f4a9514f5 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/ArgType.java @@ -1,7 +1,7 @@ package jadx.core.dex.instructions.args; import jadx.core.Consts; -import jadx.core.clsp.ClspGraph; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.parser.SignatureParser; import jadx.core.utils.Utils; @@ -45,16 +45,6 @@ public abstract class ArgType { protected int hash; - private static ClspGraph clsp; - - public static void setClsp(ClspGraph clsp) { - ArgType.clsp = clsp; - } - - public static boolean isClspSet() { - return ArgType.clsp != null; - } - private static ArgType primitive(PrimitiveType stype) { return new PrimitiveArg(stype); } @@ -474,29 +464,28 @@ public abstract class ArgType { public abstract PrimitiveType[] getPossibleTypes(); @Nullable - public static ArgType merge(ArgType a, ArgType b) { + public static ArgType merge(@Nullable DexNode dex, ArgType a, ArgType b) { if (a == null || b == null) { return null; } if (a.equals(b)) { return a; } - ArgType res = mergeInternal(a, b); + ArgType res = mergeInternal(dex, a, b); if (res == null) { - res = mergeInternal(b, a); // swap + res = mergeInternal(dex, b, a); // swap } return res; } - private static ArgType mergeInternal(ArgType a, ArgType b) { + private static ArgType mergeInternal(@Nullable DexNode dex, ArgType a, ArgType b) { if (a == UNKNOWN) { return b; } - if (a.isArray()) { - return mergeArrays((ArrayArg) a, b); + return mergeArrays(dex, (ArrayArg) a, b); } else if (b.isArray()) { - return mergeArrays((ArrayArg) b, a); + return mergeArrays(dex, (ArrayArg) b, a); } if (!a.isTypeKnown()) { if (b.isTypeKnown()) { @@ -546,7 +535,10 @@ public abstract class ArgType { if (bObj.equals(Consts.CLASS_OBJECT)) { return a; } - String obj = clsp.getCommonAncestor(aObj, bObj); + if (dex == null) { + return null; + } + String obj = dex.root().getClsp().getCommonAncestor(aObj, bObj); return obj == null ? null : object(obj); } if (a.isPrimitive() && b.isPrimitive() && a.getRegCount() == b.getRegCount()) { @@ -556,14 +548,14 @@ public abstract class ArgType { return null; } - private static ArgType mergeArrays(ArrayArg array, ArgType b) { + private static ArgType mergeArrays(DexNode dex, ArrayArg array, ArgType b) { if (b.isArray()) { ArgType ea = array.getArrayElement(); ArgType eb = b.getArrayElement(); if (ea.isPrimitive() && eb.isPrimitive()) { return OBJECT; } - ArgType res = merge(ea, eb); + ArgType res = merge(dex, ea, eb); return res == null ? null : array(res); } if (b.contains(PrimitiveType.ARRAY)) { @@ -575,25 +567,25 @@ public abstract class ArgType { return null; } - public static boolean isCastNeeded(ArgType from, ArgType to) { + public static boolean isCastNeeded(DexNode dex, ArgType from, ArgType to) { if (from.equals(to)) { return false; } if (from.isObject() && to.isObject() - && clsp.isImplements(from.getObject(), to.getObject())) { + && dex.root().getClsp().isImplements(from.getObject(), to.getObject())) { return false; } return true; } - public static boolean isInstanceOf(ArgType type, ArgType of) { + public static boolean isInstanceOf(DexNode dex, ArgType type, ArgType of) { if (type.equals(of)) { return true; } if (!type.isObject() || !of.isObject()) { return false; } - return clsp.isImplements(type.getObject(), of.getObject()); + return dex.root().getClsp().isImplements(type.getObject(), of.getObject()); } public static ArgType parse(String type) { diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/LiteralArg.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/LiteralArg.java index e684e251e..291129447 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/LiteralArg.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/LiteralArg.java @@ -17,7 +17,7 @@ public final class LiteralArg extends InsnArg { } else if (!type.isTypeKnown() && !type.contains(PrimitiveType.LONG) && !type.contains(PrimitiveType.DOUBLE)) { - ArgType m = ArgType.merge(type, ArgType.NARROW_NUMBERS); + ArgType m = ArgType.merge(null, type, ArgType.NARROW_NUMBERS); if (m != null) { type = m; } diff --git a/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java b/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java index f3557a3ec..08447b86c 100644 --- a/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java +++ b/jadx-core/src/main/java/jadx/core/dex/instructions/args/Typed.java @@ -1,5 +1,7 @@ package jadx.core.dex.instructions.args; +import jadx.core.dex.nodes.DexNode; + public abstract class Typed { protected ArgType type; @@ -16,8 +18,8 @@ public abstract class Typed { return false; } - public boolean merge(ArgType newType) { - ArgType m = ArgType.merge(type, newType); + public boolean merge(DexNode dex, ArgType newType) { + ArgType m = ArgType.merge(dex, type, newType); if (m != null && !m.equals(type)) { setType(m); return true; @@ -25,7 +27,7 @@ public abstract class Typed { return false; } - public boolean merge(InsnArg arg) { - return merge(arg.getType()); + public boolean merge(DexNode dex, InsnArg arg) { + return merge(dex, arg.getType()); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java index 1328e8611..8ca5a4e0c 100644 --- a/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java +++ b/jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java @@ -6,7 +6,6 @@ import jadx.api.ResourceType; import jadx.api.ResourcesLoader; import jadx.core.clsp.ClspGraph; import jadx.core.dex.info.ClassInfo; -import jadx.core.dex.instructions.args.ArgType; import jadx.core.utils.ErrorsCounter; import jadx.core.utils.exceptions.DecodeException; import jadx.core.utils.exceptions.JadxException; @@ -36,6 +35,7 @@ public class RootNode { @Nullable private String appPackage; private ClassNode appResClass; + private ClspGraph clsp; public RootNode(IJadxArgs args) { this.args = args; @@ -112,7 +112,7 @@ public class RootNode { public void initClassPath() throws DecodeException { try { - if (!ArgType.isClspSet()) { + if (this.clsp == null) { ClspGraph clsp = new ClspGraph(); clsp.load(); @@ -122,7 +122,7 @@ public class RootNode { } clsp.addApp(classes); - ArgType.setClsp(clsp); + this.clsp = clsp; } } catch (IOException e) { throw new DecodeException("Error loading classpath", e); @@ -166,6 +166,10 @@ public class RootNode { return dexNodes; } + public ClspGraph getClsp() { + return clsp; + } + public ErrorsCounter getErrorsCounter() { return errorsCounter; } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlineVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlineVisitor.java index d4dab6e38..6d59cbd94 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlineVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ConstInlineVisitor.java @@ -13,6 +13,7 @@ import jadx.core.dex.instructions.args.PrimitiveType; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.SSAVar; import jadx.core.dex.nodes.BlockNode; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.FieldNode; import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.MethodNode; @@ -65,7 +66,7 @@ public class ConstInlineVisitor extends AbstractVisitor { ArgType resType = insn.getResult().getType(); // make sure arg has correct type if (!arg.getType().isTypeKnown()) { - arg.merge(resType); + arg.merge(mth.dex(), resType); } return replaceConst(mth, insn, lit); } @@ -149,30 +150,31 @@ public class ConstInlineVisitor extends AbstractVisitor { * but contains some expensive operations needed only after constant inline */ private static void fixTypes(MethodNode mth, InsnNode insn, LiteralArg litArg) { + DexNode dex = mth.dex(); PostTypeInference.process(mth, insn); switch (insn.getType()) { case CONST: - insn.getArg(0).merge(insn.getResult()); + insn.getArg(0).merge(dex, insn.getResult()); break; case MOVE: - insn.getResult().merge(insn.getArg(0)); - insn.getArg(0).merge(insn.getResult()); + insn.getResult().merge(dex, insn.getArg(0)); + insn.getArg(0).merge(dex, insn.getResult()); break; case IPUT: case SPUT: IndexInsnNode node = (IndexInsnNode) insn; - insn.getArg(0).merge(((FieldInfo) node.getIndex()).getType()); + insn.getArg(0).merge(dex, ((FieldInfo) node.getIndex()).getType()); break; case IF: { InsnArg arg0 = insn.getArg(0); InsnArg arg1 = insn.getArg(1); if (arg0 == litArg) { - arg0.merge(arg1); + arg0.merge(dex, arg1); } else { - arg1.merge(arg0); + arg1.merge(dex, arg0); } break; } @@ -181,15 +183,15 @@ public class ConstInlineVisitor extends AbstractVisitor { InsnArg arg0 = insn.getArg(0); InsnArg arg1 = insn.getArg(1); if (arg0 == litArg) { - arg0.merge(arg1); + arg0.merge(dex, arg1); } else { - arg1.merge(arg0); + arg1.merge(dex, arg0); } break; case RETURN: if (insn.getArgsCount() != 0) { - insn.getArg(0).merge(mth.getReturnType()); + insn.getArg(0).merge(dex, mth.getReturnType()); } break; @@ -207,26 +209,26 @@ public class ConstInlineVisitor extends AbstractVisitor { } else { type = mth.getParentClass().getClassInfo().getType(); } - arg.merge(type); + arg.merge(dex, type); } k++; } break; case ARITH: - litArg.merge(insn.getResult()); + litArg.merge(dex, insn.getResult()); break; case APUT: case AGET: if (litArg == insn.getArg(1)) { - litArg.merge(ArgType.INT); + litArg.merge(dex, ArgType.INT); } break; case NEW_ARRAY: if (litArg == insn.getArg(0)) { - litArg.merge(ArgType.INT); + litArg.merge(dex, ArgType.INT); } break; diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java index aac7a0f28..a384a34d6 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java @@ -108,9 +108,9 @@ public class ModVisitor extends AbstractVisitor { if (next < size) { InsnNode ni = block.getInstructions().get(next); if (ni.getType() == InsnType.FILL_ARRAY) { - ni.getResult().merge(insn.getResult()); + ni.getResult().merge(mth.dex(), insn.getResult()); ArgType arrType = ((NewArrayNode) insn).getArrayType(); - ((FillArrayNode) ni).mergeElementType(arrType.getArrayElement()); + ((FillArrayNode) ni).mergeElementType(mth.dex(), arrType.getArrayElement()); remover.add(insn); } } @@ -263,7 +263,7 @@ public class ModVisitor extends AbstractVisitor { throw new JadxRuntimeException("Null array element type"); } } - insn.mergeElementType(elType); + insn.mergeElementType(mth.dex(), elType); elType = insn.getElementType(); List list = insn.getLiteralArgs(); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java index e09862e7a..d2b5ecf9f 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/SimplifyVisitor.java @@ -88,7 +88,7 @@ public class SimplifyVisitor extends AbstractVisitor { } } ArgType castToType = (ArgType) ((IndexInsnNode) insn).getIndex(); - if (!ArgType.isCastNeeded(argType, castToType)) { + if (!ArgType.isCastNeeded(mth.dex(), argType, castToType)) { InsnNode insnNode = new InsnNode(InsnType.MOVE, 1); insnNode.setOffset(insn.getOffset()); insnNode.setResult(insn.getResult()); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java index 4722f79cc..834528872 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/regions/LoopRegionVisitor.java @@ -16,6 +16,7 @@ import jadx.core.dex.instructions.args.LiteralArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.SSAVar; import jadx.core.dex.nodes.BlockNode; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.IBlock; import jadx.core.dex.nodes.IRegion; import jadx.core.dex.nodes.InsnNode; @@ -254,7 +255,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor } else { toSkip.add(nextCall); } - if (iterVar == null || !fixIterableType(iterableArg, iterVar)) { + if (iterVar == null || !fixIterableType(mth.dex(), iterableArg, iterVar)) { return false; } @@ -266,7 +267,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor return true; } - private static boolean fixIterableType(InsnArg iterableArg, RegisterArg iterVar) { + private static boolean fixIterableType(DexNode dex, InsnArg iterableArg, RegisterArg iterVar) { ArgType iterableType = iterableArg.getType(); ArgType varType = iterVar.getType(); if (iterableType.isGeneric()) { @@ -282,7 +283,7 @@ public class LoopRegionVisitor extends AbstractVisitor implements IRegionVisitor iterVar.setType(gType); return true; } - if (ArgType.isInstanceOf(gType, varType)) { + if (ArgType.isInstanceOf(dex, gType, varType)) { return true; } LOG.warn("Generic type differs: {} and {}", gType, varType); diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/FinishTypeInference.java b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/FinishTypeInference.java index b002a7f50..981ad8d20 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/FinishTypeInference.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/FinishTypeInference.java @@ -1,6 +1,7 @@ package jadx.core.dex.visitors.typeinference; import jadx.core.dex.nodes.BlockNode; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.visitors.AbstractVisitor; @@ -31,9 +32,10 @@ public class FinishTypeInference extends AbstractVisitor { } while (change); // last chance to set correct value (just use first type from 'possible' list) + DexNode dex = mth.dex(); for (BlockNode block : mth.getBasicBlocks()) { for (InsnNode insn : block.getInstructions()) { - SelectTypeVisitor.visit(insn); + SelectTypeVisitor.visit(dex, insn); } } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/PostTypeInference.java b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/PostTypeInference.java index 8ca2f26cf..dc3d56478 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/PostTypeInference.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/PostTypeInference.java @@ -8,6 +8,7 @@ import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.LiteralArg; import jadx.core.dex.instructions.args.RegisterArg; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.InsnNode; import jadx.core.dex.nodes.MethodNode; @@ -19,6 +20,7 @@ public class PostTypeInference { } public static boolean process(MethodNode mth, InsnNode insn) { + DexNode dex = mth.dex(); switch (insn.getType()) { case CONST: RegisterArg res = insn.getResult(); @@ -34,31 +36,31 @@ public class PostTypeInference { return true; } } - return litArg.merge(res); + return litArg.merge(dex, res); case MOVE: { boolean change = false; - if (insn.getResult().merge(insn.getArg(0))) { + if (insn.getResult().merge(dex, insn.getArg(0))) { change = true; } - if (insn.getArg(0).merge(insn.getResult())) { + if (insn.getArg(0).merge(dex, insn.getResult())) { change = true; } return change; } case AGET: - return fixArrayTypes(insn.getArg(0), insn.getResult()); + return fixArrayTypes(dex, insn.getArg(0), insn.getResult()); case APUT: - return fixArrayTypes(insn.getArg(0), insn.getArg(2)); + return fixArrayTypes(dex, insn.getArg(0), insn.getArg(2)); case IF: { boolean change = false; - if (insn.getArg(1).merge(insn.getArg(0))) { + if (insn.getArg(1).merge(dex, insn.getArg(0))) { change = true; } - if (insn.getArg(0).merge(insn.getArg(1))) { + if (insn.getArg(0).merge(dex, insn.getArg(1))) { change = true; } return change; @@ -138,12 +140,12 @@ public class PostTypeInference { return false; } - private static boolean fixArrayTypes(InsnArg array, InsnArg elem) { + private static boolean fixArrayTypes(DexNode dex, InsnArg array, InsnArg elem) { boolean change = false; - if (!elem.getType().isTypeKnown() && elem.merge(array.getType().getArrayElement())) { + if (!elem.getType().isTypeKnown() && elem.merge(dex, array.getType().getArrayElement())) { change = true; } - if (!array.getType().isTypeKnown() && array.merge(ArgType.array(elem.getType()))) { + if (!array.getType().isTypeKnown() && array.merge(dex, ArgType.array(elem.getType()))) { change = true; } return change; diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/SelectTypeVisitor.java b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/SelectTypeVisitor.java index b7379dbf9..c3fd0a8ef 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/SelectTypeVisitor.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/SelectTypeVisitor.java @@ -2,6 +2,7 @@ package jadx.core.dex.visitors.typeinference; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.InsnNode; public class SelectTypeVisitor { @@ -9,21 +10,21 @@ public class SelectTypeVisitor { private SelectTypeVisitor() { } - public static void visit(InsnNode insn) { + public static void visit(DexNode dex, InsnNode insn) { InsnArg res = insn.getResult(); if (res != null && !res.getType().isTypeKnown()) { - selectType(res); + selectType(dex, res); } for (InsnArg arg : insn.getArguments()) { if (!arg.getType().isTypeKnown()) { - selectType(arg); + selectType(dex, arg); } } } - private static void selectType(InsnArg arg) { + private static void selectType(DexNode dex, InsnArg arg) { ArgType t = arg.getType(); - ArgType newType = ArgType.merge(t, t.selectFirst()); + ArgType newType = ArgType.merge(dex, t, t.selectFirst()); arg.setType(newType); } diff --git a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInference.java b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInference.java index f244b7bee..91ad5efcd 100644 --- a/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInference.java +++ b/jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/TypeInference.java @@ -5,6 +5,7 @@ import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.InsnArg; import jadx.core.dex.instructions.args.RegisterArg; import jadx.core.dex.instructions.args.SSAVar; +import jadx.core.dex.nodes.DexNode; import jadx.core.dex.nodes.MethodNode; import jadx.core.dex.visitors.AbstractVisitor; import jadx.core.utils.exceptions.JadxException; @@ -18,9 +19,10 @@ public class TypeInference extends AbstractVisitor { if (mth.isNoCode()) { return; } + DexNode dex = mth.dex(); for (SSAVar var : mth.getSVars()) { // inference variable type - ArgType type = processType(var); + ArgType type = processType(dex, var); if (type == null) { type = ArgType.UNKNOWN; } @@ -40,7 +42,7 @@ public class TypeInference extends AbstractVisitor { } } - private static ArgType processType(SSAVar var) { + private static ArgType processType(DexNode dex, SSAVar var) { RegisterArg assign = var.getAssign(); List useList = var.getUseList(); if (useList.isEmpty() || var.isTypeImmutable()) { @@ -49,7 +51,7 @@ public class TypeInference extends AbstractVisitor { ArgType type = assign.getType(); for (RegisterArg arg : useList) { ArgType useType = arg.getType(); - ArgType newType = ArgType.merge(type, useType); + ArgType newType = ArgType.merge(dex, type, useType); if (newType != null) { type = newType; } diff --git a/jadx-core/src/test/java/jadx/tests/functional/JadxClasspathTest.java b/jadx-core/src/test/java/jadx/tests/functional/JadxClasspathTest.java index 0604d8f03..28448ca6b 100644 --- a/jadx-core/src/test/java/jadx/tests/functional/JadxClasspathTest.java +++ b/jadx-core/src/test/java/jadx/tests/functional/JadxClasspathTest.java @@ -2,6 +2,8 @@ package jadx.tests.functional; import jadx.core.clsp.ClspGraph; import jadx.core.dex.instructions.args.ArgType; +import jadx.core.dex.nodes.DexNode; +import jadx.core.dex.nodes.RootNode; import jadx.core.utils.exceptions.DecodeException; import java.io.IOException; @@ -13,19 +15,25 @@ import static jadx.core.dex.instructions.args.ArgType.STRING; import static jadx.core.dex.instructions.args.ArgType.object; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class JadxClasspathTest { private static final String JAVA_LANG_EXCEPTION = "java.lang.Exception"; private static final String JAVA_LANG_THROWABLE = "java.lang.Throwable"; - ClspGraph clsp; + private DexNode dex; + private ClspGraph clsp; @Before public void initClsp() throws IOException, DecodeException { clsp = new ClspGraph(); clsp.load(); - ArgType.setClsp(clsp); + dex = mock(DexNode.class); + RootNode rootNode = mock(RootNode.class); + when(rootNode.getClsp()).thenReturn(clsp); + when(dex.root()).thenReturn(rootNode); } @Test @@ -36,9 +44,9 @@ public class JadxClasspathTest { assertTrue(clsp.isImplements(JAVA_LANG_EXCEPTION, JAVA_LANG_THROWABLE)); assertFalse(clsp.isImplements(JAVA_LANG_THROWABLE, JAVA_LANG_EXCEPTION)); - assertFalse(ArgType.isCastNeeded(objExc, objThr)); - assertTrue(ArgType.isCastNeeded(objThr, objExc)); + assertFalse(ArgType.isCastNeeded(dex, objExc, objThr)); + assertTrue(ArgType.isCastNeeded(dex, objThr, objExc)); - assertTrue(ArgType.isCastNeeded(ArgType.OBJECT, STRING)); + assertTrue(ArgType.isCastNeeded(dex, ArgType.OBJECT, STRING)); } } diff --git a/jadx-core/src/test/java/jadx/tests/functional/TypeMergeTest.java b/jadx-core/src/test/java/jadx/tests/functional/TypeMergeTest.java index e56c5930b..ec51233ce 100644 --- a/jadx-core/src/test/java/jadx/tests/functional/TypeMergeTest.java +++ b/jadx-core/src/test/java/jadx/tests/functional/TypeMergeTest.java @@ -3,6 +3,8 @@ package jadx.tests.functional; import jadx.core.clsp.ClspGraph; import jadx.core.dex.instructions.args.ArgType; import jadx.core.dex.instructions.args.PrimitiveType; +import jadx.core.dex.nodes.DexNode; +import jadx.core.dex.nodes.RootNode; import jadx.core.utils.exceptions.DecodeException; import java.io.IOException; @@ -27,14 +29,21 @@ import static jadx.core.dex.instructions.args.ArgType.unknown; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; public class TypeMergeTest { + private DexNode dex; + @Before public void initClsp() throws IOException, DecodeException { ClspGraph clsp = new ClspGraph(); clsp.load(); - ArgType.setClsp(clsp); + dex = mock(DexNode.class); + RootNode rootNode = mock(RootNode.class); + when(rootNode.getClsp()).thenReturn(clsp); + when(dex.root()).thenReturn(rootNode); } @Test @@ -103,7 +112,7 @@ public class TypeMergeTest { } private void merge(ArgType t1, ArgType t2, ArgType exp) { - ArgType res = ArgType.merge(t1, t2); + ArgType res = ArgType.merge(dex, t1, t2); String msg = format(t1, t2, exp, res); if (exp == null) { assertNull("Incorrect accept: " + msg, res);