clj-java-decompiler
clj-java-decompiler copied to clipboard
Try using CFR for decompilation
Hearing that Procyon can't decompile leftn made me wonder if other decompilers could. So I whipped this up, and it works (with a lot of unfortunate differences in output formatting).
I don't expect you to use this, but it does demonstrate that it could work.
(decompile
(letfn [(foo [s]
(println
(str "Hello," s " decompiler!")))]
(foo "world and")))
produces
// Decompiling class: clj_java_decompiler/core$fn__13864
/*
* Decompiled with CFR 0.152.
*/
package clj_java_decompiler;
import clj_java_decompiler.core$fn__13864$foo__13865;
import clojure.lang.AFunction;
import clojure.lang.IFn;
public final class core$fn__13864
extends AFunction {
/*
* WARNING - void declaration
*/
public static Object invokeStatic() {
void foo;
core$fn__13864$foo__13865 core$fn__13864$foo__13865 = null;
core$fn__13864$foo__13865 = new core$fn__13864$foo__13865();
return ((IFn)foo).invoke("world and");
}
@Override
public Object invoke() {
return core$fn__13864.invokeStatic();
}
}
// Decompiling class: clj_java_decompiler/core$fn__13864$foo__13865
/*
* Decompiled with CFR 0.152.
*/
package clj_java_decompiler;
import clojure.lang.AFunction;
import clojure.lang.IFn;
import clojure.lang.RT;
import clojure.lang.Var;
public final class core$fn__13864$foo__13865
extends AFunction {
public static final Var __println = RT.var("clojure.core", "println");
public static final Var __str = RT.var("clojure.core", "str");
@Override
public Object invoke(Object s) {
core$fn__13864$foo__13865 this_ = null;
return __println.invoke(__str.invoke("Hello,", s, " decompiler!"));
}
}
// Decompiling class: cjd__init
/*
* Decompiled with CFR 0.152.
*/
import clj_java_decompiler.core$fn__13864;
import clojure.lang.Compiler;
import clojure.lang.IFn;
import clojure.lang.RT;
import clojure.lang.Var;
public class cjd__init {
public static void load() {
Object object = ((IFn)new core$fn__13864()).invoke();
}
static {
Compiler.pushNSandLoader(RT.classForName("cjd__init").getClassLoader());
try {
cjd__init.load();
}
catch (Throwable throwable) {
Var.popThreadBindings();
throw throwable;
}
Var.popThreadBindings();
}
}