diff options
Diffstat (limited to 'src/cuchaz/enigma/analysis/SourceIndex.java')
| -rw-r--r-- | src/cuchaz/enigma/analysis/SourceIndex.java | 144 |
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 | ||
| 26 | import cuchaz.enigma.mapping.Entry; | 26 | import cuchaz.enigma.mapping.Entry; |
| 27 | 27 | ||
| 28 | public class SourceIndex | 28 | public 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 | } |