24
24
import java .util .Objects ;
25
25
import java .util .Optional ;
26
26
27
+ /**
28
+ * Helper methods for working with ASM.
29
+ */
27
30
public class ASMAPI {
28
31
public static MethodNode getMethodNode () {
29
32
return new MethodNode (Opcodes .ASM6 );
30
33
}
31
34
35
+ // Terribly named method. Should be called "prependMethodCall" or something similar.
36
+ /**
37
+ * Injects a method call to the beginning of the given method.
38
+ *
39
+ * @param node The method to inject the call into
40
+ * @param methodCall The method call to inject
41
+ */
32
42
public static void appendMethodCall (MethodNode node , MethodInsnNode methodCall ) {
33
43
node .instructions .insertBefore (node .instructions .getFirst (), methodCall );
34
44
}
35
45
46
+ /**
47
+ * Signifies the method invocation type. Mirrors "INVOKE-" opcodes from ASM.
48
+ */
36
49
public enum MethodType {
37
50
VIRTUAL , SPECIAL , STATIC , INTERFACE , DYNAMIC ;
38
51
@@ -41,18 +54,47 @@ public int toOpcode() {
41
54
}
42
55
}
43
56
57
+ /**
58
+ * Builds a new {@link MethodInsnNode} with the given parameters. The opcode of the method call is determined by the
59
+ * given {@link MethodType}.
60
+ *
61
+ * @param ownerName The method owner (class)
62
+ * @param methodName The method name
63
+ * @param methodDescriptor The method descriptor
64
+ * @param type The type of method call
65
+ * @return The built method call node
66
+ */
44
67
public static MethodInsnNode buildMethodCall (final String ownerName , final String methodName , final String methodDescriptor , final MethodType type ) {
45
68
return new MethodInsnNode (type .toOpcode (), ownerName , methodName , methodDescriptor , type ==MethodType .INTERFACE );
46
69
}
47
70
71
+ /**
72
+ * Maps a method from the given SRG name to the mapped name at deobfuscated runtime.
73
+ *
74
+ * @param name The SRG name of the method
75
+ * @return The mapped name of the method
76
+ *
77
+ * @deprecated Forge no longer uses SRG names in production
78
+ */
79
+ @ Deprecated (forRemoval = true , since = "5.1" )
48
80
public static String mapMethod (String name ) {
49
81
return map (name , INameMappingService .Domain .METHOD );
50
82
}
51
83
84
+ /**
85
+ * Maps a field from the given SRG name to the mapped name at deobfuscated runtime.
86
+ *
87
+ * @param name The SRG name of the field
88
+ * @return The mapped name of the field
89
+ *
90
+ * @deprecated Forge no longer uses SRG names in production
91
+ */
92
+ @ Deprecated (forRemoval = true , since = "5.1" )
52
93
public static String mapField (String name ) {
53
94
return map (name , INameMappingService .Domain .FIELD );
54
95
}
55
96
97
+ @ Deprecated (forRemoval = true , since = "5.1" )
56
98
private static String map (String name , INameMappingService .Domain domain ) {
57
99
return Optional .ofNullable (Launcher .INSTANCE ).
58
100
map (Launcher ::environment ).
@@ -70,12 +112,15 @@ public static boolean getSystemPropertyFlag(final String propertyName) {
70
112
return Boolean .getBoolean (propertyName ) || Boolean .getBoolean ("coremod." + propertyName );
71
113
}
72
114
115
+ /**
116
+ * The mode in which the given code should be inserted.
117
+ */
73
118
public enum InsertMode {
74
119
REMOVE_ORIGINAL , INSERT_BEFORE , INSERT_AFTER
75
120
}
76
121
77
122
/**
78
- * Finds the first instruction with matching opcode
123
+ * Finds the first instruction with matching opcode.
79
124
*
80
125
* @param method the method to search in
81
126
* @param opCode the opcode to search for
@@ -86,10 +131,10 @@ public static AbstractInsnNode findFirstInstruction(MethodNode method, int opCod
86
131
}
87
132
88
133
/**
89
- * Finds the first instruction with matching opcode after the given start index
134
+ * Finds the first instruction with matching opcode after the given start index.
90
135
*
91
- * @param method the method to search in
92
- * @param opCode the opcode to search for
136
+ * @param method the method to search in
137
+ * @param opCode the opcode to search for
93
138
* @param startIndex the index to start search after (inclusive)
94
139
* @return the found instruction node or null if none matched after the given index
95
140
*/
@@ -104,10 +149,10 @@ public static AbstractInsnNode findFirstInstructionAfter(MethodNode method, int
104
149
}
105
150
106
151
/**
107
- * Finds the first instruction with matching opcode before the given index in reverse search
152
+ * Finds the first instruction with matching opcode before the given index in reverse search.
108
153
*
109
- * @param method the method to search in
110
- * @param opCode the opcode to search for
154
+ * @param method the method to search in
155
+ * @param opCode the opcode to search for
111
156
* @param startIndex the index at which to start searching (inclusive)
112
157
* @return the found instruction node or null if none matched before the given startIndex
113
158
*/
@@ -122,12 +167,12 @@ public static AbstractInsnNode findFirstInstructionBefore(MethodNode method, int
122
167
}
123
168
124
169
/**
125
- * Finds the first method call in the given method matching the given type, owner, name and descriptor
170
+ * Finds the first method call in the given method matching the given type, owner, name and descriptor.
126
171
*
127
- * @param method the method to search in
128
- * @param type the type of method call to search for
129
- * @param owner the method call's owner to search for
130
- * @param name the method call's name
172
+ * @param method the method to search in
173
+ * @param type the type of method call to search for
174
+ * @param owner the method call's owner to search for
175
+ * @param name the method call's name
131
176
* @param descriptor the method call's descriptor
132
177
* @return the found method call node or null if none matched
133
178
*/
@@ -136,13 +181,13 @@ public static MethodInsnNode findFirstMethodCall(MethodNode method, MethodType t
136
181
}
137
182
138
183
/**
139
- * Finds the first method call in the given method matching the given type, owner, name and descriptor
140
- * after the instruction given index
184
+ * Finds the first method call in the given method matching the given type, owner, name and descriptor after the
185
+ * instruction given index.
141
186
*
142
- * @param method the method to search in
143
- * @param type the type of method call to search for
144
- * @param owner the method call's owner to search for
145
- * @param name the method call's name
187
+ * @param method the method to search in
188
+ * @param type the type of method call to search for
189
+ * @param owner the method call's owner to search for
190
+ * @param name the method call's name
146
191
* @param descriptor the method call's descriptor
147
192
* @param startIndex the index after which to start searching (inclusive)
148
193
* @return the found method call node, null if none matched after the given index
@@ -164,13 +209,13 @@ public static MethodInsnNode findFirstMethodCallAfter(MethodNode method, MethodT
164
209
}
165
210
166
211
/**
167
- * Finds the first method call in the given method matching the given type, owner, name and descriptor
168
- * before the given index in reverse search
212
+ * Finds the first method call in the given method matching the given type, owner, name and descriptor before the
213
+ * given index in reverse search.
169
214
*
170
- * @param method the method to search in
171
- * @param type the type of method call to search for
172
- * @param owner the method call's owner to search for
173
- * @param name the method call's name
215
+ * @param method the method to search in
216
+ * @param type the type of method call to search for
217
+ * @param owner the method call's owner to search for
218
+ * @param name the method call's name
174
219
* @param descriptor the method call's descriptor
175
220
* @param startIndex the index at which to start searching (inclusive)
176
221
* @return the found method call node or null if none matched before the given startIndex
@@ -192,15 +237,17 @@ public static MethodInsnNode findFirstMethodCallBefore(MethodNode method, Method
192
237
}
193
238
194
239
/**
195
- * Inserts/replaces a list after/before first {@link MethodInsnNode} that matches the parameters of these functions in the method provided.
196
- * Only the first node matching is targeted, all other matches are ignored.
240
+ * Inserts/replaces a list after/before first {@link MethodInsnNode} that matches the parameters of these functions
241
+ * in the method provided. Only the first node matching is targeted, all other matches are ignored.
242
+ *
197
243
* @param method The method where you want to find the node
198
- * @param type The type of the old method node.
199
- * @param owner The owner of the old method node.
200
- * @param name The name of the old method node. You may want to use {@link #mapMethod(String)} if this is a srg name
201
- * @param desc The desc of the old method node.
202
- * @param list The list that should be inserted
203
- * @param mode How the given code should be inserted
244
+ * @param type The type of the old method node.
245
+ * @param owner The owner of the old method node.
246
+ * @param name The name of the old method node. You may want to use {@link #mapMethod(String)} if this is a srg
247
+ * name
248
+ * @param desc The desc of the old method node.
249
+ * @param list The list that should be inserted
250
+ * @param mode How the given code should be inserted
204
251
* @return True if the node was found, false otherwise
205
252
*/
206
253
public static boolean insertInsnList (MethodNode method , MethodType type , String owner , String name , String desc , InsnList list , InsertMode mode ) {
@@ -226,7 +273,8 @@ public static boolean insertInsnList(MethodNode method, MethodType type, String
226
273
}
227
274
228
275
/**
229
- * Builds a new {@link InsnList} out of the specified AbstractInsnNodes
276
+ * Builds a new {@link InsnList} out of the specified {@link AbstractInsnNode}s.
277
+ *
230
278
* @param nodes The nodes you want to add
231
279
* @return A new list with the nodes
232
280
*/
@@ -239,16 +287,15 @@ public static InsnList listOf(AbstractInsnNode... nodes) {
239
287
240
288
/**
241
289
* Rewrites accesses to a specific field in the given class to a method-call.
290
+ * <p>
291
+ * The field specified by fieldName must be private and non-static. The method-call the field-access is redirected
292
+ * to does not take any parameters and returns an object of the same type as the field. If no methodName is passed,
293
+ * any method matching the described signature will be used as callable method.
242
294
*
243
- * The field specified by fieldName must be private and non-static.
244
- * The method-call the field-access is redirected to does not take any parameters and returns an object of the
245
- * same type as the field.
246
- * If no methodName is passed, any method matching the described signature will be used as callable method.
247
- *
248
- * @param classNode the class to rewrite the accesses in
249
- * @param fieldName the field accesses should be redirected to
250
- * @param methodName the name of the method to redirect accesses through,
251
- * or null if any method with matching signature should be applicable
295
+ * @param classNode the class to rewrite the accesses in
296
+ * @param fieldName the field accesses should be redirected to
297
+ * @param methodName the name of the method to redirect accesses through, or null if any method with matching
298
+ * signature should be applicable
252
299
*/
253
300
public static void redirectFieldToMethod (final ClassNode classNode , final String fieldName , @ Nullable final String methodName ) {
254
301
MethodNode foundMethod = null ;
@@ -308,31 +355,75 @@ public static void redirectFieldToMethod(final ClassNode classNode, final String
308
355
}
309
356
}
310
357
358
+ /**
359
+ * Loads a JavaScript file by file name. Useful for reusing code across multiple files.
360
+ *
361
+ * @param file The file name to load.
362
+ * @return true if file load was successful.
363
+ *
364
+ * @throws ScriptException If the script engine encounters an error, usually due to a syntax error in the script.
365
+ * @throws IOException If an I/O error occurs while reading the file, usually due to a corrupt or missing file.
366
+ */
311
367
public static boolean loadFile (String file ) throws ScriptException , IOException {
312
368
return CoreModTracker .loadFileByName (file );
313
369
}
314
370
371
+ /**
372
+ * Loads JSON data from a file by file name.
373
+ *
374
+ * @param file The file name to load.
375
+ * @return The loaded JSON data if successful, or null if not.
376
+ *
377
+ * @throws ScriptException If the parsed JSON data is malformed.
378
+ * @throws IOException If an I/O error occurs while reading the file, usually due to a corrupt or missing file.
379
+ */
315
380
@ Nullable
316
381
public static Object loadData (String file ) throws ScriptException , IOException {
317
382
return CoreModTracker .loadDataByName (file );
318
383
}
319
384
385
+ /**
386
+ * Logs the given message at the given level. The message can contain formatting arguments. Uses a
387
+ * {@link org.apache.logging.log4j.Logger}.
388
+ *
389
+ * @param level Log level
390
+ * @param message Message
391
+ * @param args Formatting arguments
392
+ */
320
393
public static void log (String level , String message , Object ... args ) {
321
394
CoreModTracker .log (level , message , args );
322
395
}
323
396
397
+ /**
398
+ * Converts a {@link ClassNode} to a string representation. Useful for evaluating changes after transformation.
399
+ *
400
+ * @param node The class node to convert.
401
+ * @return The string representation of the class node.
402
+ */
324
403
public static String classNodeToString (ClassNode node ) {
325
404
Textifier text = new Textifier ();
326
405
node .accept (new TraceClassVisitor (null , text , null ));
327
406
return toString (text );
328
407
}
329
408
409
+ /**
410
+ * Converts a {@link FieldNode} to a string representation. Useful for evaluating changes after transformation.
411
+ *
412
+ * @param node The field node to convert.
413
+ * @return The string representation of the field node.
414
+ */
330
415
public static String fieldNodeToString (FieldNode node ) {
331
416
Textifier text = new Textifier ();
332
417
node .accept (new TraceClassVisitor (null , text , null ));
333
418
return toString (text );
334
419
}
335
420
421
+ /**
422
+ * Converts a {@link MethodNode} to a string representation. Useful for evaluating changes after transformation.
423
+ *
424
+ * @param node The method node to convert.
425
+ * @return The string representation of the method node.
426
+ */
336
427
public static String methodNodeToString (MethodNode node ) {
337
428
Textifier text = new Textifier ();
338
429
node .accept (new TraceMethodVisitor (text ));
0 commit comments