提交 67eb55a9 编写于 作者: S Skylot

gui: add type and access info to classes tree

上级 fa097cc6
......@@ -12,7 +12,6 @@ public class JadxCLI {
JadxArgs jadxArgs = new JadxArgs(args, true);
Decompiler jadx = new Decompiler(jadxArgs);
jadx.processAndSaveAll();
LOG.info("done");
System.exit(jadx.getErrorsCount());
}
}
......@@ -91,7 +91,7 @@ public final class Decompiler {
return Collections.unmodifiableList(packages);
}
public ThreadPoolExecutor saveAll(File dir) throws InterruptedException {
public ThreadPoolExecutor saveAll(File dir) {
int threadsCount = args.getThreadsCount();
LOG.debug("processing threads count: {}", threadsCount);
......
package jadx.api;
import jadx.core.codegen.CodeWriter;
import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.nodes.ClassNode;
import jadx.core.dex.nodes.FieldNode;
......@@ -51,7 +50,7 @@ public final class JavaClass {
} else {
List<JavaMethod> mths = new ArrayList<JavaMethod>(methodsCount);
for (MethodNode m : cls.getMethods()) {
if (!m.getAttributes().contains(AttributeFlag.DONT_GENERATE)) {
if (!m.getAccessFlags().isSynthetic()) {
mths.add(new JavaMethod(m));
}
}
......
package jadx.api;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.nodes.FieldNode;
public class JavaField {
......@@ -19,6 +20,10 @@ public class JavaField {
return field.getAccessFlags();
}
public ArgType getType() {
return field.getType();
}
public int getDecompiledLine() {
return field.getDecompiledLine();
}
......
......@@ -2,8 +2,11 @@ package jadx.api;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.info.MethodInfo;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.dex.nodes.MethodNode;
import java.util.List;
public class JavaMethod {
private final MethodNode mth;
......@@ -25,6 +28,22 @@ public class JavaMethod {
return mth.getAccessFlags();
}
public List<ArgType> getArguments() {
return mth.getMethodInfo().getArgumentsTypes();
}
public ArgType getReturnType() {
return mth.getReturnType();
}
public boolean isConstructor() {
return mth.getMethodInfo().isConstructor();
}
public boolean isClassInit() {
return mth.getMethodInfo().isClassInit();
}
public int getDecompiledLine() {
return mth.getDecompiledLine();
}
......
......@@ -481,7 +481,7 @@ public class InsnGen {
private void makeInvoke(InvokeNode insn, CodeWriter code) throws CodegenException {
MethodInfo callMth = insn.getCallMth();
// inline method if METHOD_INLINE attribute is attached
// inline method
MethodNode callMthNode = mth.dex().resolveMethod(callMth);
if (callMthNode != null
&& callMthNode.getAttributes().contains(AttributeType.METHOD_INLINE)) {
......@@ -507,8 +507,10 @@ public class InsnGen {
case STATIC:
ClassInfo insnCls = mth.getParentClass().getClassInfo();
if (!insnCls.equals(callMth.getDeclClass()))
code.add(useClass(callMth.getDeclClass())).add('.');
ClassInfo declClass = callMth.getDeclClass();
if (!insnCls.equals(declClass)) {
code.add(useClass(declClass)).add('.');
}
break;
}
code.add(callMth.getName());
......
......@@ -93,6 +93,18 @@ public class AccessInfo {
return (accFlags & AccessFlags.ACC_VARARGS) != 0;
}
public boolean isSynchronized() {
return (accFlags & (AccessFlags.ACC_SYNCHRONIZED | AccessFlags.ACC_DECLARED_SYNCHRONIZED)) != 0;
}
public boolean isTransient() {
return (accFlags & AccessFlags.ACC_TRANSIENT) != 0;
}
public boolean isVolatile() {
return (accFlags & AccessFlags.ACC_VOLATILE) != 0;
}
public int getFlags() {
return accFlags;
}
......@@ -126,10 +138,7 @@ public class AccessInfo {
switch (type) {
case METHOD:
if ((accFlags & AccessFlags.ACC_SYNCHRONIZED) != 0)
code.append("synchronized ");
if ((accFlags & AccessFlags.ACC_DECLARED_SYNCHRONIZED) != 0)
if (isSynchronized())
code.append("synchronized ");
if (isBridge())
......@@ -142,10 +151,10 @@ public class AccessInfo {
break;
case FIELD:
if ((accFlags & AccessFlags.ACC_VOLATILE) != 0)
if (isVolatile())
code.append("volatile ");
if ((accFlags & AccessFlags.ACC_TRANSIENT) != 0)
if (isTransient())
code.append("transient ");
break;
......
package jadx.core.dex.visitors;
import jadx.core.dex.attributes.AttributeFlag;
import jadx.core.dex.attributes.IAttribute;
import jadx.core.dex.attributes.AttributesList;
import jadx.core.dex.attributes.MethodInlineAttr;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.instructions.InsnType;
......@@ -43,8 +43,8 @@ public class MethodInlinerVisitor extends AbstractVisitor {
}
private static void addInlineAttr(MethodNode mth, InsnNode insn) {
IAttribute attr = new MethodInlineAttr(insn);
mth.getAttributes().add(attr);
mth.getAttributes().add(AttributeFlag.DONT_GENERATE);
AttributesList attributes = mth.getAttributes();
attributes.add(new MethodInlineAttr(insn));
attributes.add(AttributeFlag.DONT_GENERATE);
}
}
......@@ -8,7 +8,6 @@ import jadx.core.utils.exceptions.CodegenException;
import java.io.File;
public class SaveCode extends AbstractVisitor {
private final File dir;
private final IJadxArgs args;
......@@ -22,13 +21,10 @@ public class SaveCode extends AbstractVisitor {
CodeWriter clsCode = cls.getCode();
String fileName = cls.getClassInfo().getFullPath() + ".java";
if (isFallbackMode())
if (args.isFallbackMode()) {
fileName += ".jadx";
}
clsCode.save(dir, fileName);
return false;
}
public boolean isFallbackMode() {
return args.isFallbackMode();
}
}
......@@ -33,6 +33,7 @@ public class JClass extends DefaultMutableTreeNode implements JNode {
@Override
public void updateChilds() {
removeAllChildren();
JClass currentParent = jParrent == null ? this : jParrent;
for (JavaClass javaClass : cls.getInnerClasses()) {
JClass child = new JClass(javaClass);
......
......@@ -2,18 +2,22 @@ package jadx.gui.treemodel;
import jadx.api.JavaField;
import jadx.core.dex.info.AccessInfo;
import jadx.gui.utils.OverlayIcon;
import jadx.gui.utils.Utils;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.tree.DefaultMutableTreeNode;
public class JField extends DefaultMutableTreeNode implements JNode {
public class JField extends DefaultMutableTreeNode implements JNode {
private static final ImageIcon ICON_FLD_DEF = Utils.openIcon("field_default_obj");
private static final ImageIcon ICON_FLD_PRI = Utils.openIcon("field_private_obj");
private static final ImageIcon ICON_FLD_PRO = Utils.openIcon("field_protected_obj");
private static final ImageIcon ICON_FLD_PUB = Utils.openIcon("field_public_obj");
private static final ImageIcon ICON_TRANSIENT = Utils.openIcon("transient_co");
private static final ImageIcon ICON_VOLATILE = Utils.openIcon("volatile_co");
private final JavaField field;
private final JClass jParent;
......@@ -39,19 +43,14 @@ public class JField extends DefaultMutableTreeNode implements JNode {
@Override
public Icon getIcon() {
AccessInfo af = field.getAccessFlags();
if(af.isPublic()){
return ICON_FLD_PUB;
} else if(af.isPrivate()) {
return ICON_FLD_PRI;
} else if(af.isProtected()) {
return ICON_FLD_PRO;
} else {
return ICON_FLD_DEF;
}
OverlayIcon icon = Utils.makeIcon(af, ICON_FLD_PUB, ICON_FLD_PRI, ICON_FLD_PRO, ICON_FLD_DEF);
if (af.isTransient()) icon.add(ICON_TRANSIENT);
if (af.isVolatile()) icon.add(ICON_VOLATILE);
return icon;
}
@Override
public String toString() {
return field.getName();
return Utils.typeFormat(field.getName(), field.getType());
}
}
......@@ -2,11 +2,14 @@ package jadx.gui.treemodel;
import jadx.api.JavaMethod;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.instructions.args.ArgType;
import jadx.gui.utils.OverlayIcon;
import jadx.gui.utils.Utils;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.tree.DefaultMutableTreeNode;
import java.util.Iterator;
public class JMethod extends DefaultMutableTreeNode implements JNode {
private static final ImageIcon ICON_MTH_DEF = Utils.openIcon("methdef_obj");
......@@ -14,6 +17,9 @@ public class JMethod extends DefaultMutableTreeNode implements JNode {
private static final ImageIcon ICON_MTH_PRO = Utils.openIcon("methpro_obj");
private static final ImageIcon ICON_MTH_PUB = Utils.openIcon("methpub_obj");
private static final ImageIcon ICON_CONSTRUCTOR = Utils.openIcon("constr_ovr");
private static final ImageIcon ICON_SYNC = Utils.openIcon("synch_co");
private final JavaMethod mth;
private final JClass jparent;
......@@ -38,20 +44,28 @@ public class JMethod extends DefaultMutableTreeNode implements JNode {
@Override
public Icon getIcon() {
AccessInfo af = mth.getAccessFlags();
if (af.isPublic()) {
return ICON_MTH_PUB;
} else if (af.isPrivate()) {
return ICON_MTH_PRI;
} else if (af.isProtected()) {
return ICON_MTH_PRO;
} else {
return ICON_MTH_DEF;
}
AccessInfo accessFlags = mth.getAccessFlags();
OverlayIcon icon = Utils.makeIcon(accessFlags, ICON_MTH_PUB, ICON_MTH_PRI, ICON_MTH_PRO, ICON_MTH_DEF);
if(accessFlags.isConstructor()) icon.add(ICON_CONSTRUCTOR);
if (accessFlags.isSynchronized()) icon.add(ICON_SYNC);
return icon;
}
@Override
public String toString() {
return mth.getName();
if (mth.isClassInit()) {
return "{...}";
}
StringBuilder base = new StringBuilder();
base.append(mth.getName());
base.append('(');
for (Iterator<ArgType> it = mth.getArguments().iterator(); it.hasNext(); ) {
base.append(Utils.typeStr(it.next()));
if(it.hasNext())
base.append(", ");
}
base.append(')');
return Utils.typeFormat(base.toString(), mth.getReturnType());
}
}
package jadx.gui.utils;
import javax.swing.Icon;
import java.awt.Component;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class OverlayIcon implements Icon {
private final Icon icon;
private final List<Icon> icons = new ArrayList<Icon>(4);
private static final double A = 0.8;
private static final double B = 0.2;
private static final double[] pos = new double[]{A, B, B, B, A, A, B, A};
public OverlayIcon(Icon icon) {
this.icon = icon;
}
@Override
public int getIconHeight() {
return icon.getIconHeight();
}
@Override
public int getIconWidth() {
return icon.getIconWidth();
}
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
int w = getIconWidth();
int h = getIconHeight();
icon.paintIcon(c, g, x, y);
int k = 0;
for (Icon icon : icons) {
int dx = (int) (pos[k++] * (w - icon.getIconWidth()));
int dy = (int) (pos[k++] * (h - icon.getIconHeight()));
icon.paintIcon(c, g, x + dx, y + dy);
}
}
public void add(Icon icon) {
icons.add(icon);
}
public void addAll(Collection<Icon> icons) {
icons.addAll(icons);
}
public List<Icon> getIcons() {
return icons;
}
}
package jadx.gui.utils;
import jadx.core.dex.info.AccessInfo;
import jadx.core.dex.instructions.args.ArgType;
import jadx.core.utils.exceptions.JadxRuntimeException;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
......@@ -10,6 +13,11 @@ import java.net.URL;
public class Utils {
private static final ImageIcon ICON_STATIC = Utils.openIcon("static_co");
private static final ImageIcon ICON_FINAL = Utils.openIcon("final_co");
private static final ImageIcon ICON_ABSTRACT = Utils.openIcon("abstract_co");
private static final ImageIcon ICON_NATIVE = Utils.openIcon("native_co");
public static ImageIcon openIcon(String name) {
String iconPath = "/icons-16/" + name + ".png";
URL resource = Utils.class.getResource(iconPath);
......@@ -23,4 +31,43 @@ public class Utils {
comp.getInputMap().put(key, id);
comp.getActionMap().put(id, action);
}
public static String typeFormat(String name, ArgType type) {
return "<html>" + name + "<span style='color:#888888;'> : " + typeStr(type) + "</span></html>";
}
public static String typeStr(ArgType type) {
if (type.isObject()) {
String cls = type.getObject();
int dot = cls.lastIndexOf('.');
if (dot != -1) {
return cls.substring(dot + 1);
} else {
return cls;
}
}
if (type.isArray()) {
return typeStr(type.getArrayElement()) + "[]";
}
return type.toString();
}
public static OverlayIcon makeIcon(AccessInfo af, Icon pub, Icon pri, Icon pro, Icon def) {
Icon icon;
if (af.isPublic()) {
icon = pub;
} else if (af.isPrivate()) {
icon = pri;
} else if (af.isProtected()) {
icon = pro;
} else {
icon = def;
}
OverlayIcon overIcon = new OverlayIcon(icon);
if (af.isFinal()) overIcon.add(ICON_FINAL);
if (af.isStatic()) overIcon.add(ICON_STATIC);
if (af.isAbstract()) overIcon.add(ICON_ABSTRACT);
if (af.isNative()) overIcon.add(ICON_NATIVE);
return overIcon;
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册