summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java11
-rw-r--r--enigma/src/main/java/cuchaz/enigma/EnigmaProject.java62
2 files changed, 55 insertions, 18 deletions
diff --git a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
index 2dc1d77a..b62e9cf9 100644
--- a/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
+++ b/enigma-swing/src/main/java/cuchaz/enigma/gui/GuiController.java
@@ -189,9 +189,14 @@ public class GuiController implements ClientPacketHandler {
189 189
190 return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> { 190 return ProgressDialog.runOffThread(this.gui.getFrame(), progress -> {
191 EnigmaProject.JarExport jar = project.exportRemappedJar(progress); 191 EnigmaProject.JarExport jar = project.exportRemappedJar(progress);
192 EnigmaProject.SourceExport source = jar.decompile(progress, chp.getDecompilerService()); 192 jar.decompileStream(progress, chp.getDecompilerService(), EnigmaProject.DecompileErrorStrategy.TRACE_AS_SOURCE)
193 193 .forEach(source -> {
194 source.write(path, progress); 194 try {
195 source.writeTo(source.resolvePath(path));
196 } catch (IOException e) {
197 e.printStackTrace();
198 }
199 });
195 }); 200 });
196 } 201 }
197 202
diff --git a/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java b/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java
index 3999572f..c3751581 100644
--- a/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java
+++ b/enigma/src/main/java/cuchaz/enigma/EnigmaProject.java
@@ -31,12 +31,14 @@ import java.io.IOException;
31import java.nio.file.Files; 31import java.nio.file.Files;
32import java.nio.file.Path; 32import java.nio.file.Path;
33import java.util.Collection; 33import java.util.Collection;
34import java.util.List;
34import java.util.Map; 35import java.util.Map;
35import java.util.Objects; 36import java.util.Objects;
36import java.util.concurrent.atomic.AtomicInteger; 37import java.util.concurrent.atomic.AtomicInteger;
37import java.util.jar.JarEntry; 38import java.util.jar.JarEntry;
38import java.util.jar.JarOutputStream; 39import java.util.jar.JarOutputStream;
39import java.util.stream.Collectors; 40import java.util.stream.Collectors;
41import java.util.stream.Stream;
40 42
41public class EnigmaProject { 43public class EnigmaProject {
42 private final Enigma enigma; 44 private final Enigma enigma;
@@ -173,15 +175,13 @@ public class EnigmaProject {
173 .filter(Objects::nonNull) 175 .filter(Objects::nonNull)
174 .collect(Collectors.toMap(n -> n.name, Functions.identity())); 176 .collect(Collectors.toMap(n -> n.name, Functions.identity()));
175 177
176 return new JarExport(jarIndex, compiled); 178 return new JarExport(compiled);
177 } 179 }
178 180
179 public static final class JarExport { 181 public static final class JarExport {
180 private final JarIndex jarIndex;
181 private final Map<String, ClassNode> compiled; 182 private final Map<String, ClassNode> compiled;
182 183
183 JarExport(JarIndex jarIndex, Map<String, ClassNode> compiled) { 184 JarExport(Map<String, ClassNode> compiled) {
184 this.jarIndex = jarIndex;
185 this.compiled = compiled; 185 this.compiled = compiled;
186 } 186 }
187 187
@@ -207,6 +207,15 @@ public class EnigmaProject {
207 } 207 }
208 208
209 public SourceExport decompile(ProgressListener progress, DecompilerService decompilerService) { 209 public SourceExport decompile(ProgressListener progress, DecompilerService decompilerService) {
210 return this.decompile(progress, decompilerService, DecompileErrorStrategy.PROPAGATE);
211 }
212
213 public SourceExport decompile(ProgressListener progress, DecompilerService decompilerService, DecompileErrorStrategy errorStrategy) {
214 List<ClassSource> decompiled = this.decompileStream(progress, decompilerService, errorStrategy).collect(Collectors.toList());
215 return new SourceExport(decompiled);
216 }
217
218 public Stream<ClassSource> decompileStream(ProgressListener progress, DecompilerService decompilerService, DecompileErrorStrategy errorStrategy) {
210 Collection<ClassNode> classes = this.compiled.values().stream() 219 Collection<ClassNode> classes = this.compiled.values().stream()
211 .filter(classNode -> classNode.name.indexOf('$') == -1) 220 .filter(classNode -> classNode.name.indexOf('$') == -1)
212 .collect(Collectors.toList()); 221 .collect(Collectors.toList());
@@ -218,16 +227,33 @@ public class EnigmaProject {
218 227
219 AtomicInteger count = new AtomicInteger(); 228 AtomicInteger count = new AtomicInteger();
220 229
221 Collection<ClassSource> decompiled = classes.parallelStream() 230 return classes.parallelStream()
222 .map(translatedNode -> { 231 .map(translatedNode -> {
223 progress.step(count.getAndIncrement(), translatedNode.name); 232 progress.step(count.getAndIncrement(), translatedNode.name);
224 233
225 String source = decompileClass(translatedNode, decompiler); 234 String source = null;
235 try {
236 source = decompileClass(translatedNode, decompiler);
237 } catch (Throwable throwable) {
238 switch (errorStrategy) {
239 case PROPAGATE: throw throwable;
240 case IGNORE: break;
241 case TRACE_AS_SOURCE: {
242 StringWriter writer = new StringWriter();
243 throwable.printStackTrace(new PrintWriter(writer));
244 source = writer.toString();
245 break;
246 }
247 }
248 }
249
250 if (source == null) {
251 return null;
252 }
253
226 return new ClassSource(translatedNode.name, source); 254 return new ClassSource(translatedNode.name, source);
227 }) 255 })
228 .collect(Collectors.toList()); 256 .filter(Objects::nonNull);
229
230 return new SourceExport(decompiled);
231 } 257 }
232 258
233 private String decompileClass(ClassNode translatedNode, Decompiler decompiler) { 259 private String decompileClass(ClassNode translatedNode, Decompiler decompiler) {
@@ -236,7 +262,7 @@ public class EnigmaProject {
236 } 262 }
237 263
238 public static final class SourceExport { 264 public static final class SourceExport {
239 private final Collection<ClassSource> decompiled; 265 public final Collection<ClassSource> decompiled;
240 266
241 SourceExport(Collection<ClassSource> decompiled) { 267 SourceExport(Collection<ClassSource> decompiled) {
242 this.decompiled = decompiled; 268 this.decompiled = decompiled;
@@ -255,24 +281,30 @@ public class EnigmaProject {
255 } 281 }
256 } 282 }
257 283
258 private static class ClassSource { 284 public static class ClassSource {
259 private final String name; 285 public final String name;
260 private final String source; 286 public final String source;
261 287
262 ClassSource(String name, String source) { 288 ClassSource(String name, String source) {
263 this.name = name; 289 this.name = name;
264 this.source = source; 290 this.source = source;
265 } 291 }
266 292
267 void writeTo(Path path) throws IOException { 293 public void writeTo(Path path) throws IOException {
268 Files.createDirectories(path.getParent()); 294 Files.createDirectories(path.getParent());
269 try (BufferedWriter writer = Files.newBufferedWriter(path)) { 295 try (BufferedWriter writer = Files.newBufferedWriter(path)) {
270 writer.write(source); 296 writer.write(source);
271 } 297 }
272 } 298 }
273 299
274 Path resolvePath(Path root) { 300 public Path resolvePath(Path root) {
275 return root.resolve(name.replace('.', '/') + ".java"); 301 return root.resolve(name.replace('.', '/') + ".java");
276 } 302 }
277 } 303 }
304
305 public enum DecompileErrorStrategy {
306 PROPAGATE,
307 TRACE_AS_SOURCE,
308 IGNORE
309 }
278} 310}