Skip to content

Commit 5d5182d

Browse files
committed
Refactor bytecode decompilers to be more modular
1 parent c5a6bde commit 5d5182d

File tree

3 files changed

+67
-39
lines changed

3 files changed

+67
-39
lines changed

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

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public String decompileClassNode(ClassNode cn, byte[] b) {
4545
return decompile(new PrefixedStringBuilder(), new ArrayList<>(), containerName, cn).toString();
4646
}
4747

48-
protected static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, ArrayList<String> decompiledClasses, String containerName, ClassNode cn) {
48+
protected PrefixedStringBuilder decompile(PrefixedStringBuilder sb, ArrayList<String> decompiledClasses, String containerName, ClassNode cn) {
4949
ArrayList<String> unableToDecompile = new ArrayList<>();
5050
decompiledClasses.add(cn.name);
5151
sb.append(getAccessString(cn.access));
@@ -73,14 +73,14 @@ protected static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, Array
7373

7474
for (Iterator<FieldNode> it = cn.fields.iterator(); it.hasNext(); ) {
7575
sb.append(" ");
76-
FieldNodeDecompiler.decompile(sb, it.next());
76+
getFieldNodeDecompiler(sb, it).decompile();
7777
sb.append(JDA.nl);
7878
if (!it.hasNext())
7979
sb.append(JDA.nl);
8080
}
8181

8282
for (Iterator<MethodNode> it = cn.methods.iterator(); it.hasNext(); ) {
83-
MethodNodeDecompiler.decompile(sb, it.next(), cn);
83+
getMethodNodeDecompiler(sb, cn, it).decompile();
8484
if (it.hasNext())
8585
sb.append(JDA.nl);
8686
}
@@ -118,6 +118,14 @@ protected static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, Array
118118
return sb;
119119
}
120120

121+
protected FieldNodeDecompiler getFieldNodeDecompiler(PrefixedStringBuilder sb, Iterator<FieldNode> it) {
122+
return new FieldNodeDecompiler(sb, it.next());
123+
}
124+
125+
protected MethodNodeDecompiler getMethodNodeDecompiler(PrefixedStringBuilder sb, ClassNode cn, Iterator<MethodNode> it) {
126+
return new MethodNodeDecompiler(sb, it.next(), cn);
127+
}
128+
121129
public static String getAccessString(int access) {
122130
List<String> tokens = new ArrayList<>();
123131
if ((access & Opcodes.ACC_PUBLIC) != 0)

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,15 @@
1313
*/
1414

1515
public class FieldNodeDecompiler {
16+
protected final PrefixedStringBuilder sb;
17+
protected final FieldNode f;
1618

17-
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, FieldNode f) {
19+
public FieldNodeDecompiler(PrefixedStringBuilder sb, FieldNode f) {
20+
this.sb = sb;
21+
this.f = f;
22+
}
23+
24+
public PrefixedStringBuilder decompile() {
1825
String s = getAccessString(f.access);
1926
sb.append(s);
2027
if (s.length() > 0)

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

Lines changed: 48 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,18 @@
1616
*/
1717

1818
public class MethodNodeDecompiler {
19+
protected final PrefixedStringBuilder sb;
20+
protected final MethodNode mn;
21+
protected final ClassNode cn;
22+
23+
public MethodNodeDecompiler(PrefixedStringBuilder sb, MethodNode mn, ClassNode cn) {
24+
this.sb = sb;
25+
this.mn = mn;
26+
this.cn = cn;
27+
}
1928

2029
@SuppressWarnings("unused")
21-
public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNode m, ClassNode cn) {
30+
public PrefixedStringBuilder decompile() {
2231
String package_ = null;
2332
String class_ = null;
2433
if (cn.name.contains("/")) {
@@ -31,41 +40,41 @@ public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNo
3140
// Descriptor
3241
if (createDescriptors()) {
3342
sb.append(" // ");
34-
sb.append(m.owner.name);
43+
sb.append(mn.owner.name);
3544
sb.append(".");
36-
sb.append(m.name);
37-
sb.append(m.desc);
45+
sb.append(mn.name);
46+
sb.append(mn.desc);
3847
sb.append(JDA.nl);
3948
}
4049

4150
// Access
42-
String access = getAccessString(m.access);
51+
String access = getAccessString(mn.access);
4352
sb.append(" ");
4453
sb.append(access);
45-
if (access.length() > 0 && !m.name.equals("<clinit>"))
54+
if (access.length() > 0 && !mn.name.equals("<clinit>"))
4655
sb.append(" ");
4756

4857
// Return type
49-
if (m.name.charAt(0) != '<' && !m.name.endsWith("init>")) {
50-
Type returnType = Type.getReturnType(m.desc);
58+
if (mn.name.charAt(0) != '<' && !mn.name.endsWith("init>")) {
59+
Type returnType = Type.getReturnType(mn.desc);
5160
sb.append(returnType.getClassName());
5261
sb.append(" ");
5362
}
5463

5564
// Method name
56-
if (m.name.equals("<init>")) {
65+
if (mn.name.equals("<init>")) {
5766
sb.append(class_);
58-
} else if (m.name.equals("<clinit>")) {
67+
} else if (mn.name.equals("<clinit>")) {
5968
} else {
60-
sb.append(m.name);
69+
sb.append(mn.name);
6170
}
6271

6372
// Arguments
6473
TypeAndName[] args = new TypeAndName[0];
65-
if (!m.name.equals("<clinit>")) {
74+
if (!mn.name.equals("<clinit>")) {
6675
sb.append("(");
6776

68-
final Type[] argTypes = Type.getArgumentTypes(m.desc);
77+
final Type[] argTypes = Type.getArgumentTypes(mn.desc);
6978
args = new TypeAndName[argTypes.length];
7079

7180
for (int i = 0; i < argTypes.length; i++) {
@@ -86,13 +95,13 @@ public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNo
8695
}
8796

8897
// Throws
89-
int amountOfThrows = m.exceptions.size();
98+
int amountOfThrows = mn.exceptions.size();
9099
if (amountOfThrows > 0) {
91100
sb.append(" throws ");
92-
sb.append(m.exceptions.get(0));// exceptions is list<string>
101+
sb.append(mn.exceptions.get(0));// exceptions is list<string>
93102
for (int i = 1; i < amountOfThrows; i++) {
94103
sb.append(", ");
95-
sb.append(m.exceptions.get(i));
104+
sb.append(mn.exceptions.get(i));
96105
}
97106
}
98107

@@ -103,38 +112,38 @@ public static PrefixedStringBuilder decompile(PrefixedStringBuilder sb, MethodNo
103112
sb.append(" {");
104113

105114
if (createComments() && !createDescriptors()) {
106-
if (m.name.equals("<clinit>"))
115+
if (mn.name.equals("<clinit>"))
107116
sb.append(" // <clinit>");
108-
else if (m.name.equals("<init>"))
117+
else if (mn.name.equals("<init>"))
109118
sb.append(" // <init>");
110119
}
111120
}
112121
sb.append(JDA.nl);
113122

114123
// Code
115124
if (!access.contains("abstract")) {
116-
if (m.signature != null) {
117-
sb.append(" <sig:").append(m.signature).append(">");
125+
if (mn.signature != null) {
126+
sb.append(" <sig:").append(mn.signature).append(">");
118127
}
119128

120-
if (m.annotationDefault != null) {
121-
sb.append(m.annotationDefault);
129+
if (mn.annotationDefault != null) {
130+
sb.append(mn.annotationDefault);
122131
sb.append("\n");
123132
}
124133

125-
InstructionPrinter insnPrinter = new InstructionPrinter(m, args);
134+
InstructionPrinter insnPrinter = getInstructionPrinter(mn, args);
126135

127-
addAttrList(m.attrs, "attr", sb, insnPrinter);
128-
addAttrList(m.invisibleAnnotations, "invisAnno", sb, insnPrinter);
129-
addAttrList(m.invisibleAnnotations, "invisLocalVarAnno", sb, insnPrinter);
130-
addAttrList(m.invisibleTypeAnnotations, "invisTypeAnno", sb, insnPrinter);
131-
addAttrList(m.localVariables, "localVar", sb, insnPrinter);
132-
addAttrList(m.visibleAnnotations, "visAnno", sb, insnPrinter);
133-
addAttrList(m.visibleLocalVariableAnnotations, "visLocalVarAnno", sb, insnPrinter);
134-
addAttrList(m.visibleTypeAnnotations, "visTypeAnno", sb, insnPrinter);
136+
addAttrList(mn.attrs, "attr", sb, insnPrinter);
137+
addAttrList(mn.invisibleAnnotations, "invisAnno", sb, insnPrinter);
138+
addAttrList(mn.invisibleAnnotations, "invisLocalVarAnno", sb, insnPrinter);
139+
addAttrList(mn.invisibleTypeAnnotations, "invisTypeAnno", sb, insnPrinter);
140+
addAttrList(mn.localVariables, "localVar", sb, insnPrinter);
141+
addAttrList(mn.visibleAnnotations, "visAnno", sb, insnPrinter);
142+
addAttrList(mn.visibleLocalVariableAnnotations, "visLocalVarAnno", sb, insnPrinter);
143+
addAttrList(mn.visibleTypeAnnotations, "visTypeAnno", sb, insnPrinter);
135144

136145
// Exception table
137-
for (Object o : m.tryCatchBlocks) {
146+
for (Object o : mn.tryCatchBlocks) {
138147
TryCatchBlockNode tcbn = (TryCatchBlockNode) o;
139148
sb.append(" ");
140149
sb.append("TryCatch: L");
@@ -165,7 +174,11 @@ else if (m.name.equals("<init>"))
165174
return sb;
166175
}
167176

168-
private static void addAttrList(List<?> list, String name, PrefixedStringBuilder sb, InstructionPrinter insnPrinter) {
177+
protected InstructionPrinter getInstructionPrinter(MethodNode m, TypeAndName[] args) {
178+
return new InstructionPrinter(m, args);
179+
}
180+
181+
protected static void addAttrList(List<?> list, String name, PrefixedStringBuilder sb, InstructionPrinter insnPrinter) {
169182
if (list == null)
170183
return;
171184
if (list.size() > 0) {
@@ -181,7 +194,7 @@ private static void addAttrList(List<?> list, String name, PrefixedStringBuilder
181194
}
182195
}
183196

184-
private static String printAttr(Object o, InstructionPrinter insnPrinter) {
197+
protected static String printAttr(Object o, InstructionPrinter insnPrinter) {
185198
if (o instanceof LocalVariableNode) {
186199
LocalVariableNode lvn = (LocalVariableNode) o;
187200
return "index=" + lvn.index + " , name=" + lvn.name + " , desc=" + lvn.desc + ", sig=" + lvn.signature + ", start=L" + insnPrinter.resolveLabel(lvn.start) + ", end=L" + insnPrinter.resolveLabel(lvn.end);
@@ -203,7 +216,7 @@ private static String printAttr(Object o, InstructionPrinter insnPrinter) {
203216
return o.toString();
204217
}
205218

206-
private static String getAccessString(int access) {
219+
protected static String getAccessString(int access) {
207220
// public, protected, private, abstract, static,
208221
// final, synchronized, native & strictfp are permitted
209222
List<String> tokens = new ArrayList<>();

0 commit comments

Comments
 (0)