summaryrefslogtreecommitdiff
path: root/src/main/java/cuchaz/enigma/gui/CodeReader.java
diff options
context:
space:
mode:
authorGravatar lclc982016-07-04 18:14:22 +1000
committerGravatar lclc982016-07-04 18:14:22 +1000
commit59e189bef2b5e6d129fb7c2c988ed0b2130e36ac (patch)
tree2b638e60905251de85a4917152d6fc39a4112194 /src/main/java/cuchaz/enigma/gui/CodeReader.java
parentFixed Obf Class list order (diff)
downloadenigma-fork-59e189bef2b5e6d129fb7c2c988ed0b2130e36ac.tar.gz
enigma-fork-59e189bef2b5e6d129fb7c2c988ed0b2130e36ac.tar.xz
enigma-fork-59e189bef2b5e6d129fb7c2c988ed0b2130e36ac.zip
Reformat
Diffstat (limited to 'src/main/java/cuchaz/enigma/gui/CodeReader.java')
-rw-r--r--src/main/java/cuchaz/enigma/gui/CodeReader.java202
1 files changed, 0 insertions, 202 deletions
diff --git a/src/main/java/cuchaz/enigma/gui/CodeReader.java b/src/main/java/cuchaz/enigma/gui/CodeReader.java
deleted file mode 100644
index a476fa5..0000000
--- a/src/main/java/cuchaz/enigma/gui/CodeReader.java
+++ /dev/null
@@ -1,202 +0,0 @@
1/*******************************************************************************
2 * Copyright (c) 2015 Jeff Martin.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the GNU Lesser General Public
5 * License v3.0 which accompanies this distribution, and is available at
6 * http://www.gnu.org/licenses/lgpl.html
7 * <p>
8 * Contributors:
9 * Jeff Martin - initial API and implementation
10 ******************************************************************************/
11package cuchaz.enigma.gui;
12
13import com.strobel.decompiler.languages.java.ast.CompilationUnit;
14
15import java.awt.Rectangle;
16import java.awt.event.ActionEvent;
17import java.awt.event.ActionListener;
18
19import javax.swing.JEditorPane;
20import javax.swing.SwingUtilities;
21import javax.swing.Timer;
22import javax.swing.text.BadLocationException;
23import javax.swing.text.Highlighter.HighlightPainter;
24
25import cuchaz.enigma.Deobfuscator;
26import cuchaz.enigma.analysis.EntryReference;
27import cuchaz.enigma.analysis.SourceIndex;
28import cuchaz.enigma.analysis.Token;
29import cuchaz.enigma.mapping.ClassEntry;
30import cuchaz.enigma.mapping.Entry;
31import de.sciss.syntaxpane.DefaultSyntaxKit;
32
33
34public class CodeReader extends JEditorPane {
35
36 private static final long serialVersionUID = 3673180950485748810L;
37
38 private static final Object lock = new Object();
39
40 public interface SelectionListener {
41 void onSelect(EntryReference<Entry, Entry> reference);
42 }
43
44 private SelectionHighlightPainter selectionHighlightPainter;
45 private SourceIndex sourceIndex;
46 private SelectionListener selectionListener;
47
48 public CodeReader() {
49
50 setEditable(false);
51 setContentType("text/java");
52
53 // turn off token highlighting (it's wrong most of the time anyway...)
54 DefaultSyntaxKit kit = (DefaultSyntaxKit) getEditorKit();
55 kit.toggleComponent(this, "de.sciss.syntaxpane.components.TokenMarker");
56
57 // hook events
58 addCaretListener(event -> {
59 if (this.selectionListener != null && this.sourceIndex != null) {
60 Token token = this.sourceIndex.getReferenceToken(event.getDot());
61 if (token != null) {
62 this.selectionListener.onSelect(this.sourceIndex.getDeobfReference(token));
63 } else {
64 this.selectionListener.onSelect(null);
65 }
66 }
67 });
68
69 this.selectionHighlightPainter = new SelectionHighlightPainter();
70 this.sourceIndex = null;
71 this.selectionListener = null;
72 }
73
74 public void setSelectionListener(SelectionListener val) {
75 this.selectionListener = val;
76 }
77
78 public void setCode(String code) {
79 // sadly, the java lexer is not thread safe, so we have to serialize all these calls
80 synchronized (lock) {
81 setText(code);
82 }
83 }
84
85 public SourceIndex getSourceIndex() {
86 return this.sourceIndex;
87 }
88
89 public void decompileClass(ClassEntry classEntry, Deobfuscator deobfuscator, Runnable callback) {
90 decompileClass(classEntry, deobfuscator, null, callback);
91 }
92
93 public void decompileClass(final ClassEntry classEntry, final Deobfuscator deobfuscator, final Boolean ignoreBadTokens, final Runnable callback) {
94
95 if (classEntry == null) {
96 setCode(null);
97 return;
98 }
99
100 setCode("(decompiling...)");
101
102 // run decompilation in a separate thread to keep ui responsive
103 new Thread() {
104 @Override
105 public void run() {
106
107 // decompile it
108 CompilationUnit sourceTree = deobfuscator.getSourceTree(classEntry.getOutermostClassName());
109 String source = deobfuscator.getSource(sourceTree);
110 setCode(source);
111 sourceIndex = deobfuscator.getSourceIndex(sourceTree, source, ignoreBadTokens);
112
113 if (callback != null) {
114 callback.run();
115 }
116 }
117 }.start();
118 }
119
120 public void navigateToClassDeclaration(ClassEntry classEntry) {
121
122 // navigate to the class declaration
123 Token token = this.sourceIndex.getDeclarationToken(classEntry);
124 if (token == null) {
125 // couldn't find the class declaration token, might be an anonymous class
126 // look for any declaration in that class instead
127 for (Entry entry : this.sourceIndex.declarations()) {
128 if (entry.getClassEntry().equals(classEntry)) {
129 token = this.sourceIndex.getDeclarationToken(entry);
130 break;
131 }
132 }
133 }
134
135 if (token != null) {
136 navigateToToken(token);
137 } else {
138 // couldn't find anything =(
139 System.out.println("Unable to find declaration in source for " + classEntry);
140 }
141 }
142
143 public void navigateToToken(final Token token) {
144 navigateToToken(this, token, this.selectionHighlightPainter);
145 }
146
147 // HACKHACK: someday we can update the main GUI to use this code reader
148 public static void navigateToToken(final JEditorPane editor, final Token token, final HighlightPainter highlightPainter) {
149
150 // set the caret position to the token
151 editor.setCaretPosition(token.start);
152 editor.grabFocus();
153
154 try {
155 // make sure the token is visible in the scroll window
156 Rectangle start = editor.modelToView(token.start);
157 Rectangle end = editor.modelToView(token.end);
158 final Rectangle show = start.union(end);
159 show.grow(start.width * 10, start.height * 6);
160 SwingUtilities.invokeLater(() -> editor.scrollRectToVisible(show));
161 } catch (BadLocationException ex) {
162 throw new Error(ex);
163 }
164
165 // highlight the token momentarily
166 final Timer timer = new Timer(200, new ActionListener() {
167 private int m_counter = 0;
168 private Object m_highlight = null;
169
170 @Override
171 public void actionPerformed(ActionEvent event) {
172 if (m_counter % 2 == 0) {
173 try {
174 m_highlight = editor.getHighlighter().addHighlight(token.start, token.end, highlightPainter);
175 } catch (BadLocationException ex) {
176 // don't care
177 }
178 } else if (m_highlight != null) {
179 editor.getHighlighter().removeHighlight(m_highlight);
180 }
181
182 if (m_counter++ > 6) {
183 Timer timer = (Timer) event.getSource();
184 timer.stop();
185 }
186 }
187 });
188 timer.start();
189 }
190
191 public void setHighlightedToken(Token token, HighlightPainter painter) {
192 try {
193 getHighlighter().addHighlight(token.start, token.end, painter);
194 } catch (BadLocationException ex) {
195 throw new IllegalArgumentException(ex);
196 }
197 }
198
199 public void clearHighlights() {
200 getHighlighter().removeAllHighlights();
201 }
202}