Skip to content

Commit 54d2c2f

Browse files
committed
Bytecode decompiler improvements
- Implement MultiANewArray - Display return type in method name - Move method descriptor up and make it a complete descriptor - Create option for method descriptors - Do not display <init> comment if descriptors are on - Fix some spacing - Fix some capitalization
1 parent 87ba29e commit 54d2c2f

File tree

3 files changed

+91
-37
lines changed

3 files changed

+91
-37
lines changed

src/main/java/the/bytecode/club/jda/decompilers/bytecode/ClassNodeDecompiler.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import the.bytecode.club.jda.settings.DecompilerSettings;
1212

1313
import java.util.ArrayList;
14+
import java.util.Iterator;
1415
import java.util.List;
1516

1617
/**
@@ -81,20 +82,21 @@ protected static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, Array
8182
}
8283
sb.append(" {");
8384
sb.append(JDA.nl);
84-
for (FieldNode fn : cn.fields)
85+
86+
for (Iterator<FieldNode> it = cn.fields.iterator(); it.hasNext(); )
8587
{
86-
sb.append(JDA.nl);
8788
sb.append(" ");
88-
FieldNodeDecompiler.decompile(sb, fn);
89-
}
90-
if (cn.fields.size() > 0)
91-
{
89+
FieldNodeDecompiler.decompile(sb, it.next());
9290
sb.append(JDA.nl);
91+
if (!it.hasNext())
92+
sb.append(JDA.nl);
9393
}
94-
for (MethodNode mn : cn.methods)
94+
95+
for (Iterator<MethodNode> it = cn.methods.iterator(); it.hasNext(); )
9596
{
96-
sb.append(JDA.nl);
97-
MethodNodeDecompiler.decompile(sb, mn, cn);
97+
MethodNodeDecompiler.decompile(sb, it.next(), cn);
98+
if (it.hasNext())
99+
sb.append(JDA.nl);
98100
}
99101

100102
for (Object o : cn.innerClasses)
@@ -122,7 +124,7 @@ protected static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, Array
122124

123125
if (!unableToDecompile.isEmpty())
124126
{
125-
sb.append("//the following inner classes couldn't be decompiled: ");
127+
sb.append("// The following inner classes couldn't be decompiled: ");
126128
for (String s : unableToDecompile)
127129
{
128130
sb.append(s);
@@ -183,7 +185,8 @@ public void decompileToZip(String zipName)
183185
public enum Settings implements DecompilerSettings.Setting
184186
{
185187
DEBUG_HELPERS("debug-helpers", "Debug Helpers", true),
186-
APPEND_BRACKETS_TO_LABELS("append-brackets-to-labels", "Append Brackets to Labels", true);
188+
APPEND_BRACKETS_TO_LABELS("append-brackets-to-labels", "Append Brackets to Labels", true),
189+
SHOW_METHOD_DESCRIPTORS("show-method-descriptors", "Show Method Descriptors", true);
187190

188191
private String name;
189192
private String param;

src/main/java/the/bytecode/club/jda/decompilers/bytecode/InstructionPrinter.java

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import org.objectweb.asm.Type;
66
import org.objectweb.asm.tree.*;
77
import the.bytecode.club.jda.api.ExceptionUI;
8-
import the.bytecode.club.jda.decompilers.Decompiler;
98

109
import java.io.BufferedWriter;
1110
import java.io.File;
@@ -14,6 +13,9 @@
1413
import java.lang.reflect.Modifier;
1514
import java.util.*;
1615

16+
import static the.bytecode.club.jda.decompilers.bytecode.MethodNodeDecompiler.createComments;
17+
import static the.bytecode.club.jda.decompilers.bytecode.MethodNodeDecompiler.createLabelBrackets;
18+
1719
/**
1820
* @author Konloch
1921
* @author Bibl
@@ -73,7 +75,7 @@ public ArrayList<String> createPrint()
7375
while (it.hasNext())
7476
{
7577
AbstractInsnNode ain = (AbstractInsnNode) it.next();
76-
String line = "";
78+
String line;
7779
if (ain instanceof VarInsnNode)
7880
{
7981
line = printVarInsnNode((VarInsnNode) ain, it);
@@ -108,12 +110,12 @@ else if (ain instanceof LineNumberNode)
108110
}
109111
else if (ain instanceof LabelNode)
110112
{
111-
if (firstLabel && Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS))
113+
if (firstLabel && createLabelBrackets())
112114
info.add("}");
113115

114116
line = printLabelnode((LabelNode) ain);
115117

116-
if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS))
118+
if (createLabelBrackets())
117119
{
118120
if (!firstLabel)
119121
firstLabel = true;
@@ -144,9 +146,13 @@ else if (ain instanceof InvokeDynamicInsnNode)
144146
{
145147
line = printInvokeDynamicInsNode((InvokeDynamicInsnNode) ain);
146148
}
149+
else if (ain instanceof MultiANewArrayInsnNode)
150+
{
151+
line = printMultiANewArrayInsnNode((MultiANewArrayInsnNode) ain);
152+
}
147153
else
148154
{
149-
line += "UNADDED OPCODE: " + nameOpcode(ain.opcode()) + " " + ain.toString();
155+
line = "// UNADDED OPCODE: " + nameOpcode(ain.opcode()) + " " + ain.toString();
150156
}
151157
if (!line.equals(""))
152158
{
@@ -157,7 +163,7 @@ else if (ain instanceof InvokeDynamicInsnNode)
157163
info.add(line);
158164
}
159165
}
160-
if (firstLabel && Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS))
166+
if (firstLabel && createLabelBrackets())
161167
info.add("}");
162168
return info;
163169
}
@@ -167,18 +173,18 @@ protected String printVarInsnNode(VarInsnNode vin, ListIterator<?> it)
167173
StringBuilder sb = new StringBuilder();
168174
sb.append(nameOpcode(vin.opcode()));
169175
sb.append(vin.var);
170-
if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.DEBUG_HELPERS))
176+
if (createComments())
171177
{
172178
if (vin.var == 0 && !Modifier.isStatic(mNode.access))
173179
{
174-
sb.append(" // reference to self");
180+
sb.append(" // Reference to self");
175181
}
176182
else
177183
{
178184
final int refIndex = vin.var - (Modifier.isStatic(mNode.access) ? 0 : 1);
179185
if (refIndex >= 0 && refIndex < args.length - 1)
180186
{
181-
sb.append(" // reference to ").append(args[refIndex].name);
187+
sb.append(" // Reference to ").append(args[refIndex].name);
182188
}
183189
}
184190
}
@@ -277,7 +283,7 @@ protected String printTypeInsnNode(TypeInsnNode tin)
277283
{
278284
new ExceptionUI(e);
279285
}
280-
return "//error";
286+
return "// error";
281287
}
282288

283289
protected String printIincInsnNode(IincInsnNode iin)
@@ -341,6 +347,11 @@ protected String printInvokeDynamicInsNode(InvokeDynamicInsnNode idin)
341347
return sb.toString();
342348
}
343349

350+
protected String printMultiANewArrayInsnNode(MultiANewArrayInsnNode manain)
351+
{
352+
return nameOpcode(manain.opcode()) + " " + manain.desc;
353+
}
354+
344355
protected String nameOpcode(int opcode)
345356
{
346357
return " " + OpcodeInfo.OPCODES.get(opcode).toLowerCase();

src/main/java/the/bytecode/club/jda/decompilers/bytecode/MethodNodeDecompiler.java

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,33 @@ public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNo
3333
class_ = cn.name;
3434
}
3535

36-
String s = getAccessString(m.access);
36+
// Descriptor
37+
if (createDescriptors())
38+
{
39+
sb.append(" // ");
40+
sb.append(m.owner.name);
41+
sb.append(".");
42+
sb.append(m.name);
43+
sb.append(m.desc);
44+
sb.append(JDA.nl);
45+
}
46+
47+
// Access
48+
String access = getAccessString(m.access);
3749
sb.append(" ");
38-
sb.append(s);
39-
if (s.length() > 0)
50+
sb.append(access);
51+
if (access.length() > 0 && !m.name.equals("<clinit>"))
52+
sb.append(" ");
53+
54+
// Return type
55+
if (m.name.charAt(0) != '<' && !m.name.endsWith("init>"))
56+
{
57+
Type returnType = Type.getReturnType(m.desc);
58+
sb.append(returnType.getClassName());
4059
sb.append(" ");
60+
}
4161

62+
// Method name
4263
if (m.name.equals("<init>"))
4364
{
4465
sb.append(class_);
@@ -51,8 +72,8 @@ else if (m.name.equals("<clinit>"))
5172
sb.append(m.name);
5273
}
5374

75+
// Arguments
5476
TypeAndName[] args = new TypeAndName[0];
55-
5677
if (!m.name.equals("<clinit>"))
5778
{
5879
sb.append("(");
@@ -78,6 +99,7 @@ else if (m.name.equals("<clinit>"))
7899
sb.append(")");
79100
}
80101

102+
// Throws
81103
int amountOfThrows = m.exceptions.size();
82104
if (amountOfThrows > 0)
83105
{
@@ -90,31 +112,28 @@ else if (m.name.equals("<clinit>"))
90112
}
91113
}
92114

93-
if (s.contains("abstract"))
115+
// End method name
116+
if (access.contains("abstract"))
94117
{
95-
sb.append(" {}");
96-
sb.append(" //");
97-
sb.append(m.desc);
98-
sb.append(JDA.nl);
118+
sb.append(";");
99119
}
100120
else
101121
{
102-
103122
sb.append(" {");
104123

105-
if (Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.DEBUG_HELPERS))
124+
if (createComments() && !createDescriptors())
106125
{
107126
if (m.name.equals("<clinit>"))
108127
sb.append(" // <clinit>");
109128
else if (m.name.equals("<init>"))
110129
sb.append(" // <init>");
111130
}
131+
}
132+
sb.append(JDA.nl);
112133

113-
sb.append(" //");
114-
sb.append(m.desc);
115-
116-
sb.append(JDA.nl);
117-
134+
// Code
135+
if (!access.contains("abstract"))
136+
{
118137
if (m.signature != null)
119138
{
120139
sb.append(" <sig:").append(m.signature).append(">");
@@ -137,6 +156,7 @@ else if (m.name.equals("<init>"))
137156
addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno", sb, insnPrinter);
138157
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb, insnPrinter);
139158

159+
// Exception table
140160
for (Object o : m.tryCatchBlocks)
141161
{
142162
TryCatchBlockNode tcbn = (TryCatchBlockNode) o;
@@ -154,14 +174,19 @@ else if (m.name.equals("<init>"))
154174
sb.append("Type is null.");
155175
sb.append(JDA.nl);
156176
}
177+
178+
// Instructions
157179
for (String insn : insnPrinter.createPrint())
158180
{
159181
sb.append(" ");
160182
sb.append(insn);
161183
sb.append(JDA.nl);
162184
}
185+
186+
// Closing brace
163187
sb.append(" }" + JDA.nl);
164188
}
189+
165190
return sb;
166191
}
167192

@@ -251,4 +276,19 @@ private static String getAccessString(int access)
251276
}
252277
return sb.toString();
253278
}
279+
280+
static boolean createComments()
281+
{
282+
return Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.DEBUG_HELPERS);
283+
}
284+
285+
static boolean createLabelBrackets()
286+
{
287+
return Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.APPEND_BRACKETS_TO_LABELS);
288+
}
289+
290+
static boolean createDescriptors()
291+
{
292+
return Decompiler.BYTECODE.getSettings().isSelected(ClassNodeDecompiler.Settings.SHOW_METHOD_DESCRIPTORS);
293+
}
254294
}

0 commit comments

Comments
 (0)