Skip to content

Commit

Permalink
Arranged the parameters of fernflower, forgeflower, and vineflower. C…
Browse files Browse the repository at this point in the history
…ompleted the related configuration functions
  • Loading branch information
meiMingle committed Oct 31, 2024
1 parent 11719c8 commit 0dd833d
Show file tree
Hide file tree
Showing 11 changed files with 618 additions and 468 deletions.
3 changes: 2 additions & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ subprojects {
google()
maven { url 'https://maven.quiltmc.org/repository/release/' }
maven { url 'https://jitpack.io' }
maven { url 'https://www.jetbrains.com/intellij-repository/releases' }
// maven { url 'https://www.jetbrains.com/intellij-repository/releases' }
maven { url 'https://www.jetbrains.com/intellij-repository/snapshots' }
maven { url 'https://maven.minecraftforge.net' }
}

Expand Down
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ regex = "0.1.16"
richtextfx = "0.11.3"
treemapfx = "1.1.0"
vineflower = "1.10.1"
fernflower = "242.23726.103"
#fernflower = "242.23726.103"
fernflower = "243.21565-EAP-CANDIDATE-SNAPSHOT"
forgeflower = "2.0.674.2"
annotations = "24.0.0"
wordwrap = "0.1.12"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,160 @@
package software.coley.recaf.services.decompile.fernflower;

import jakarta.annotation.Nonnull;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import org.slf4j.event.Level;
import recaf.relocation.libs.fernflower.org.jetbrains.java.decompiler.main.Fernflower;
import recaf.relocation.libs.fernflower.org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences;
import recaf.relocation.libs.fernflower.org.jetbrains.java.decompiler.util.InterpreterUtil;
import software.coley.observables.ObservableBoolean;
import software.coley.observables.ObservableInteger;
import software.coley.observables.ObservableObject;
import software.coley.observables.ObservableString;
import software.coley.recaf.config.BasicConfigValue;
import software.coley.recaf.services.decompile.BaseDecompilerConfig;

