summaryrefslogtreecommitdiff
path: root/src/cuchaz/enigma/analysis/SourceIndex.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/cuchaz/enigma/analysis/SourceIndex.java')
-rw-r--r--src/cuchaz/enigma/analysis/SourceIndex.java144
1 files changed, 59 insertions, 85 deletions
diff --git a/src/cuchaz/enigma/analysis/SourceIndex.java b/src/cuchaz/enigma/analysis/SourceIndex.java
index 0e33de0..b43ab61 100644
--- a/src/cuchaz/enigma/analysis/SourceIndex.java
+++ b/src/cuchaz/enigma/analysis/SourceIndex.java
@@ -25,16 +25,15 @@ import com.strobel.decompiler.languages.java.ast.Identifier;
25 25
26import cuchaz.enigma.mapping.Entry; 26import cuchaz.enigma.mapping.Entry;
27 27
28public class SourceIndex 28public class SourceIndex {
29{ 29
30 private String m_source; 30 private String m_source;
31 private TreeMap<Token,EntryReference<Entry,Entry>> m_tokenToReference; 31 private TreeMap<Token,EntryReference<Entry,Entry>> m_tokenToReference;
32 private Multimap<EntryReference<Entry,Entry>,Token> m_referenceToTokens; 32 private Multimap<EntryReference<Entry,Entry>,Token> m_referenceToTokens;
33 private Map<Entry,Token> m_declarationToToken; 33 private Map<Entry,Token> m_declarationToToken;
34 private List<Integer> m_lineOffsets; 34 private List<Integer> m_lineOffsets;
35 35
36 public SourceIndex( String source ) 36 public SourceIndex(String source) {
37 {
38 m_source = source; 37 m_source = source;
39 m_tokenToReference = Maps.newTreeMap(); 38 m_tokenToReference = Maps.newTreeMap();
40 m_referenceToTokens = HashMultimap.create(); 39 m_referenceToTokens = HashMultimap.create();
@@ -42,142 +41,119 @@ public class SourceIndex
42 m_lineOffsets = Lists.newArrayList(); 41 m_lineOffsets = Lists.newArrayList();
43 42
44 // count the lines 43 // count the lines
45 m_lineOffsets.add( 0 ); 44 m_lineOffsets.add(0);
46 for( int i=0; i<source.length(); i++ ) 45 for (int i = 0; i < source.length(); i++) {
47 { 46 if (source.charAt(i) == '\n') {
48 if( source.charAt( i ) == '\n' ) 47 m_lineOffsets.add(i + 1);
49 {
50 m_lineOffsets.add( i + 1 );
51 } 48 }
52 } 49 }
53 } 50 }
54 51
55 public String getSource( ) 52 public String getSource() {
56 {
57 return m_source; 53 return m_source;
58 } 54 }
59 55
60 public Token getToken( AstNode node ) 56 public Token getToken(AstNode node) {
61 { 57
62 // get the text of the node 58 // get the text of the node
63 String name = ""; 59 String name = "";
64 if( node instanceof Identifier ) 60 if (node instanceof Identifier) {
65 {
66 name = ((Identifier)node).getName(); 61 name = ((Identifier)node).getName();
67 } 62 }
68 63
69 // get a token for this node's region 64 // get a token for this node's region
70 Region region = node.getRegion(); 65 Region region = node.getRegion();
71 if( region.getBeginLine() == 0 || region.getEndLine() == 0 ) 66 if (region.getBeginLine() == 0 || region.getEndLine() == 0) {
72 {
73 // DEBUG 67 // DEBUG
74 System.err.println( String.format( "WARNING: %s \"%s\" has invalid region: %s", node.getNodeType(), name, region ) ); 68 System.err.println(String.format("WARNING: %s \"%s\" has invalid region: %s", node.getNodeType(), name, region));
75 return null; 69 return null;
76 } 70 }
77 Token token = new Token( 71 Token token = new Token(
78 toPos( region.getBeginLine(), region.getBeginColumn() ), 72 toPos(region.getBeginLine(), region.getBeginColumn()),
79 toPos( region.getEndLine(), region.getEndColumn() ), 73 toPos(region.getEndLine(), region.getEndColumn()),
80 m_source 74 m_source
81 ); 75 );
82 if( token.start == 0 ) 76 if (token.start == 0) {
83 {
84 // DEBUG 77 // DEBUG
85 System.err.println( String.format( "WARNING: %s \"%s\" has invalid start: %s", node.getNodeType(), name, region ) ); 78 System.err.println(String.format("WARNING: %s \"%s\" has invalid start: %s", node.getNodeType(), name, region));
86 return null; 79 return null;
87 } 80 }
88 81
89 // DEBUG 82 // DEBUG
90 //System.out.println( String.format( "%s \"%s\" region: %s", node.getNodeType(), name, region ) ); 83 // System.out.println( String.format( "%s \"%s\" region: %s", node.getNodeType(), name, region ) );
91 84
92 // for tokens representing inner classes, make sure we only get the simple name 85 // for tokens representing inner classes, make sure we only get the simple name
93 int pos = name.lastIndexOf( '$' ); 86 int pos = name.lastIndexOf('$');
94 if( pos >= 0 ) 87 if (pos >= 0) {
95 {
96 token.end -= pos + 1; 88 token.end -= pos + 1;
97 } 89 }
98 90
99 return token; 91 return token;
100 } 92 }
101 93
102 public void addReference( AstNode node, Entry deobfEntry, Entry deobfContext ) 94 public void addReference(AstNode node, Entry deobfEntry, Entry deobfContext) {
103 { 95 Token token = getToken(node);
104 Token token = getToken( node ); 96 if (token != null) {
105 if( token != null ) 97 EntryReference<Entry,Entry> deobfReference = new EntryReference<Entry,Entry>(deobfEntry, token.text, deobfContext);
106 { 98 m_tokenToReference.put(token, deobfReference);
107 EntryReference<Entry,Entry> deobfReference = new EntryReference<Entry,Entry>( deobfEntry, token.text, deobfContext ); 99 m_referenceToTokens.put(deobfReference, token);
108 m_tokenToReference.put( token, deobfReference );
109 m_referenceToTokens.put( deobfReference, token );
110 } 100 }
111 } 101 }
112 102
113 public void addDeclaration( AstNode node, Entry deobfEntry ) 103 public void addDeclaration(AstNode node, Entry deobfEntry) {
114 { 104 Token token = getToken(node);
115 Token token = getToken( node ); 105 if (token != null) {
116 if( token != null ) 106 EntryReference<Entry,Entry> reference = new EntryReference<Entry,Entry>(deobfEntry, token.text);
117 { 107 m_tokenToReference.put(token, reference);
118 EntryReference<Entry,Entry> reference = new EntryReference<Entry,Entry>( deobfEntry, token.text ); 108 m_referenceToTokens.put(reference, token);
119 m_tokenToReference.put( token, reference ); 109 m_declarationToToken.put(deobfEntry, token);
120 m_referenceToTokens.put( reference, token );
121 m_declarationToToken.put( deobfEntry, token );
122 } 110 }
123 } 111 }
124 112
125 public Token getReferenceToken( int pos ) 113 public Token getReferenceToken(int pos) {
126 { 114 Token token = m_tokenToReference.floorKey(new Token(pos, pos, null));
127 Token token = m_tokenToReference.floorKey( new Token( pos, pos, null ) ); 115 if (token != null && token.contains(pos)) {
128 if( token != null && token.contains( pos ) )
129 {
130 return token; 116 return token;
131 } 117 }
132 return null; 118 return null;
133 } 119 }
134 120
135 public Collection<Token> getReferenceTokens( EntryReference<Entry,Entry> deobfReference ) 121 public Collection<Token> getReferenceTokens(EntryReference<Entry,Entry> deobfReference) {
136 { 122 return m_referenceToTokens.get(deobfReference);
137 return m_referenceToTokens.get( deobfReference );
138 } 123 }
139 124
140 public EntryReference<Entry,Entry> getDeobfReference( Token token ) 125 public EntryReference<Entry,Entry> getDeobfReference(Token token) {
141 { 126 if (token == null) {
142 if( token == null )
143 {
144 return null; 127 return null;
145 } 128 }
146 return m_tokenToReference.get( token ); 129 return m_tokenToReference.get(token);
147 } 130 }
148 131
149 public void replaceDeobfReference( Token token, EntryReference<Entry,Entry> newDeobfReference ) 132 public void replaceDeobfReference(Token token, EntryReference<Entry,Entry> newDeobfReference) {
150 { 133 EntryReference<Entry,Entry> oldDeobfReference = m_tokenToReference.get(token);
151 EntryReference<Entry,Entry> oldDeobfReference = m_tokenToReference.get( token ); 134 m_tokenToReference.put(token, newDeobfReference);
152 m_tokenToReference.put( token, newDeobfReference ); 135 Collection<Token> tokens = m_referenceToTokens.get(oldDeobfReference);
153 Collection<Token> tokens = m_referenceToTokens.get( oldDeobfReference ); 136 m_referenceToTokens.removeAll(oldDeobfReference);
154 m_referenceToTokens.removeAll( oldDeobfReference ); 137 m_referenceToTokens.putAll(newDeobfReference, tokens);
155 m_referenceToTokens.putAll( newDeobfReference, tokens );
156 } 138 }
157 139
158 public Iterable<Token> referenceTokens( ) 140 public Iterable<Token> referenceTokens() {
159 {
160 return m_tokenToReference.keySet(); 141 return m_tokenToReference.keySet();
161 } 142 }
162 143
163 public Iterable<Token> declarationTokens( ) 144 public Iterable<Token> declarationTokens() {
164 {
165 return m_declarationToToken.values(); 145 return m_declarationToToken.values();
166 } 146 }
167 147
168 public Token getDeclarationToken( Entry deobfEntry ) 148 public Token getDeclarationToken(Entry deobfEntry) {
169 { 149 return m_declarationToToken.get(deobfEntry);
170 return m_declarationToToken.get( deobfEntry );
171 } 150 }
172 151
173 public int getLineNumber( int pos ) 152 public int getLineNumber(int pos) {
174 {
175 // line number is 1-based 153 // line number is 1-based
176 int line = 0; 154 int line = 0;
177 for( Integer offset : m_lineOffsets ) 155 for (Integer offset : m_lineOffsets) {
178 { 156 if (offset > pos) {
179 if( offset > pos )
180 {
181 break; 157 break;
182 } 158 }
183 line++; 159 line++;
@@ -185,15 +161,13 @@ public class SourceIndex
185 return line; 161 return line;
186 } 162 }
187 163
188 public int getColumnNumber( int pos ) 164 public int getColumnNumber(int pos) {
189 {
190 // column number is 1-based 165 // column number is 1-based
191 return pos - m_lineOffsets.get( getLineNumber( pos ) - 1 ) + 1; 166 return pos - m_lineOffsets.get(getLineNumber(pos) - 1) + 1;
192 } 167 }
193 168
194 private int toPos( int line, int col ) 169 private int toPos(int line, int col) {
195 {
196 // line and col are 1-based 170 // line and col are 1-based
197 return m_lineOffsets.get( line - 1 ) + col - 1; 171 return m_lineOffsets.get(line - 1) + col - 1;
198 } 172 }
199} 173}