summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/analysis/SourceIndex.java
diff options
context:
space:
mode:
authorGravatar Thog2017-03-08 08:17:04 +0100
committerGravatar Thog2017-03-08 08:17:04 +0100
commit6e464ea251cab63c776ece0b2a356f1498ffa294 (patch)
tree5ed30c03f5ac4cd2d6877874f5ede576049954f7 /src/main/java/cuchaz/enigma/analysis/SourceIndex.java
parentDrop unix case style and implement hashCode when equals is overrided (diff)
downloadenigma-fork-6e464ea251cab63c776ece0b2a356f1498ffa294.tar.gz
enigma-fork-6e464ea251cab63c776ece0b2a356f1498ffa294.tar.xz
enigma-fork-6e464ea251cab63c776ece0b2a356f1498ffa294.zip
Follow Fabric guidelines
Diffstat (limited to 'src/main/java/cuchaz/enigma/analysis/SourceIndex.java')
-rw-r--r--src/main/java/cuchaz/enigma/analysis/SourceIndex.java305
1 files changed, 152 insertions, 153 deletions
diff --git a/src/main/java/cuchaz/enigma/analysis/SourceIndex.java b/src/main/java/cuchaz/enigma/analysis/SourceIndex.java
index 719930e..19250c8 100644
--- a/src/main/java/cuchaz/enigma/analysis/SourceIndex.java
+++ b/src/main/java/cuchaz/enigma/analysis/SourceIndex.java
@@ -8,174 +8,173 @@
8 * Contributors: 8 * Contributors:
9 * Jeff Martin - initial API and implementation 9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/ 10 ******************************************************************************/
11
11package cuchaz.enigma.analysis; 12package cuchaz.enigma.analysis;
12 13
13import com.google.common.collect.HashMultimap; 14import com.google.common.collect.HashMultimap;
14import com.google.common.collect.Lists; 15import com.google.common.collect.Lists;
15import com.google.common.collect.Maps; 16import com.google.common.collect.Maps;
16import com.google.common.collect.Multimap; 17import com.google.common.collect.Multimap;
17
18import com.strobel.decompiler.languages.Region; 18import com.strobel.decompiler.languages.Region;
19import com.strobel.decompiler.languages.java.ast.AstNode; 19import com.strobel.decompiler.languages.java.ast.AstNode;
20import com.strobel.decompiler.languages.java.ast.Identifier; 20import com.strobel.decompiler.languages.java.ast.Identifier;
21import cuchaz.enigma.mapping.Entry;
21 22
22import java.util.Collection; 23import java.util.Collection;
23import java.util.List; 24import java.util.List;
24import java.util.Map; 25import java.util.Map;
25import java.util.TreeMap; 26import java.util.TreeMap;
26 27
27import cuchaz.enigma.mapping.Entry;
28
29public class SourceIndex { 28public class SourceIndex {
30 29
31 private String source; 30 private String source;
32 private TreeMap<Token, EntryReference<Entry, Entry>> tokenToReference; 31 private TreeMap<Token, EntryReference<Entry, Entry>> tokenToReference;
33 private Multimap<EntryReference<Entry, Entry>, Token> referenceToTokens; 32 private Multimap<EntryReference<Entry, Entry>, Token> referenceToTokens;
34 private Map<Entry, Token> declarationToToken; 33 private Map<Entry, Token> declarationToToken;
35 private List<Integer> lineOffsets; 34 private List<Integer> lineOffsets;
36 private boolean ignoreBadTokens; 35 private boolean ignoreBadTokens;
37 36
38 public SourceIndex(String source) { 37 public SourceIndex(String source) {
39 this(source, true); 38 this(source, true);
40 } 39 }
41 40
42 public SourceIndex(String source, boolean ignoreBadTokens) { 41 public SourceIndex(String source, boolean ignoreBadTokens) {
43 this.source = source; 42 this.source = source;
44 this.ignoreBadTokens = ignoreBadTokens; 43 this.ignoreBadTokens = ignoreBadTokens;
45 this.tokenToReference = Maps.newTreeMap(); 44 this.tokenToReference = Maps.newTreeMap();
46 this.referenceToTokens = HashMultimap.create(); 45 this.referenceToTokens = HashMultimap.create();
47 this.declarationToToken = Maps.newHashMap(); 46 this.declarationToToken = Maps.newHashMap();
48 this.lineOffsets = Lists.newArrayList(); 47 this.lineOffsets = Lists.newArrayList();
49 48
50 // count the lines 49 // count the lines
51 this.lineOffsets.add(0); 50 this.lineOffsets.add(0);
52 for (int i = 0; i < source.length(); i++) { 51 for (int i = 0; i < source.length(); i++) {
53 if (source.charAt(i) == '\n') { 52 if (source.charAt(i) == '\n') {
54 this.lineOffsets.add(i + 1); 53 this.lineOffsets.add(i + 1);
55 } 54 }
56 } 55 }
57 } 56 }
58 57
59 public String getSource() { 58 public String getSource() {
60 return this.source; 59 return this.source;
61 } 60 }
62 61
63 public Token getToken(AstNode node) { 62 public Token getToken(AstNode node) {
64 63
65 // get the text of the node 64 // get the text of the node
66 String name = ""; 65 String name = "";
67 if (node instanceof Identifier) { 66 if (node instanceof Identifier) {
68 name = ((Identifier) node).getName(); 67 name = ((Identifier) node).getName();
69 } 68 }
70 69
71 // get a token for this node's region 70 // get a token for this node's region
72 Region region = node.getRegion(); 71 Region region = node.getRegion();
73 if (region.getBeginLine() == 0 || region.getEndLine() == 0) { 72 if (region.getBeginLine() == 0 || region.getEndLine() == 0) {
74 // DEBUG 73 // DEBUG
75 System.err.println(String.format("WARNING: %s \"%s\" has invalid region: %s", node.getNodeType(), name, region)); 74 System.err.println(String.format("WARNING: %s \"%s\" has invalid region: %s", node.getNodeType(), name, region));
76 return null; 75 return null;
77 } 76 }
78 Token token = new Token(toPos(region.getBeginLine(), region.getBeginColumn()), toPos(region.getEndLine(), region.getEndColumn()), this.source); 77 Token token = new Token(toPos(region.getBeginLine(), region.getBeginColumn()), toPos(region.getEndLine(), region.getEndColumn()), this.source);
79 if (token.start == 0) { 78 if (token.start == 0) {
80 // DEBUG 79 // DEBUG
81 System.err.println(String.format("WARNING: %s \"%s\" has invalid start: %s", node.getNodeType(), name, region)); 80 System.err.println(String.format("WARNING: %s \"%s\" has invalid start: %s", node.getNodeType(), name, region));
82 return null; 81 return null;
83 } 82 }
84 83
85 // DEBUG 84 // DEBUG
86 // System.out.println( String.format( "%s \"%s\" region: %s", node.getNodeType(), name, region ) ); 85 // System.out.println( String.format( "%s \"%s\" region: %s", node.getNodeType(), name, region ) );
87 86
88 // if the token has a $ in it, something's wrong. Ignore this token 87 // if the token has a $ in it, something's wrong. Ignore this token
89 if (name.lastIndexOf('$') >= 0 && this.ignoreBadTokens) { 88 if (name.lastIndexOf('$') >= 0 && this.ignoreBadTokens) {
90 // DEBUG 89 // DEBUG
91 System.err.println(String.format("WARNING: %s \"%s\" is probably a bad token. It was ignored", node.getNodeType(), name)); 90 System.err.println(String.format("WARNING: %s \"%s\" is probably a bad token. It was ignored", node.getNodeType(), name));
92 return null; 91 return null;
93 } 92 }
94 93
95 return token; 94 return token;
96 } 95 }
97 96
98 public void addReference(AstNode node, Entry deobfEntry, Entry deobfContext) { 97 public void addReference(AstNode node, Entry deobfEntry, Entry deobfContext) {
99 Token token = getToken(node); 98 Token token = getToken(node);
100 if (token != null) { 99 if (token != null) {
101 EntryReference<Entry, Entry> deobfReference = new EntryReference<>(deobfEntry, token.text, deobfContext); 100 EntryReference<Entry, Entry> deobfReference = new EntryReference<>(deobfEntry, token.text, deobfContext);
102 this.tokenToReference.put(token, deobfReference); 101 this.tokenToReference.put(token, deobfReference);
103 this.referenceToTokens.put(deobfReference, token); 102 this.referenceToTokens.put(deobfReference, token);
104 } 103 }
105 } 104 }
106 105
107 public void addDeclaration(AstNode node, Entry deobfEntry) { 106 public void addDeclaration(AstNode node, Entry deobfEntry) {
108 Token token = getToken(node); 107 Token token = getToken(node);
109 if (token != null) { 108 if (token != null) {
110 EntryReference<Entry, Entry> reference = new EntryReference<>(deobfEntry, token.text); 109 EntryReference<Entry, Entry> reference = new EntryReference<>(deobfEntry, token.text);
111 this.tokenToReference.put(token, reference); 110 this.tokenToReference.put(token, reference);
112 this.referenceToTokens.put(reference, token); 111 this.referenceToTokens.put(reference, token);
113 this.declarationToToken.put(deobfEntry, token); 112 this.declarationToToken.put(deobfEntry, token);
114 } 113 }
115 } 114 }
116 115
117 public Token getReferenceToken(int pos) { 116 public Token getReferenceToken(int pos) {
118 Token token = this.tokenToReference.floorKey(new Token(pos, pos, null)); 117 Token token = this.tokenToReference.floorKey(new Token(pos, pos, null));
119 if (token != null && token.contains(pos)) { 118 if (token != null && token.contains(pos)) {
120 return token; 119 return token;
121 } 120 }
122 return null; 121 return null;
123 } 122 }
124 123
125 public Collection<Token> getReferenceTokens(EntryReference<Entry, Entry> deobfReference) { 124 public Collection<Token> getReferenceTokens(EntryReference<Entry, Entry> deobfReference) {
126 return this.referenceToTokens.get(deobfReference); 125 return this.referenceToTokens.get(deobfReference);
127 } 126 }
128 127
129 public EntryReference<Entry, Entry> getDeobfReference(Token token) { 128 public EntryReference<Entry, Entry> getDeobfReference(Token token) {
130 if (token == null) { 129 if (token == null) {
131 return null; 130 return null;
132 } 131 }
133 return this.tokenToReference.get(token); 132 return this.tokenToReference.get(token);
134 } 133 }
135 134
136 public void replaceDeobfReference(Token token, EntryReference<Entry, Entry> newDeobfReference) { 135 public void replaceDeobfReference(Token token, EntryReference<Entry, Entry> newDeobfReference) {
137 EntryReference<Entry, Entry> oldDeobfReference = this.tokenToReference.get(token); 136 EntryReference<Entry, Entry> oldDeobfReference = this.tokenToReference.get(token);
138 this.tokenToReference.put(token, newDeobfReference); 137 this.tokenToReference.put(token, newDeobfReference);
139 Collection<Token> tokens = this.referenceToTokens.get(oldDeobfReference); 138 Collection<Token> tokens = this.referenceToTokens.get(oldDeobfReference);
140 this.referenceToTokens.removeAll(oldDeobfReference); 139 this.referenceToTokens.removeAll(oldDeobfReference);
141 this.referenceToTokens.putAll(newDeobfReference, tokens); 140 this.referenceToTokens.putAll(newDeobfReference, tokens);
142 } 141 }
143 142
144 public Iterable<Token> referenceTokens() { 143 public Iterable<Token> referenceTokens() {
145 return this.tokenToReference.keySet(); 144 return this.tokenToReference.keySet();
146 } 145 }
147 146
148 public Iterable<Token> declarationTokens() { 147 public Iterable<Token> declarationTokens() {
149 return this.declarationToToken.values(); 148 return this.declarationToToken.values();
150 } 149 }
151 150
152 public Iterable<Entry> declarations() { 151 public Iterable<Entry> declarations() {
153 return this.declarationToToken.keySet(); 152 return this.declarationToToken.keySet();
154 } 153 }
155 154
156 public Token getDeclarationToken(Entry deobfEntry) { 155 public Token getDeclarationToken(Entry deobfEntry) {
157 return this.declarationToToken.get(deobfEntry); 156 return this.declarationToToken.get(deobfEntry);
158 } 157 }
159 158
160 public int getLineNumber(int pos) { 159 public int getLineNumber(int pos) {
161 // line number is 1-based 160 // line number is 1-based
162 int line = 0; 161 int line = 0;
163 for (Integer offset : this.lineOffsets) { 162 for (Integer offset : this.lineOffsets) {
164 if (offset > pos) { 163 if (offset > pos) {
165 break; 164 break;
166 } 165 }
167 line++; 166 line++;
168 } 167 }
169 return line; 168 return line;
170 } 169 }
171 170
172 public int getColumnNumber(int pos) { 171 public int getColumnNumber(int pos) {
173 // column number is 1-based 172 // column number is 1-based
174 return pos - this.lineOffsets.get(getLineNumber(pos) - 1) + 1; 173 return pos - this.lineOffsets.get(getLineNumber(pos) - 1) + 1;
175 } 174 }
176 175
177 private int toPos(int line, int col) { 176 private int toPos(int line, int col) {
178 // line and col are 1-based 177 // line and col are 1-based
179 return this.lineOffsets.get(line - 1) + col - 1; 178 return this.lineOffsets.get(line - 1) + col - 1;
180 } 179 }
181} 180}