Skip to content

Commit 4b82d8c

Browse files
committed
fix: Bump version -> 2.15.6 & Update dependencies, JFX should support Mac M1
Also update class patcher, CFR/FF decompilers
1 parent fb04fb4 commit 4b82d8c

File tree

8 files changed

+321
-188
lines changed

8 files changed

+321
-188
lines changed

checkstyle-suppressions.xml

+4
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,8 @@
125125
<suppress checks="CyclomaticComplexity"
126126
files="IllegalBytecodePatcherUtil.java"
127127
lines="0-9999"/>
128+
129+
<suppress checks="ClassDataAbstractionCoupling"
130+
files="FernFlowerAccessor.java"
131+
lines="0-9999"/>
128132
</suppressions>

pom.xml

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,17 @@
33
<groupId>me.coley</groupId>
44
<artifactId>recaf</artifactId>
55
<url>https://github.com/Col-E/Recaf/</url>
6-
<version>2.21.5</version>
6+
<version>2.21.6</version>
77
<name>Recaf</name>
88
<description>A modern java bytecode editor</description>
99
<!-- Variables -->
1010
<properties>
1111
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1212
<asm.version>9.2</asm.version>
1313
<analysis.version>1.6.0</analysis.version>
14-
<dude.version>1.7.3</dude.version>
15-
<cfr.version>0.151</cfr.version>
16-
<ff.version>403</ff.version>
14+
<dude.version>1.8.0</dude.version>
15+
<cfr.version>0.152</cfr.version>
16+
<ff.version>1.5.498.23</ff.version>
1717
<procyon.version>0.5.36</procyon.version>
1818
<junit.version>5.8.1</junit.version>
1919
<pico.version>4.6.1</pico.version>
@@ -128,7 +128,7 @@
128128
<!-- http://files.minecraftforge.net/maven/net/minecraftforge/fernflower/ -->
129129
<dependency>
130130
<groupId>net.minecraftforge</groupId>
131-
<artifactId>fernflower</artifactId>
131+
<artifactId>forgeflower</artifactId>
132132
<version>${ff.version}</version>
133133
</dependency>
134134
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->