import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
* FernflowerConfig
* {@link org.jetbrains}
*
* @author meiMingle
*/
@ApplicationScoped
@SuppressWarnings("all") // ignore unused refs / typos
public class FernflowerConfig extends BaseDecompilerConfig {

/**
* Mapped from here {@link IFernflowerPreferences}
*/
private final ObservableBoolean rbr = new ObservableBoolean(true);
private final ObservableBoolean rsy = new ObservableBoolean(false);
private final ObservableBoolean din = new ObservableBoolean(true);
private final ObservableBoolean dc4 = new ObservableBoolean(true);
private final ObservableBoolean das = new ObservableBoolean(true);
private final ObservableBoolean hes = new ObservableBoolean(true);
private final ObservableBoolean hdc = new ObservableBoolean(true);
private final ObservableBoolean dgs = new ObservableBoolean(false);
private final ObservableBoolean ner = new ObservableBoolean(true);
private final ObservableBoolean esm = new ObservableBoolean(true);
private final ObservableBoolean den = new ObservableBoolean(true);
private final ObservableBoolean rgn = new ObservableBoolean(true);
private final ObservableBoolean lit = new ObservableBoolean(false);
private final ObservableBoolean bto = new ObservableBoolean(true);
private final ObservableBoolean asc = new ObservableBoolean(false);
private final ObservableBoolean nns = new ObservableBoolean(false);
private final ObservableBoolean uto = new ObservableBoolean(true);
private final ObservableBoolean udv = new ObservableBoolean(true);
private final ObservableBoolean ump = new ObservableBoolean(true);
private final ObservableBoolean rer = new ObservableBoolean(true);
private final ObservableBoolean fdi = new ObservableBoolean(true);
private final ObservableBoolean inn = new ObservableBoolean(true);
private final ObservableBoolean lac = new ObservableBoolean(false);
private final ObservableBoolean bsm = new ObservableBoolean(false);
private final ObservableBoolean iib = new ObservableBoolean(false);
private final ObservableBoolean vac = new ObservableBoolean(false);
private final ObservableBoolean crp = new ObservableBoolean(false);
private final ObservableBoolean cps = new ObservableBoolean(false);
private final ObservableBoolean sfn = new ObservableBoolean(false);
private final ObservableBoolean iec = new ObservableBoolean(false);
private final ObservableBoolean cci = new ObservableBoolean(true);
private final ObservableBoolean isl = new ObservableBoolean(true);
private final ObservableBoolean ucrc = new ObservableBoolean(true);
private final ObservableObject<Level> log = new ObservableObject<>(Level.WARN);
private final ObservableInteger mpm = new ObservableInteger(0);
private final ObservableBoolean ren = new ObservableBoolean(false);
private final ObservableString urc = new ObservableString(null, (Function<String, String>) o -> {
if (o == null || o.isBlank()) return null;
return o;
});

private final ObservableBoolean nls = new ObservableBoolean(!InterpreterUtil.IS_WINDOWS);
private final ObservableString ind = new ObservableString(" ");
private final ObservableString ban = new ObservableString("// Recreated by Recaf (powered by FernFlower decompiler)\n\n");
private final ObservableBoolean __unit_test_mode__ = new ObservableBoolean(false);
private final ObservableBoolean __dump_original_lines__ = new ObservableBoolean(false);
private final ObservableBoolean jvn = new ObservableBoolean(false);
private final ObservableBoolean jpr = new ObservableBoolean(false);
private final ObservableBoolean sef = new ObservableBoolean(false);

@Inject
public FernflowerConfig() {
super("decompiler-fernflower" + CONFIG_SUFFIX);
addValue(new BasicConfigValue<>("rbr", boolean.class, rbr));
addValue(new BasicConfigValue<>("rsy", boolean.class, rsy));
addValue(new BasicConfigValue<>("din", boolean.class, din));
addValue(new BasicConfigValue<>("dc4", boolean.class, dc4));
addValue(new BasicConfigValue<>("das", boolean.class, das));
addValue(new BasicConfigValue<>("hes", boolean.class, hes));
addValue(new BasicConfigValue<>("hdc", boolean.class, hdc));
addValue(new BasicConfigValue<>("dgs", boolean.class, dgs));
addValue(new BasicConfigValue<>("ner", boolean.class, ner));
addValue(new BasicConfigValue<>("esm", boolean.class, esm));
addValue(new BasicConfigValue<>("den", boolean.class, den));
addValue(new BasicConfigValue<>("rgn", boolean.class, rgn));
addValue(new BasicConfigValue<>("lit", boolean.class, lit));
addValue(new BasicConfigValue<>("bto", boolean.class, bto));
addValue(new BasicConfigValue<>("asc", boolean.class, asc));
addValue(new BasicConfigValue<>("nns", boolean.class, nns));
addValue(new BasicConfigValue<>("uto", boolean.class, uto));
addValue(new BasicConfigValue<>("udv", boolean.class, udv));
addValue(new BasicConfigValue<>("ump", boolean.class, ump));
addValue(new BasicConfigValue<>("rer", boolean.class, rer));
addValue(new BasicConfigValue<>("fdi", boolean.class, fdi));
addValue(new BasicConfigValue<>("inn", boolean.class, inn));
addValue(new BasicConfigValue<>("lac", boolean.class, lac));
addValue(new BasicConfigValue<>("bsm", boolean.class, bsm));
addValue(new BasicConfigValue<>("iib", boolean.class, iib));
addValue(new BasicConfigValue<>("vac", boolean.class, vac));
addValue(new BasicConfigValue<>("crp", boolean.class, crp));
addValue(new BasicConfigValue<>("cps", boolean.class, cps));
addValue(new BasicConfigValue<>("sfn", boolean.class, sfn));
addValue(new BasicConfigValue<>("iec", boolean.class, iec));
addValue(new BasicConfigValue<>("cci", boolean.class, cci));
addValue(new BasicConfigValue<>("isl", boolean.class, isl));
addValue(new BasicConfigValue<>("ucrc", boolean.class, ucrc));
addValue(new BasicConfigValue<>("log", Level.class, log));
addValue(new BasicConfigValue<>("mpm", int.class, mpm));
addValue(new BasicConfigValue<>("ren", boolean.class, ren));
addValue(new BasicConfigValue<>("urc", String.class, urc));
addValue(new BasicConfigValue<>("nls", boolean.class, nls));
addValue(new BasicConfigValue<>("ind", String.class, ind));
addValue(new BasicConfigValue<>("ban", String.class, ban));
addValue(new BasicConfigValue<>("__unit_test_mode__", boolean.class, __unit_test_mode__));
addValue(new BasicConfigValue<>("__dump_original_lines__", boolean.class, __dump_original_lines__));
addValue(new BasicConfigValue<>("jvn", boolean.class, jvn));
addValue(new BasicConfigValue<>("jpr", boolean.class, jpr));
addValue(new BasicConfigValue<>("sef", boolean.class, sef));

registerConfigValuesHashUpdates();
}

/**
* @return Map of values to pass to the {@link Fernflower} instance.
*/
@Nonnull
protected Map<String, Object> getFernflowerProperties() {
Map<String, Object> properties = new HashMap<>(IFernflowerPreferences.DEFAULTS);
getValues().forEach((key, value) -> {
if (value.getValue() instanceof Boolean bool) {
properties.put(key, bool ? "1" : "0");
} else if (value.getValue() instanceof String str) {
properties.put(key, str);
} else if (value.getValue() instanceof Level level) {
properties.put(key, level.name());
} else if (value.getValue() instanceof Integer integer) {
properties.put(key, integer.toString());
}
});
return properties;
}


public ObservableObject<Level> getLoggingLevel() {
return new ObservableObject<>(Level.WARN);
return log;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,49 +36,38 @@ public class FernflowerDecompiler extends AbstractJvmDecompiler {
@Inject
public FernflowerDecompiler(@Nonnull FernflowerConfig config) {
// Change this version to be dynamic when / if the Fernflower authors make a function that returns the version...
super(NAME, "242.23726.103", config);
super(NAME, "243.21565-EAP-CANDIDATE-SNAPSHOT", config);
this.config = config;
logger = new FernflowerLogger(config);
}

@Nonnull
@Override
public DecompileResult decompileInternal(@Nonnull Workspace workspace, @Nonnull JvmClassInfo info) {
Map<String, Object> fernflowerProperties = config.getFernflowerProperties();


Map<String, Object> options = new HashMap<>();

options.put("hdc", "0");
options.put("dgs", "1");
options.put("rsy", "1");
options.put("rbr", "1");
options.put("nls", "1");
options.put("ban", "//Recreated by Recaf (powered by FernFlower decompiler)\n\n");
options.put("mpm", 60);
options.put("ind", " ");
options.put("iib", "1");
options.put("vac", "1");
options.put("cps", "1");
options.put("crp", "1");

options.put("bsm", "1");// "decompiler.use.line.mapping"
options.put("__dump_original_lines__", "1");// "decompiler.dump.original.lines"

MyResultSaver saver = new MyResultSaver();
MyBytecodeProvider provider = new MyBytecodeProvider(workspace);

BaseDecompiler decompiler = new BaseDecompiler(
provider,
saver,
options,
fernflowerProperties,
logger
);

try {
String path = ((BasicWorkspaceFileResource) workspace.getPrimaryResource()).getFileInfo().getName() + "!" + info.getName() + ".class";
String clzName = info.getName();
String path = ((BasicWorkspaceFileResource) workspace.getPrimaryResource()).getFileInfo().getName() + "!" + clzName + ".class";
decompiler.addSource(new FakeFile(path));
List<InnerClassInfo> innerClasses = info.getInnerClasses();
innerClasses.forEach(inner -> decompiler.addSource(new FakeFile(((BasicWorkspaceFileResource) workspace.getPrimaryResource()).getFileInfo().getName() + "!" + inner.getName() + ".class")));
innerClasses.forEach(inner->{
if (workspace.findClass(inner.getInnerClassName())!=null) {
decompiler.addSource(new FakeFile(((BasicWorkspaceFileResource) workspace.getPrimaryResource()).getFileInfo().getName() + "!" + inner.getName() + ".class"));
}

});
decompiler.decompileContext();
if (saver.getResult() == null || saver.getResult().isEmpty()) {
return new DecompileResult(new IllegalStateException("Missing decompilation output"), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ public byte[] getBytecode(String absolutePath, String internalPath) {
String path = split[0];
String name = split[1];

ClassPathNode aClass = workspace.findClass(name.substring(0, name.lastIndexOf('.')));
return aClass.getValue().asJvmClass().getBytecode();
ClassPathNode aClass = workspace.findJvmClass(name.substring(0, name.lastIndexOf('.')));
if (aClass != null) {
return aClass.getValue().asJvmClass().getBytecode();
}
return null;
}
}
Loading

0 comments on commit 0dd833d

Please sign in to comment.