summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/mapping/MappingsTinyReader.java
diff options
context:
space:
mode:
authorGravatar Gegy2019-01-24 14:48:32 +0200
committerGravatar Adrian Siekierka2019-01-24 13:48:32 +0100
commit00fcd0550fcdda621c2e4662f6ddd55ce673b931 (patch)
tree6f9e4c24dbcc6d118fceec56adf7bf9d747a485c /src/main/java/cuchaz/enigma/mapping/MappingsTinyReader.java
parentmark as 0.13.0-SNAPSHOT for preliminary development (diff)
downloadenigma-fork-00fcd0550fcdda621c2e4662f6ddd55ce673b931.tar.gz
enigma-fork-00fcd0550fcdda621c2e4662f6ddd55ce673b931.tar.xz
enigma-fork-00fcd0550fcdda621c2e4662f6ddd55ce673b931.zip
[WIP] Mapping rework (#91)
* Move packages * Mapping & entry refactor: first pass * Fix deobf -> obf tree remapping * Resolve various issues * Give all entries the potential for parents and treat inner classes as children * Deobf UI tree elements * Tests pass * Sort mapping output * Fix delta tracking * Index separation and first pass for #97 * Keep track of remapped jar index * Fix child entries not being remapped * Drop non-root entries * Track dropped mappings * Fix enigma mapping ordering * EntryTreeNode interface * Small tweaks * Naive full index remap on rename * Entries can resolve to more than one root entry * Support alternative resolution strategies * Bridge method resolution * Tests pass * Fix mappings being used where there are none * Fix methods with different descriptors being considered unique. closes #89
Diffstat (limited to 'src/main/java/cuchaz/enigma/mapping/MappingsTinyReader.java')
-rw-r--r--src/main/java/cuchaz/enigma/mapping/MappingsTinyReader.java130
1 files changed, 0 insertions, 130 deletions
diff --git a/src/main/java/cuchaz/enigma/mapping/MappingsTinyReader.java b/src/main/java/cuchaz/enigma/mapping/MappingsTinyReader.java
deleted file mode 100644
index 756ac43..0000000
--- a/src/main/java/cuchaz/enigma/mapping/MappingsTinyReader.java
+++ /dev/null
@@ -1,130 +0,0 @@
1package cuchaz.enigma.mapping;
2
3import com.google.common.base.Charsets;
4import com.google.common.collect.Maps;
5import cuchaz.enigma.mapping.entry.ClassEntry;
6import cuchaz.enigma.throwables.MappingConflict;
7import cuchaz.enigma.throwables.MappingParseException;
8
9import java.io.File;
10import java.io.IOException;
11import java.nio.file.Files;
12import java.util.ArrayList;
13import java.util.List;
14import java.util.Map;
15
16public class MappingsTinyReader {
17 public ClassMapping readClass(String[] parts) {
18 // Extract the inner naming of the deob form if it have one
19 String deobName = parts[2].contains("$") ? parts[2].substring(parts[2].lastIndexOf('$') + 1) : parts[2];
20 return new ClassMapping(parts[1], deobName).setDeobfInner(parts[2]);
21 }
22
23 public FieldMapping readField(String[] parts) {
24 return new FieldMapping(parts[3], new TypeDescriptor(parts[2]), parts[4], Mappings.EntryModifier.UNCHANGED);
25 }
26
27 public MethodMapping readMethod(String[] parts) {
28 return new MethodMapping(parts[3], new MethodDescriptor(parts[2]), parts[4]);
29 }
30
31 public Mappings read(File file) throws IOException, MappingParseException {
32 Mappings mappings = new Mappings(Mappings.FormatType.TINY_FILE);
33 List<String> lines = Files.readAllLines(file.toPath(), Charsets.UTF_8);
34 Map<String, ClassMapping> classMappingMap = Maps.newHashMap();
35 lines.remove(0); // TODO: use the header
36 for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) {
37 String line = lines.get(lineNumber);
38 String[] parts = line.split("\t");
39 try {
40 String token = parts[0];
41 ClassMapping classMapping;
42 switch (token) {
43 case "CLASS":
44
45 // Check for orphan created by field or method entries. It shouldn't be possible but I prefer to handle this case
46 if (classMappingMap.containsKey(parts[1])) {
47 classMapping = classMappingMap.get(parts[1]);
48
49 // We have the full deob name, Enigma only support simple class name so we extract it.
50 String deobName = parts[2].contains("$") ?
51 parts[2].substring(parts[2].lastIndexOf('$') + 1) :
52 parts[2];
53
54 // Add full deob name to the class mapping to handle inner class after this loop
55 classMappingMap.put(parts[2], classMapping.setDeobfInner(parts[2]));
56 classMapping.setDeobfName(deobName);
57
58 // Avoid to make the mapping dirty directly at the startup
59 classMapping.resetDirty();
60 } else
61 classMapping = readClass(parts);
62 classMappingMap.put(parts[1], classMapping);
63 break;
64 case "FIELD":
65 // We can have missing classes mappings because they don't have a ob name, so we create it and use it
66 classMapping = classMappingMap.computeIfAbsent(parts[1], k -> new ClassMapping(parts[1]));
67 classMapping.addFieldMapping(readField(parts));
68 break;
69 case "METHOD":
70 // We can have missing classes mappings because they don't have a ob name, so we create it and use it
71 classMapping = classMappingMap.computeIfAbsent(parts[1], k -> new ClassMapping(parts[1]));
72 classMapping.addMethodMapping(readMethod(parts));
73 break;
74 case "MTH-ARG":
75 classMapping = classMappingMap.computeIfAbsent(parts[1], k -> new ClassMapping(parts[1]));
76 classMapping.setArgumentName(parts[3], new MethodDescriptor(parts[2]), Integer.parseInt(parts[4]), parts[5]);
77 break;
78 default:
79 throw new MappingParseException(file, lineNumber, "Unknown token '" + token + "' !");
80 }
81 } catch (ArrayIndexOutOfBoundsException | IllegalArgumentException ex) {
82 ex.printStackTrace();
83 throw new MappingParseException(file, lineNumber, "Malformed line:\n" + line);
84 }
85 }
86
87 List<ClassMapping> toRegister = new ArrayList<>(classMappingMap.values());
88
89 // After having completely parsed the file, we need to register it to the real mapping
90 for (ClassMapping classMapping : toRegister) {
91 ClassEntry obEntry = classMapping.getObfEntry();
92 ClassEntry deobEntry = classMapping.getDeObfEntry();
93 try {
94 if (obEntry.isInnerClass()) {
95 ClassMapping parent = classMappingMap.get(obEntry.getOuterClassName());
96 // Inner class can miss their parent... So we create it and add it to the mappings
97 if (parent == null) {
98 parent = new ClassMapping(obEntry.getOuterClassName()); // FIXME: WE ACTUALLY DON'T MANAGE INNER CLASS OF INNER CLASS
99 classMappingMap.put(obEntry.getOuterClassName(), parent);
100 mappings.addClassMapping(parent);
101 }
102 // Add the inner class to the parent
103 parent.addInnerClassMapping(classMapping);
104 }
105 // obf class can become deobf inner classs, manage this case.
106 else if (deobEntry != null && deobEntry.isInnerClass()) {
107 String outerClassName = deobEntry.getOuterClassName();
108 ClassMapping parent = classMappingMap.get(outerClassName);
109
110 // Only the inner is deob??? Okay
111 if (parent == null) {
112 parent = classMappingMap.get(outerClassName);
113 if (parent == null) {
114 parent = new ClassMapping(outerClassName); // FIXME: WE ACTUALLY DON'T MANAGE INNER CLASS OF INNER CLASS
115 classMappingMap.put(outerClassName, parent);
116 mappings.addClassMapping(parent);
117 }
118 }
119 parent.addInnerClassMapping(classMapping);
120 } else
121 mappings.addClassMapping(classMapping);
122 } catch (MappingConflict e) {
123 throw new MappingParseException(file, -1, e.getMessage());
124 }
125 }
126 lines.clear();
127 classMappingMap.clear();
128 return mappings;
129 }
130}