src/main/java/me/coley/recaf/Recaf.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* @author Matt
3232
*/
3333
public class Recaf {
34-
public static final String VERSION = "2.21.5";
34+
public static final String VERSION = "2.21.6";
3535
public static final String DOC_URL = "https://col-e.github.io/Recaf-documentation/";
3636
public static final int ASM_VERSION = Opcodes.ASM9;
3737
private static Controller currentController;
@@ -80,7 +80,7 @@ private static void init() {
8080
// Bypass JDK restrictions.
8181
VMUtil.patch();
8282
// Patch in dependencies
83-
SelfDependencyPatcher.patch();
83+
SelfDependencyPatcher.ensureJavafxSupport();
8484
// Fix title bar not displaying in GTK systems
8585
System.setProperty("jdk.gtk.version", "2");
8686
// Fix for this dumb "feature" - https://mattryall.net/blog/the-infamous-turkish-locale-bug

src/main/java/me/coley/recaf/decompile/fernflower/FernFlowerAccessor.java

+53-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,24 @@
11
package me.coley.recaf.decompile.fernflower;
22

33
import me.coley.recaf.workspace.Workspace;
4-
import org.jetbrains.java.decompiler.main.*;
5-
import org.jetbrains.java.decompiler.main.extern.*;
6-
import org.jetbrains.java.decompiler.struct.*;
4+
import org.jetbrains.java.decompiler.main.ClassesProcessor;
5+
import org.jetbrains.java.decompiler.main.DecompilerContext;
6+
import org.jetbrains.java.decompiler.main.IdentityRenamerFactory;
7+
import org.jetbrains.java.decompiler.main.extern.IBytecodeProvider;
8+
import org.jetbrains.java.decompiler.main.extern.IFernflowerLogger;
9+
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
10+
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
11+
import org.jetbrains.java.decompiler.modules.renamer.PoolInterceptor;
12+
import org.jetbrains.java.decompiler.struct.IDecompiledData;
13+
import org.jetbrains.java.decompiler.struct.StructClass;
714
import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
815
import org.jetbrains.java.decompiler.util.TextBuffer;
916

1017
import java.io.IOException;
1118
import java.io.PrintWriter;
1219
import java.io.StringWriter;
13-
import java.util.*;
20+
import java.util.Locale;
21+
import java.util.Map;
1422

1523
/**
1624
* FernFlower accessor. Modified from {@link org.jetbrains.java.decompiler.main.Fernflower} to
@@ -37,13 +45,15 @@ public class FernFlowerAccessor implements IDecompiledData {
3745
public FernFlowerAccessor(IBytecodeProvider provider, IResultSaver saver, Map<String, Object>
3846
properties, IFernflowerLogger logger) {
3947
String level = (String) properties.get(IFernflowerPreferences.LOG_LEVEL);
40-
if(level != null) {
48+
if (level != null) {
4149
logger.setSeverity(IFernflowerLogger.Severity.valueOf(level.toUpperCase(Locale.ENGLISH)));
4250
}
4351
structContext = new StructContextDecorator(saver, this, new LazyLoader(provider));
4452
classProcessor = new ClassesProcessor(structContext);
45-
DecompilerContext context = new DecompilerContext(properties, logger, structContext,
46-
classProcessor, null);
53+
int threadCount = 1;
54+
DecompilerContext context = new DecompilerContext(
55+
properties, threadCount, logger, structContext, classProcessor,
56+
new PoolInterceptor(), new IdentityRenamerFactory());
4757
DecompilerContext.setCurrentContext(context);
4858
}
4959

@@ -66,8 +76,32 @@ public void addWorkspace(Workspace workspace) throws IOException, ReflectiveOper
6676
/**
6777
* Analyze classes in the workspace.
6878
*/
69-
public void analyze() {
79+
public void analyze() throws IOException, InterruptedException {
7080
classProcessor.loadClasses(null);
81+
// The threading model with FF makes no damn sense and there is NO documentaiton.
82+
// Uuggggghhhhhhh....
83+
// Sorry, you get shit performance on a single thread until I find some docs.
84+
/*
85+
DecompilerContext root = DecompilerContext.getCurrentContext();
86+
ExecutorService pool = Executors.newWorkStealingPool();
87+
for (StructClass cl : structContext.getClasses().values())
88+
pool.submit(() -> {
89+
try {
90+
DecompilerContext.cloneContext(root);
91+
classProcessor.processClass(cl);
92+
} catch (Throwable t) {
93+
t.printStackTrace();
94+
}
95+
});
96+
pool.shutdown();
97+
pool.awaitTermination(10, TimeUnit.SECONDS);
98+
*/
99+
for (StructClass cl : structContext.getClasses().values())
100+
try {
101+
classProcessor.processClass(cl);
102+
} catch (Throwable t) {
103+
t.printStackTrace();
104+
}
71105
}
72106

73107
/**
@@ -86,13 +120,23 @@ public String decompile(String name) {
86120
@Override
87121
public String getClassEntryName(StructClass cl, String entryName) {
88122
ClassesProcessor.ClassNode node = classProcessor.getMapRootClasses().get(cl.qualifiedName);
89-
if(node.type != ClassesProcessor.ClassNode.CLASS_ROOT) {
123+
if (node.type != ClassesProcessor.ClassNode.CLASS_ROOT) {
90124
return null;
91125
} else {
92126
return entryName.substring(0, entryName.lastIndexOf(".class")) + ".java";
93127
}
94128
}
95129

130+
@Override
131+
public boolean processClass(StructClass structClass) {
132+
try {
133+
classProcessor.processClass(structClass);
134+
return true;
135+
} catch (IOException e) {
136+
return false;
137+
}
138+
}
139+
96140
@Override
97141
public String getClassContent(StructClass cl) {
98142
TextBuffer buffer;

src/main/java/me/coley/recaf/decompile/fernflower/FernFlowerDecompiler.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ private void setup(Workspace workspace) {
8585
decompiler = new FernFlowerAccessor(provider, DUMMY_COLLECTOR, getOptions(), LOGGER);
8686
try {
8787
decompiler.addWorkspace(workspace);
88+
decompiler.analyze();
8889
} catch(IOException ex) {
8990
throw new IllegalStateException("Failed to load inputs for FernFlower!", ex);
9091
} catch(ReflectiveOperationException ex) {
@@ -94,7 +95,6 @@ private void setup(Workspace workspace) {
9495
} catch(Exception ex) {
9596
throw new IllegalStateException(ex);
9697
}
97-
decompiler.analyze();
9898
lastWorkspace = workspace;
9999
}
100100
}
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
package me.coley.recaf.decompile.fernflower;
22

3-
import me.coley.recaf.util.Log;
43
import me.coley.recaf.workspace.JavaResource;
54
import me.coley.recaf.workspace.Workspace;
65
import org.jetbrains.java.decompiler.main.extern.IResultSaver;
7-
import org.jetbrains.java.decompiler.struct.*;
6+
import org.jetbrains.java.decompiler.struct.IDecompiledData;
7+
import org.jetbrains.java.decompiler.struct.StructContext;
88
import org.jetbrains.java.decompiler.struct.lazy.LazyLoader;
99

1010
import java.io.IOException;
11-
import java.lang.reflect.Field;
1211
import java.util.Map;
1312

14-
import static me.coley.recaf.util.CollectionUtil.*;
13+
import static me.coley.recaf.util.CollectionUtil.copySet;
1514

1615
/**
1716
* Decorator for StructContext to support Recaf workspaces.
@@ -26,7 +25,7 @@ public class StructContextDecorator extends StructContext {
2625
* Result saver <i>(Unused/noop)</i>
2726
* @param data
2827
* Data instance, should be an instance of
29-
* {@link me.coley.recaf.decompile.fernflower.FernFlowerAccessor}.
28+
* {@link me.coley.recaf.decompile.fernflower.FernFlowerAccessor}.
3029
* @param loader
3130
* LazyLoader to hold links to class resources.
3231
*/
@@ -40,40 +39,24 @@ public StructContextDecorator(IResultSaver saver, IDecompiledData data, LazyLoad
4039
*
4140
* @throws IOException
4241
* Thrown if a class cannot be read.
43-
* @throws ReflectiveOperationException
44-
* Thrown if the parent loader could not be fetched.
4542
* @throws IndexOutOfBoundsException
4643
* Thrown if FernFlower can't read the class.
4744
* <i>(IE: It fails on newer Java class files)</i>
4845
*/
49-
public void addWorkspace(Workspace workspace) throws IOException,
50-
ReflectiveOperationException {
51-
LazyLoader loader = getLoader();
46+
public void addWorkspace(Workspace workspace) throws IOException {
5247
// Add primary resource classes
53-
addResource(workspace.getPrimary(), loader);
48+
addResource(workspace.getPrimary());
5449
for (JavaResource resource : workspace.getLibraries())
55-
addResource(resource, loader);
50+
addResource(resource);
5651
}
5752

58-
private void addResource(JavaResource resource, LazyLoader loader) throws IOException {
53+
private void addResource(JavaResource resource) throws IOException {
5954
// Iterate resource class entries
60-
for(Map.Entry<String, byte[]> entry : copySet(resource.getClasses().entrySet())) {
55+
for (Map.Entry<String, byte[]> entry : copySet(resource.getClasses().entrySet())) {
6156
String name = entry.getKey();
57+
String simpleName = name.substring(name.lastIndexOf('/') + 1);
6258
byte[] code = entry.getValue();
63-
// register class in the map and lazy-loader.
64-
try {
65-
getClasses().put(name, new StructClass(code, true, loader));
66-
loader.addClassLink(name, new LazyLoader.Link(null, name + ".class"));
67-
} catch (Throwable t) {
68-
Log.debug("Error populating FF Struct from code, class={}", name);
69-
}
59+
addData(name, simpleName, code, true);
7060
}
7161
}
72-
73-
private LazyLoader getLoader() throws ReflectiveOperationException {
74-
// Hack to access private parent loader
75-
Field floader = StructContext.class.getDeclaredField("loader");
76-
floader.setAccessible(true);
77-
return (LazyLoader) floader.get(this);
78-
}
7962
}

src/main/java/me/coley/recaf/util/StringUtil.java

+19-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ public static String generateName(String alphabet, int index) {
7171
int m = 8;
7272
final char[] array = new char[m];
7373
int n = m - 1;
74-
while(index > charz.length - 1) {
74+
while (index > charz.length - 1) {
7575
int k = Math.abs(-(index % alphabetLength));
7676
array[n--] = charz[k];
7777
index /= alphabetLength;
@@ -91,7 +91,7 @@ public static String generateName(String alphabet, int index) {
9191
*/
9292
public static String indent(int level, String indent) {
9393
StringBuilder sb = new StringBuilder();
94-
for(int i = 0; i < level; i++)
94+
for (int i = 0; i < level; i++)
9595
sb.append(indent);
9696
return sb.toString();
9797
}
@@ -123,4 +123,21 @@ public static String limit(String str, int maxLength) {
123123
public static <E extends Enum<?>> String toString(E value) {
124124
return value.name().substring(0, 1).toUpperCase() + value.name().substring(1).toLowerCase();
125125
}
126+
127+
/**
128+
* @param pattern
129+
* Pattern to look for.
130+
* @param text
131+
* Text to check.
132+
*
133+
* @return Number of times the given pattern appears in the text.
134+
*/
135+
public static int count(String pattern, String text) {
136+
int count = 0;
137+
while (text.contains(pattern)) {
138+
text = text.replaceFirst(pattern, "");
139+
count++;
140+
}
141+
return count;
142+
}
126143
}

0 commit comments

Comments
 (0)