From 62a28c8e88f3754a271b2ffd858250eb314fb05b Mon Sep 17 00:00:00 2001 From: Skylot Date: Sun, 7 Apr 2013 15:39:50 +0400 Subject: [PATCH] Remove empty public constructors --- src/main/java/jadx/Main.java | 3 +- src/main/java/jadx/dex/info/AccessInfo.java | 18 ++++++++++-- src/main/java/jadx/dex/info/ClassInfo.java | 4 +-- .../java/jadx/dex/visitors/ClassModifier.java | 28 +++++++++++++++++-- 4 files changed, 44 insertions(+), 9 deletions(-) diff --git a/src/main/java/jadx/Main.java b/src/main/java/jadx/Main.java index 2438139b2..0d0aab170 100644 --- a/src/main/java/jadx/Main.java +++ b/src/main/java/jadx/Main.java @@ -98,8 +98,6 @@ public class Main { if (args.isRawCFGOutput()) passes.add(new DotGraphVisitor(args.getOutDir(), false, true)); - passes.add(new ClassModifier()); - passes.add(new ModVisitor()); passes.add(new EnumVisitor()); @@ -115,6 +113,7 @@ public class Main { if (args.isCFGOutput()) passes.add(new DotGraphVisitor(args.getOutDir(), true)); + passes.add(new ClassModifier()); passes.add(new CleanRegions()); } passes.add(new CodeGen(args)); diff --git a/src/main/java/jadx/dex/info/AccessInfo.java b/src/main/java/jadx/dex/info/AccessInfo.java index 9a71f0558..437f4c73b 100644 --- a/src/main/java/jadx/dex/info/AccessInfo.java +++ b/src/main/java/jadx/dex/info/AccessInfo.java @@ -37,6 +37,18 @@ public class AccessInfo { return new AccessInfo(f, type); } + public boolean isPublic() { + return (accFlags & AccessFlags.ACC_PUBLIC) != 0; + } + + public boolean isProtected() { + return (accFlags & AccessFlags.ACC_PROTECTED) != 0; + } + + public boolean isPrivate() { + return (accFlags & AccessFlags.ACC_PRIVATE) != 0; + } + public boolean isAbstract() { return (accFlags & AccessFlags.ACC_ABSTRACT) != 0; } @@ -87,13 +99,13 @@ public class AccessInfo { public String makeString() { StringBuilder code = new StringBuilder(); - if ((accFlags & AccessFlags.ACC_PUBLIC) != 0) + if (isPublic()) code.append("public "); - if ((accFlags & AccessFlags.ACC_PRIVATE) != 0) + if (isPrivate()) code.append("private "); - if ((accFlags & AccessFlags.ACC_PROTECTED) != 0) + if (isProtected()) code.append("protected "); if (isStatic()) diff --git a/src/main/java/jadx/dex/info/ClassInfo.java b/src/main/java/jadx/dex/info/ClassInfo.java index 23f74c08e..d893b093a 100644 --- a/src/main/java/jadx/dex/info/ClassInfo.java +++ b/src/main/java/jadx/dex/info/ClassInfo.java @@ -5,12 +5,12 @@ import jadx.dex.instructions.args.ArgType; import jadx.dex.nodes.DexNode; import java.io.File; -import java.util.HashMap; import java.util.Map; +import java.util.WeakHashMap; public final class ClassInfo { - private static final Map CLASSINFO_CACHE = new HashMap(); + private static final Map CLASSINFO_CACHE = new WeakHashMap(); private static final String DEFAULT_PACKAGE_NAME = "defpackage"; private final String clsName; diff --git a/src/main/java/jadx/dex/visitors/ClassModifier.java b/src/main/java/jadx/dex/visitors/ClassModifier.java index d14e77bee..198fba931 100644 --- a/src/main/java/jadx/dex/visitors/ClassModifier.java +++ b/src/main/java/jadx/dex/visitors/ClassModifier.java @@ -1,11 +1,13 @@ package jadx.dex.visitors; import jadx.dex.info.AccessInfo; +import jadx.dex.nodes.BlockNode; import jadx.dex.nodes.ClassNode; import jadx.dex.nodes.MethodNode; import jadx.utils.exceptions.JadxException; import java.util.Iterator; +import java.util.List; public class ClassModifier extends AbstractVisitor { @@ -21,10 +23,32 @@ public class ClassModifier extends AbstractVisitor { // remove bridge methods if (af.isBridge() && af.isSynthetic()) { - // TODO make some checks before deleting - it.remove(); + if (!isMethodIdUniq(cls, mth)) { + // TODO add more checks before method deletion + it.remove(); + } + } + + // remove public empty constructors + if (af.isConstructor() + && af.isPublic() + && mth.getArguments(false).isEmpty()) { + List bb = mth.getBasicBlocks(); + if (bb.isEmpty() || (bb.size() == 1 && bb.get(0).getInstructions().isEmpty())) { + it.remove(); + } } } return false; } + + private boolean isMethodIdUniq(ClassNode cls, MethodNode mth) { + String shortId = mth.getMethodInfo().getShortId(); + for (MethodNode otherMth : cls.getMethods()) { + if (otherMth.getMethodInfo().getShortId().equals(shortId) + && otherMth != mth) + return false; + } + return true; + } }