summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
diff options
context:
space:
mode:
authorGravatar gegy10002018-07-17 19:14:08 +0200
committerGravatar GitHub2018-07-17 19:14:08 +0200
commita88175ffc95792b88a8724f66db6dda2b8cc32ee (patch)
tree65895bbc6cf1766f4ca01e1257619ab1993e71dc /src/main/java/cuchaz/enigma/mapping/ClassMapping.java
parentMerge pull request #3 from thiakil/src-jar (diff)
downloadenigma-fork-a88175ffc95792b88a8724f66db6dda2b8cc32ee.tar.gz
enigma-fork-a88175ffc95792b88a8724f66db6dda2b8cc32ee.tar.xz
enigma-fork-a88175ffc95792b88a8724f66db6dda2b8cc32ee.zip
ASM Based Class Translator (#1)
* Initial port to ASM * Package updates * Annotation + inner class translation * Fix inner class mapping * More bytecode translation * Signature refactoring * Fix highlighting of mapped names * Fix parameter name offset * Fix anonymous class generation * Fix issues with inner class signature transformation * Fix bridged method detection * Fix compile issues * Resolve all failed tests * Apply deobfuscated name to transformed classes * Fix class signatures not being translated * Fix frame array type translation * Fix frame array type translation * Fix array translation in method calls * Fix method reference and bridge detection * Fix handling of null deobf mappings * Parameter translation in interfaces * Fix enum parameter index offset * Fix parsed local variable indexing * Fix stackoverflow on rebuilding method names * Ignore invalid decompiled variable indices * basic source jar * Output directly to file on source export * Make decompile parallel * fix incorrect super calls * Use previous save state to delete old mapping files * Fix old mappings not properly being removed * Fix old mappings not properly being removed * make isMethodProvider public (cherry picked from commit ebad6a9) * speed up Deobfuscator's getSources by using a single TranslatingTypeloader and caching the ClassLoaderTypeloader * ignore .idea project folders * move SynchronizedTypeLoader to a non-inner * fix signature remap of inners for now * index & resolve method/field references for usages view * Allow reader/writer subclasses to provide the underlying file operations * fix giving obf classes a name not removing them from the panel * buffer the ParsedJar class entry inputstream, allow use with a jarinputstream * make CachingClasspathTypeLoader public * make CachingClasspathTypeLoader public * support enum switches with obfuscated SwitchMaps
Diffstat (limited to 'src/main/java/cuchaz/enigma/mapping/ClassMapping.java')
-rw-r--r--src/main/java/cuchaz/enigma/mapping/ClassMapping.java210
1 files changed, 131 insertions, 79 deletions
diff --git a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
index 51751ca..8f3f2b2 100644
--- a/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
+++ b/src/main/java/cuchaz/enigma/mapping/ClassMapping.java
@@ -12,6 +12,9 @@
12package cuchaz.enigma.mapping; 12package cuchaz.enigma.mapping;
13 13
14import com.google.common.collect.Maps; 14import com.google.common.collect.Maps;
15import cuchaz.enigma.mapping.entry.ClassEntry;
16import cuchaz.enigma.mapping.entry.FieldEntry;
17import cuchaz.enigma.mapping.entry.MethodEntry;
15import cuchaz.enigma.throwables.MappingConflict; 18import cuchaz.enigma.throwables.MappingConflict;
16 19
17import java.util.ArrayList; 20import java.util.ArrayList;
@@ -34,7 +37,6 @@ public class ClassMapping implements Comparable<ClassMapping> {
34 private Map<String, MethodMapping> methodsByDeobf; 37 private Map<String, MethodMapping> methodsByDeobf;
35 private boolean isDirty; 38 private boolean isDirty;
36 private Mappings.EntryModifier modifier; 39 private Mappings.EntryModifier modifier;
37 private boolean deobfInner;
38 40
39 public ClassMapping(String obfFullName) { 41 public ClassMapping(String obfFullName) {
40 this(obfFullName, null, Mappings.EntryModifier.UNCHANGED); 42 this(obfFullName, null, Mappings.EntryModifier.UNCHANGED);
@@ -81,6 +83,10 @@ public class ClassMapping implements Comparable<ClassMapping> {
81 return deobfName; 83 return deobfName;
82 } 84 }
83 85
86 public String getTranslatedName(TranslationDirection direction) {
87 return direction.choose(deobfName, obfFullName);
88 }
89
84 //// INNER CLASSES //////// 90 //// INNER CLASSES ////////
85 91
86 public void setDeobfName(String val) { 92 public void setDeobfName(String val) {
@@ -191,21 +197,21 @@ public class ClassMapping implements Comparable<ClassMapping> {
191 return fieldsByObf.values(); 197 return fieldsByObf.values();
192 } 198 }
193 199
194 public boolean containsObfField(String obfName, Type obfType) { 200 public boolean containsObfField(String obfName, TypeDescriptor obfDesc) {
195 return fieldsByObf.containsKey(getFieldKey(obfName, obfType)); 201 return fieldsByObf.containsKey(getFieldKey(obfName, obfDesc));
196 } 202 }
197 203
198 public boolean containsDeobfField(String deobfName, Type deobfType) { 204 public boolean containsDeobfField(String deobfName, TypeDescriptor deobfDesc) {
199 return fieldsByDeobf.containsKey(getFieldKey(deobfName, deobfType)); 205 return fieldsByDeobf.containsKey(getFieldKey(deobfName, deobfDesc));
200 } 206 }
201 207
202 public void addFieldMapping(FieldMapping fieldMapping) { 208 public void addFieldMapping(FieldMapping fieldMapping) {
203 String obfKey = getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType()); 209 String obfKey = getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfDesc());
204 if (fieldsByObf.containsKey(obfKey)) { 210 if (fieldsByObf.containsKey(obfKey)) {
205 throw new Error("Already have mapping for " + obfFullName + "." + obfKey); 211 throw new Error("Already have mapping for " + obfFullName + "." + obfKey);
206 } 212 }
207 if (fieldMapping.getDeobfName() != null) { 213 if (fieldMapping.getDeobfName() != null) {
208 String deobfKey = getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfType()); 214 String deobfKey = getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfDesc());
209 if (fieldsByDeobf.containsKey(deobfKey)) { 215 if (fieldsByDeobf.containsKey(deobfKey)) {
210 throw new Error("Already have mapping for " + deobfName + "." + deobfKey); 216 throw new Error("Already have mapping for " + deobfName + "." + deobfKey);
211 } 217 }
@@ -218,63 +224,67 @@ public class ClassMapping implements Comparable<ClassMapping> {
218 } 224 }
219 225
220 public void removeFieldMapping(FieldMapping fieldMapping) { 226 public void removeFieldMapping(FieldMapping fieldMapping) {
221 boolean obfWasRemoved = fieldsByObf.remove(getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType())) != null; 227 boolean obfWasRemoved = fieldsByObf.remove(getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfDesc())) != null;
222 assert (obfWasRemoved); 228 assert (obfWasRemoved);
223 if (fieldMapping.getDeobfName() != null) { 229 if (fieldMapping.getDeobfName() != null) {
224 boolean deobfWasRemoved = fieldsByDeobf.remove(getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfType())) != null; 230 boolean deobfWasRemoved = fieldsByDeobf.remove(getFieldKey(fieldMapping.getDeobfName(), fieldMapping.getObfDesc())) != null;
225 assert (deobfWasRemoved); 231 assert (deobfWasRemoved);
226 } 232 }
227 this.isDirty = true; 233 this.isDirty = true;
228 } 234 }
229 235
230 public FieldMapping getFieldByObf(String obfName, Type obfType) { 236 public FieldMapping getFieldByObf(String obfName, TypeDescriptor obfDesc) {
231 return fieldsByObf.get(getFieldKey(obfName, obfType)); 237 return fieldsByObf.get(getFieldKey(obfName, obfDesc));
238 }
239
240 public FieldMapping getFieldByObf(FieldEntry field) {
241 return getFieldByObf(field.getName(), field.getDesc());
232 } 242 }
233 243
234 public FieldMapping getFieldByDeobf(String deobfName, Type obfType) { 244 public FieldMapping getFieldByDeobf(String deobfName, TypeDescriptor obfDesc) {
235 return fieldsByDeobf.get(getFieldKey(deobfName, obfType)); 245 return fieldsByDeobf.get(getFieldKey(deobfName, obfDesc));
236 } 246 }
237 247
238 public String getObfFieldName(String deobfName, Type obfType) { 248 public String getObfFieldName(String deobfName, TypeDescriptor obfDesc) {
239 FieldMapping fieldMapping = fieldsByDeobf.get(getFieldKey(deobfName, obfType)); 249 FieldMapping fieldMapping = fieldsByDeobf.get(getFieldKey(deobfName, obfDesc));
240 if (fieldMapping != null) { 250 if (fieldMapping != null) {
241 return fieldMapping.getObfName(); 251 return fieldMapping.getObfName();
242 } 252 }
243 return null; 253 return null;
244 } 254 }
245 255
246 public String getDeobfFieldName(String obfName, Type obfType) { 256 public String getDeobfFieldName(String obfName, TypeDescriptor obfDesc) {
247 FieldMapping fieldMapping = fieldsByObf.get(getFieldKey(obfName, obfType)); 257 FieldMapping fieldMapping = fieldsByObf.get(getFieldKey(obfName, obfDesc));
248 if (fieldMapping != null) { 258 if (fieldMapping != null) {
249 return fieldMapping.getDeobfName(); 259 return fieldMapping.getDeobfName();
250 } 260 }
251 return null; 261 return null;
252 } 262 }
253 263
254 private String getFieldKey(String name, Type type) { 264 private String getFieldKey(String name, TypeDescriptor desc) {
255 if (name == null) { 265 if (name == null) {
256 throw new IllegalArgumentException("name cannot be null!"); 266 throw new IllegalArgumentException("name cannot be null!");
257 } 267 }
258 if (type == null) { 268 if (desc == null) {
259 throw new IllegalArgumentException("type cannot be null!"); 269 throw new IllegalArgumentException("desc cannot be null!");
260 } 270 }
261 return name + ":" + type; 271 return name + ":" + desc;
262 } 272 }
263 273
264 public void setFieldName(String obfName, Type obfType, String deobfName) { 274 public void setFieldName(String obfName, TypeDescriptor obfDesc, String deobfName) {
265 assert (deobfName != null); 275 assert (deobfName != null);
266 FieldMapping fieldMapping = fieldsByObf.get(getFieldKey(obfName, obfType)); 276 FieldMapping fieldMapping = fieldsByObf.get(getFieldKey(obfName, obfDesc));
267 if (fieldMapping == null) { 277 if (fieldMapping == null) {
268 fieldMapping = new FieldMapping(obfName, obfType, deobfName, Mappings.EntryModifier.UNCHANGED); 278 fieldMapping = new FieldMapping(obfName, obfDesc, deobfName, Mappings.EntryModifier.UNCHANGED);
269 boolean obfWasAdded = fieldsByObf.put(getFieldKey(obfName, obfType), fieldMapping) == null; 279 boolean obfWasAdded = fieldsByObf.put(getFieldKey(obfName, obfDesc), fieldMapping) == null;
270 assert (obfWasAdded); 280 assert (obfWasAdded);
271 } else { 281 } else {
272 boolean wasRemoved = fieldsByDeobf.remove(getFieldKey(fieldMapping.getDeobfName(), obfType)) != null; 282 boolean wasRemoved = fieldsByDeobf.remove(getFieldKey(fieldMapping.getDeobfName(), obfDesc)) != null;
273 assert (wasRemoved); 283 assert (wasRemoved);
274 } 284 }
275 fieldMapping.setDeobfName(deobfName); 285 fieldMapping.setDeobfName(deobfName);
276 if (deobfName != null) { 286 if (deobfName != null) {
277 boolean wasAdded = fieldsByDeobf.put(getFieldKey(deobfName, obfType), fieldMapping) == null; 287 boolean wasAdded = fieldsByDeobf.put(getFieldKey(deobfName, obfDesc), fieldMapping) == null;
278 assert (wasAdded); 288 assert (wasAdded);
279 } 289 }
280 this.isDirty = true; 290 this.isDirty = true;
@@ -282,13 +292,13 @@ public class ClassMapping implements Comparable<ClassMapping> {
282 292
283 //// METHODS //////// 293 //// METHODS ////////
284 294
285 public void setFieldObfNameAndType(String oldObfName, Type obfType, String newObfName, Type newObfType) { 295 public void setFieldObfNameAndType(String oldObfName, TypeDescriptor obfDesc, String newObfName, TypeDescriptor newObfDesc) {
286 assert (newObfName != null); 296 assert (newObfName != null);
287 FieldMapping fieldMapping = fieldsByObf.remove(getFieldKey(oldObfName, obfType)); 297 FieldMapping fieldMapping = fieldsByObf.remove(getFieldKey(oldObfName, obfDesc));
288 assert (fieldMapping != null); 298 assert (fieldMapping != null);
289 fieldMapping.setObfName(newObfName); 299 fieldMapping.setObfName(newObfName);
290 fieldMapping.setObfType(newObfType); 300 fieldMapping.setObfDesc(newObfDesc);
291 boolean obfWasAdded = fieldsByObf.put(getFieldKey(newObfName, newObfType), fieldMapping) == null; 301 boolean obfWasAdded = fieldsByObf.put(getFieldKey(newObfName, newObfDesc), fieldMapping) == null;
292 assert (obfWasAdded); 302 assert (obfWasAdded);
293 this.isDirty = true; 303 this.isDirty = true;
294 } 304 }
@@ -298,23 +308,23 @@ public class ClassMapping implements Comparable<ClassMapping> {
298 return methodsByObf.values(); 308 return methodsByObf.values();
299 } 309 }
300 310
301 public boolean containsObfMethod(String obfName, Signature obfSignature) { 311 public boolean containsObfMethod(String obfName, MethodDescriptor obfDescriptor) {
302 return methodsByObf.containsKey(getMethodKey(obfName, obfSignature)); 312 return methodsByObf.containsKey(getMethodKey(obfName, obfDescriptor));
303 } 313 }
304 314
305 public boolean containsDeobfMethod(String deobfName, Signature obfSignature) { 315 public boolean containsDeobfMethod(String deobfName, MethodDescriptor obfDescriptor) {
306 return methodsByDeobf.containsKey(getMethodKey(deobfName, obfSignature)); 316 return methodsByDeobf.containsKey(getMethodKey(deobfName, obfDescriptor));
307 } 317 }
308 318
309 public void addMethodMapping(MethodMapping methodMapping) { 319 public void addMethodMapping(MethodMapping methodMapping) {
310 String obfKey = getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature()); 320 String obfKey = getMethodKey(methodMapping.getObfName(), methodMapping.getObfDesc());
311 if (methodsByObf.containsKey(obfKey)) { 321 if (methodsByObf.containsKey(obfKey)) {
312 throw new Error("Already have mapping for " + obfFullName + "." + obfKey); 322 throw new Error("Already have mapping for " + obfFullName + "." + obfKey);
313 } 323 }
314 boolean wasAdded = methodsByObf.put(obfKey, methodMapping) == null; 324 boolean wasAdded = methodsByObf.put(obfKey, methodMapping) == null;
315 assert (wasAdded); 325 assert (wasAdded);
316 if (methodMapping.getDeobfName() != null) { 326 if (!methodMapping.isObfuscated()) {
317 String deobfKey = getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature()); 327 String deobfKey = getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfDesc());
318 if (methodsByDeobf.containsKey(deobfKey)) { 328 if (methodsByDeobf.containsKey(deobfKey)) {
319 throw new Error("Already have mapping for " + deobfName + "." + deobfKey); 329 throw new Error("Already have mapping for " + deobfName + "." + deobfKey);
320 } 330 }
@@ -326,44 +336,48 @@ public class ClassMapping implements Comparable<ClassMapping> {
326 } 336 }
327 337
328 public void removeMethodMapping(MethodMapping methodMapping) { 338 public void removeMethodMapping(MethodMapping methodMapping) {
329 boolean obfWasRemoved = methodsByObf.remove(getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature())) != null; 339 boolean obfWasRemoved = methodsByObf.remove(getMethodKey(methodMapping.getObfName(), methodMapping.getObfDesc())) != null;
330 assert (obfWasRemoved); 340 assert (obfWasRemoved);
331 if (methodMapping.getDeobfName() != null) { 341 if (!methodMapping.isObfuscated()) {
332 boolean deobfWasRemoved = methodsByDeobf.remove(getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature())) != null; 342 boolean deobfWasRemoved = methodsByDeobf.remove(getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfDesc())) != null;
333 assert (deobfWasRemoved); 343 assert (deobfWasRemoved);
334 } 344 }
335 this.isDirty = true; 345 this.isDirty = true;
336 } 346 }
337 347
338 public MethodMapping getMethodByObf(String obfName, Signature obfSignature) { 348 public MethodMapping getMethodByObf(String obfName, MethodDescriptor obfDescriptor) {
339 return methodsByObf.get(getMethodKey(obfName, obfSignature)); 349 return methodsByObf.get(getMethodKey(obfName, obfDescriptor));
350 }
351
352 public MethodMapping getMethodByObf(MethodEntry method) {
353 return getMethodByObf(method.getName(), method.getDesc());
340 } 354 }
341 355
342 public MethodMapping getMethodByDeobf(String deobfName, Signature obfSignature) { 356 public MethodMapping getMethodByDeobf(String deobfName, MethodDescriptor obfDescriptor) {
343 return methodsByDeobf.get(getMethodKey(deobfName, obfSignature)); 357 return methodsByDeobf.get(getMethodKey(deobfName, obfDescriptor));
344 } 358 }
345 359
346 private String getMethodKey(String name, Signature signature) { 360 private String getMethodKey(String name, MethodDescriptor descriptor) {
347 if (name == null) { 361 if (name == null) {
348 throw new IllegalArgumentException("name cannot be null!"); 362 throw new IllegalArgumentException("name cannot be null!");
349 } 363 }
350 if (signature == null) { 364 if (descriptor == null) {
351 throw new IllegalArgumentException("signature cannot be null!"); 365 throw new IllegalArgumentException("descriptor cannot be null!");
352 } 366 }
353 return name + signature; 367 return name + descriptor;
354 } 368 }
355 369
356 public void setMethodName(String obfName, Signature obfSignature, String deobfName) { 370 public void setMethodName(String obfName, MethodDescriptor obfDescriptor, String deobfName) {
357 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfName, obfSignature)); 371 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfName, obfDescriptor));
358 if (methodMapping == null) { 372 if (methodMapping == null) {
359 methodMapping = createMethodMapping(obfName, obfSignature); 373 methodMapping = createMethodMapping(obfName, obfDescriptor);
360 } else if (methodMapping.getDeobfName() != null) { 374 } else if (!methodMapping.isObfuscated()) {
361 boolean wasRemoved = methodsByDeobf.remove(getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfSignature())) != null; 375 boolean wasRemoved = methodsByDeobf.remove(getMethodKey(methodMapping.getDeobfName(), methodMapping.getObfDesc())) != null;
362 assert (wasRemoved); 376 assert (wasRemoved);
363 } 377 }
364 methodMapping.setDeobfName(deobfName); 378 methodMapping.setDeobfName(deobfName);
365 if (deobfName != null) { 379 if (deobfName != null) {
366 boolean wasAdded = methodsByDeobf.put(getMethodKey(deobfName, obfSignature), methodMapping) == null; 380 boolean wasAdded = methodsByDeobf.put(getMethodKey(deobfName, obfDescriptor), methodMapping) == null;
367 assert (wasAdded); 381 assert (wasAdded);
368 } 382 }
369 this.isDirty = true; 383 this.isDirty = true;
@@ -371,35 +385,35 @@ public class ClassMapping implements Comparable<ClassMapping> {
371 385
372 //// ARGUMENTS //////// 386 //// ARGUMENTS ////////
373 387
374 public void setMethodObfNameAndSignature(String oldObfName, Signature obfSignature, String newObfName, Signature newObfSignature) { 388 public void setMethodObfNameAndSignature(String oldObfName, MethodDescriptor obfDescriptor, String newObfName, MethodDescriptor newObfDescriptor) {
375 assert (newObfName != null); 389 assert (newObfName != null);
376 MethodMapping methodMapping = methodsByObf.remove(getMethodKey(oldObfName, obfSignature)); 390 MethodMapping methodMapping = methodsByObf.remove(getMethodKey(oldObfName, obfDescriptor));
377 assert (methodMapping != null); 391 assert (methodMapping != null);
378 methodMapping.setObfName(newObfName); 392 methodMapping.setObfName(newObfName);
379 methodMapping.setObfSignature(newObfSignature); 393 methodMapping.setObfDescriptor(newObfDescriptor);
380 boolean obfWasAdded = methodsByObf.put(getMethodKey(newObfName, newObfSignature), methodMapping) == null; 394 boolean obfWasAdded = methodsByObf.put(getMethodKey(newObfName, newObfDescriptor), methodMapping) == null;
381 assert (obfWasAdded); 395 assert (obfWasAdded);
382 this.isDirty = true; 396 this.isDirty = true;
383 } 397 }
384 398
385 public void setArgumentName(String obfMethodName, Signature obfMethodSignature, int argumentIndex, String argumentName) { 399 public void setArgumentName(String obfMethodName, MethodDescriptor obfMethodDescriptor, int argumentIndex, String argumentName) {
386 assert (argumentName != null); 400 assert (argumentName != null);
387 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfMethodName, obfMethodSignature)); 401 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfMethodName, obfMethodDescriptor));
388 if (methodMapping == null) { 402 if (methodMapping == null) {
389 methodMapping = createMethodMapping(obfMethodName, obfMethodSignature); 403 methodMapping = createMethodMapping(obfMethodName, obfMethodDescriptor);
390 } 404 }
391 methodMapping.setArgumentName(argumentIndex, argumentName); 405 methodMapping.setLocalVariableName(argumentIndex, argumentName);
392 this.isDirty = true; 406 this.isDirty = true;
393 } 407 }
394 408
395 public void removeArgumentName(String obfMethodName, Signature obfMethodSignature, int argumentIndex) { 409 public void removeArgumentName(String obfMethodName, MethodDescriptor obfMethodDescriptor, int argumentIndex) {
396 methodsByObf.get(getMethodKey(obfMethodName, obfMethodSignature)).removeArgumentName(argumentIndex); 410 methodsByObf.get(getMethodKey(obfMethodName, obfMethodDescriptor)).removeLocalVariableName(argumentIndex);
397 this.isDirty = true; 411 this.isDirty = true;
398 } 412 }
399 413
400 private MethodMapping createMethodMapping(String obfName, Signature obfSignature) { 414 private MethodMapping createMethodMapping(String obfName, MethodDescriptor obfDescriptor) {
401 MethodMapping methodMapping = new MethodMapping(obfName, obfSignature); 415 MethodMapping methodMapping = new MethodMapping(obfName, obfDescriptor);
402 boolean wasAdded = methodsByObf.put(getMethodKey(obfName, obfSignature), methodMapping) == null; 416 boolean wasAdded = methodsByObf.put(getMethodKey(obfName, obfDescriptor), methodMapping) == null;
403 assert (wasAdded); 417 assert (wasAdded);
404 this.isDirty = true; 418 this.isDirty = true;
405 return methodMapping; 419 return methodMapping;
@@ -459,24 +473,24 @@ public class ClassMapping implements Comparable<ClassMapping> {
459 473
460 // rename field types 474 // rename field types
461 for (FieldMapping fieldMapping : new ArrayList<>(fieldsByObf.values())) { 475 for (FieldMapping fieldMapping : new ArrayList<>(fieldsByObf.values())) {
462 String oldFieldKey = getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType()); 476 String oldFieldKey = getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfDesc());
463 if (fieldMapping.renameObfClass(oldObfClassName, newObfClassName)) { 477 if (fieldMapping.renameObfClass(oldObfClassName, newObfClassName)) {
464 boolean wasRemoved = fieldsByObf.remove(oldFieldKey) != null; 478 boolean wasRemoved = fieldsByObf.remove(oldFieldKey) != null;
465 assert (wasRemoved); 479 assert (wasRemoved);
466 boolean wasAdded = fieldsByObf 480 boolean wasAdded = fieldsByObf
467 .put(getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfType()), fieldMapping) == null; 481 .put(getFieldKey(fieldMapping.getObfName(), fieldMapping.getObfDesc()), fieldMapping) == null;
468 assert (wasAdded); 482 assert (wasAdded);
469 } 483 }
470 } 484 }
471 485
472 // rename method signatures 486 // rename method signatures
473 for (MethodMapping methodMapping : new ArrayList<>(methodsByObf.values())) { 487 for (MethodMapping methodMapping : new ArrayList<>(methodsByObf.values())) {
474 String oldMethodKey = getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature()); 488 String oldMethodKey = getMethodKey(methodMapping.getObfName(), methodMapping.getObfDesc());
475 if (methodMapping.renameObfClass(oldObfClassName, newObfClassName)) { 489 if (methodMapping.renameObfClass(oldObfClassName, newObfClassName)) {
476 boolean wasRemoved = methodsByObf.remove(oldMethodKey) != null; 490 boolean wasRemoved = methodsByObf.remove(oldMethodKey) != null;
477 assert (wasRemoved); 491 assert (wasRemoved);
478 boolean wasAdded = methodsByObf 492 boolean wasAdded = methodsByObf
479 .put(getMethodKey(methodMapping.getObfName(), methodMapping.getObfSignature()), methodMapping) == null; 493 .put(getMethodKey(methodMapping.getObfName(), methodMapping.getObfDesc()), methodMapping) == null;
480 assert (wasAdded); 494 assert (wasAdded);
481 } 495 }
482 } 496 }
@@ -490,9 +504,9 @@ public class ClassMapping implements Comparable<ClassMapping> {
490 return false; 504 return false;
491 } 505 }
492 506
493 public boolean containsArgument(BehaviorEntry obfBehaviorEntry, String name) { 507 public boolean containsArgument(MethodEntry obfMethodEntry, String name) {
494 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfBehaviorEntry.getName(), obfBehaviorEntry.getSignature())); 508 MethodMapping methodMapping = methodsByObf.get(getMethodKey(obfMethodEntry.getName(), obfMethodEntry.getDesc()));
495 return methodMapping != null && methodMapping.containsArgument(name); 509 return methodMapping != null && methodMapping.containsLocalVariable(name);
496 } 510 }
497 511
498 public ClassEntry getObfEntry() { 512 public ClassEntry getObfEntry() {
@@ -503,6 +517,14 @@ public class ClassMapping implements Comparable<ClassMapping> {
503 return deobfFullName != null ? new ClassEntry(deobfFullName) : null; 517 return deobfFullName != null ? new ClassEntry(deobfFullName) : null;
504 } 518 }
505 519
520 public boolean isObfuscated() {
521 return this.deobfName == null || this.deobfName.equals(this.obfFullName);
522 }
523
524 public String getSaveName() {
525 return this.isObfuscated() ? this.obfFullName : this.deobfName;
526 }
527
506 public boolean isDirty() { 528 public boolean isDirty() {
507 return isDirty; 529 return isDirty;
508 } 530 }
@@ -511,6 +533,10 @@ public class ClassMapping implements Comparable<ClassMapping> {
511 this.isDirty = false; 533 this.isDirty = false;
512 } 534 }
513 535
536 public void markDirty() {
537 this.isDirty = true;
538 }
539
514 public Mappings.EntryModifier getModifier() { 540 public Mappings.EntryModifier getModifier() {
515 return modifier; 541 return modifier;
516 } 542 }
@@ -521,9 +547,9 @@ public class ClassMapping implements Comparable<ClassMapping> {
521 this.modifier = modifier; 547 this.modifier = modifier;
522 } 548 }
523 549
524 public void setFieldModifier(String obfName, Type obfType, Mappings.EntryModifier modifier) { 550 public void setFieldModifier(String obfName, TypeDescriptor obfDesc, Mappings.EntryModifier modifier) {
525 FieldMapping fieldMapping = fieldsByObf.computeIfAbsent(getFieldKey(obfName, obfType), 551 FieldMapping fieldMapping = fieldsByObf.computeIfAbsent(getFieldKey(obfName, obfDesc),
526 k -> new FieldMapping(obfName, obfType, null, Mappings.EntryModifier.UNCHANGED)); 552 k -> new FieldMapping(obfName, obfDesc, null, Mappings.EntryModifier.UNCHANGED));
527 553
528 if (fieldMapping.getModifier() != modifier) { 554 if (fieldMapping.getModifier() != modifier) {
529 fieldMapping.setModifier(modifier); 555 fieldMapping.setModifier(modifier);
@@ -531,7 +557,7 @@ public class ClassMapping implements Comparable<ClassMapping> {
531 } 557 }
532 } 558 }
533 559
534 public void setMethodModifier(String obfName, Signature sig, Mappings.EntryModifier modifier) { 560 public void setMethodModifier(String obfName, MethodDescriptor sig, Mappings.EntryModifier modifier) {
535 MethodMapping methodMapping = methodsByObf.computeIfAbsent(getMethodKey(obfName, sig), 561 MethodMapping methodMapping = methodsByObf.computeIfAbsent(getMethodKey(obfName, sig),
536 k -> new MethodMapping(obfName, sig, null, Mappings.EntryModifier.UNCHANGED)); 562 k -> new MethodMapping(obfName, sig, null, Mappings.EntryModifier.UNCHANGED));
537 563
@@ -546,4 +572,30 @@ public class ClassMapping implements Comparable<ClassMapping> {
546 this.deobfFullName = deobName; 572 this.deobfFullName = deobName;
547 return this; 573 return this;
548 } 574 }
575
576 public ClassMapping copy() {
577 ClassMapping copied = new ClassMapping(this.obfFullName);
578 copied.obfSimpleName= this.obfSimpleName;
579 copied.modifier = this.modifier;
580 copied.deobfFullName = this.deobfFullName;
581 copied.deobfName = this.deobfName;
582 copied.innerClassesByDeobf = this.innerClassesByDeobf;
583 copied.innerClassesByObfFull = this.innerClassesByObfFull;
584 copied.innerClassesByObfSimple = this.innerClassesByObfSimple;
585 copied.fieldsByObf = this.fieldsByObf;
586 copied.fieldsByDeobf = this.fieldsByDeobf;
587 copied.methodsByObf = this.methodsByObf;
588 copied.methodsByDeobf = this.methodsByDeobf;
589 return copied;
590 }
591
592 @Override
593 public int hashCode() {
594 return this.obfFullName.hashCode();
595 }
596
597 @Override
598 public boolean equals(Object obj) {
599 return obj instanceof ClassMapping && ((ClassMapping) obj).obfFullName.equals(this.obfFullName);
600 }
549} 601}