Skip to content

Commit c50e834

Browse files
committed
fix compiler
1 parent f96c714 commit c50e834

File tree

7 files changed

+69
-27
lines changed

7 files changed

+69
-27
lines changed

src/main/java/cn/enaium/joe/gui/panel/file/tabbed/tab/classes/ASMifierTablePanel.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,12 @@ public ASMifierTablePanel(ClassNode classNode) {
6969
"}" +
7070
"}";
7171

72-
byte[] dumps = (byte[])new ASMClassLoader().defineClass(className, Compiler.compileSingle(className, stringBuilder)).getMethod("dump").invoke(null);
72+
StringWriter errorTracer = new StringWriter();
73+
byte[] dumpClazz = Compiler.compileSingle(className, stringBuilder, errorTracer);
74+
if (dumpClazz == null) {
75+
MessageUtil.error(errorTracer.toString());
76+
}
77+
byte[] dumps = (byte[])new ASMClassLoader().defineClass(className, dumpClazz).getMethod("dump").invoke(null);
7378
ReflectionHelper.copyAllMember(classNode, ASMUtil.acceptClassNode(new ClassReader(dumps)));
7479
MessageUtil.info(LangUtil.i18n("success"));
7580
EditSaveSuccessEvent.trigger(classNode.name);

src/main/java/cn/enaium/joe/util/classes/ASMClassLoader.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package cn.enaium.joe.util.classes;
22

33
public class ASMClassLoader extends ClassLoader{
4+
public ASMClassLoader(){}
5+
6+
public ASMClassLoader(ClassLoader classLoader){super(classLoader);}
7+
48
public Class<?> defineClass(String canonicalName, byte[] clazz){
59
return defineClass(canonicalName, clazz, 0, clazz.length);
610
}

src/main/java/cn/enaium/joe/util/compiler/Compiler.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@
1616

1717
package cn.enaium.joe.util.compiler;
1818

19+
import cn.enaium.joe.Main;
1920
import cn.enaium.joe.util.Util;
2021
import cn.enaium.joe.util.compiler.environment.RecompileEnvironment;
2122
import cn.enaium.joe.util.compiler.virtual.MemoryClassLoader;
2223
import cn.enaium.joe.util.compiler.virtual.VirtualFileManager;
2324
import cn.enaium.joe.util.compiler.virtual.VirtualJavaFileObject;
2425

2526
import javax.tools.*;
27+
import java.io.PrintWriter;
2628
import java.io.StringWriter;
29+
import java.io.Writer;
2730
import java.nio.charset.StandardCharsets;
2831
import java.util.HashMap;
2932
import java.util.Map;
@@ -56,17 +59,26 @@ public static byte[] compileSingle(String canonicalName, String text){
5659
return compiler.getClasses().get(canonicalName);
5760
}
5861

62+
public static byte[] compileSingle(String canonicalName, String text, Writer errorTracer){
63+
Compiler compiler = new Compiler();
64+
compiler.addSource(canonicalName, text);
65+
CompileError compileError = compiler.compile();
66+
if (compileError != null) {
67+
compileError.printStackTrace(new PrintWriter(errorTracer));
68+
return null;
69+
}
70+
return compiler.getClasses().get(canonicalName);
71+
}
72+
5973
public CompileError compile() {
60-
MemoryClassLoader memoryClassLoader = new MemoryClassLoader(RecompileEnvironment.getEnvironment());
61-
Thread.currentThread().setContextClassLoader(memoryClassLoader);
74+
MemoryClassLoader memoryClassLoader = new MemoryClassLoader(Main.classLoader, RecompileEnvironment.getEnvironment());
6275
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
6376
StandardJavaFileManager standardJavaFileManager = compiler.getStandardFileManager(null, null, StandardCharsets.UTF_8);
6477
VirtualFileManager fileManager = new VirtualFileManager(standardJavaFileManager, this.javaFileObjectMap, memoryClassLoader);
6578
try {
6679
StringWriter stringWriter = new StringWriter();
6780
JavaCompiler.CompilationTask task = compiler.getTask(stringWriter, fileManager, Util.cast(listener), null, null, javaFileObjectMap.values());
68-
Boolean b = task.call();
69-
if (b != null && b) {
81+
if (task.call() == Boolean.TRUE) {
7082
this.results = fileManager.getClasses();
7183
return null;
7284
} else return new CompileError(stringWriter.toString());

src/main/java/cn/enaium/joe/util/compiler/virtual/MemoryClassLoader.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
public class MemoryClassLoader extends ASMClassLoader {
88
final Map<String, byte[]> classes;
99

10-
public MemoryClassLoader(Map<String, byte[]> classes){
10+
public MemoryClassLoader(ClassLoader parent, Map<String, byte[]> classes){
11+
super(parent);
1112
if (classes == null) classes = Map.of();
1213
this.classes = classes;
1314
}

src/main/java/cn/enaium/joe/util/compiler/virtual/VirtualFileManager.java

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public Map<String, byte[]> getClasses() {
2222

2323
@Override
2424
public ClassLoader getClassLoader(Location location) {
25-
return this.classLoader;
25+
return this.classLoader == null ? super.getClassLoader(location) : this.classLoader;
2626
}
2727

2828
@Override
@@ -37,23 +37,26 @@ public JavaFileObject getJavaFileForOutput(JavaFileManager.Location location, St
3737
}
3838

3939
@Override
40-
public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) {
41-
return ServiceLoader.load(service, classLoader);
40+
public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
41+
return this.classLoader == null ? super.getServiceLoader(location, service) : ServiceLoader.load(service, classLoader);
4242
}
4343

4444
@Override
4545
public Iterable<JavaFileObject> list(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) throws IOException {
4646
List<JavaFileObject> ret = new ArrayList<>();
47-
if ((StandardLocation.CLASS_OUTPUT.equals(location) || StandardLocation.CLASS_PATH.equals(location))
48-
&& kinds.contains(JavaFileObject.Kind.CLASS)) {
49-
for (Map.Entry<String, byte[]> e : classLoader.classes.entrySet()) {
50-
if (e.getKey().startsWith(packageName + ".")) {
51-
if (recurse || e.getKey().lastIndexOf('.') == packageName.length()) {
52-
ret.add(new VirtualJavaClassObject(e.getKey(), e.getValue()));
47+
if (this.classLoader != null) {
48+
if ((StandardLocation.CLASS_OUTPUT.equals(location) || StandardLocation.CLASS_PATH.equals(location))
49+
&& kinds.contains(JavaFileObject.Kind.CLASS)) {
50+
for (Map.Entry<String, byte[]> e : classLoader.classes.entrySet()) {
51+
if (e.getKey().startsWith(packageName + ".")) {
52+
if (recurse || e.getKey().lastIndexOf('.') == packageName.length()) {
53+
ret.add(new VirtualJavaClassObject(e.getKey(), e.getValue()));
54+
}
5355
}
5456
}
5557
}
5658
}
59+
System.out.println(Arrays.toString(ret.toArray()));
5760
Iterable<JavaFileObject> superList = super.list(location, packageName, kinds, recurse);
5861
if (superList != null) for (JavaFileObject f : superList)
5962
ret.add(f);
@@ -62,6 +65,8 @@ public Iterable<JavaFileObject> list(Location location, String packageName, Set<
6265

6366
@Override
6467
public String inferBinaryName(Location location, JavaFileObject file) {
65-
return file.getName();
68+
if (file instanceof VirtualJavaClassObject) {
69+
return file.getName();
70+
} else return super.inferBinaryName(location, file);
6671
}
6772
}

src/test/java/cn/enaium/joe/asm/VisitorTest.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import cn.enaium.joe.util.compiler.Compiler;
44
import cn.enaium.joe.util.ASMUtil;
55
import cn.enaium.joe.util.ImagineBreakerHelper;
6+
import org.junit.jupiter.api.Assertions;
67
import org.junit.jupiter.api.Test;
78
import org.objectweb.asm.ClassReader;
89
import org.objectweb.asm.tree.ClassNode;
@@ -14,8 +15,6 @@
1415
import java.io.PrintWriter;
1516
import java.io.StringWriter;
1617

17-
import static org.junit.jupiter.api.Assertions.assertNull;
18-
1918
/**
2019
* @author Enaium
2120
*/
@@ -29,11 +28,14 @@ public void test() throws IOException {
2928
StringWriter stringWriter = new StringWriter();
3029
ClassReader classReader = new ClassReader(this.getClass().getName());
3130
classReader.accept(new TraceClassVisitor(null, new ASMifier(), new PrintWriter(stringWriter)), 0);
32-
Compiler compiler = new Compiler();
3331
String name = "asm." + this.getClass().getName() + "Dump";
34-
compiler.addSource(name, stringWriter.toString());
35-
assertNull(compiler.compile());
36-
ClassNode classNode = ASMUtil.acceptClassNode(new ClassReader(compiler.getClasses().get(name)));
32+
StringWriter errorTracer = new StringWriter();
33+
byte[] clazz = Compiler.compileSingle(name, stringWriter.toString(), errorTracer);
34+
if (!errorTracer.toString().isEmpty()) {
35+
System.out.println(errorTracer);
36+
}
37+
Assertions.assertNotNull(clazz);
38+
ClassNode classNode = ASMUtil.acceptClassNode(new ClassReader(clazz));
3739
StringWriter out = new StringWriter();
3840
classNode.accept(new TraceClassVisitor(new PrintWriter(out)));
3941
System.out.println(out);

src/test/java/cn/enaium/joe/compiler/CompilerTest.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package cn.enaium.joe.compiler;
1818

1919
import cn.enaium.joe.util.ASMUtil;
20+
import cn.enaium.joe.util.classes.ASMClassLoader;
2021
import cn.enaium.joe.util.compiler.Compiler;
2122
import org.junit.jupiter.api.Assertions;
2223
import org.junit.jupiter.api.Test;
@@ -33,12 +34,24 @@
3334
class CompilerTest {
3435
@Test
3536
public void compile() {
36-
Compiler compiler = new Compiler();
37-
compiler.addSource("Test", "public class Test { public static void main(String[] args) { System.out.println(0xCAFEBABE); } }");
38-
Assertions.assertNull(compiler.compile());
39-
ClassNode classNode = ASMUtil.acceptClassNode(new ClassReader(compiler.getClasses().get("Test")));
37+
StringWriter stringWriter = new StringWriter();
38+
final byte[] clazz = Compiler.compileSingle("CompilerTestFooClass", "public class CompilerTestFooClass { public static boolean foo() { return CompilerTestFooClass.class.getName().equals(\"CompilerTestFooClass\"); } }", stringWriter);
39+
if (!stringWriter.toString().isEmpty()) {
40+
System.out.println(stringWriter);
41+
}
42+
Assertions.assertNotNull(clazz);
43+
ClassNode classNode = ASMUtil.acceptClassNode(new ClassReader(clazz));
4044
StringWriter out = new StringWriter();
4145
classNode.accept(new TraceClassVisitor(new PrintWriter(out)));
42-
System.out.println(out);
46+
Assertions.assertTrue(() -> {
47+
try {
48+
return (boolean) new ASMClassLoader().defineClass("CompilerTestFooClass", clazz).getMethod("foo").invoke(null);
49+
} catch (Throwable throwable) {
50+
StringWriter stringWriter1 = new StringWriter();
51+
throwable.printStackTrace(new PrintWriter(stringWriter1));
52+
System.out.println(stringWriter1);
53+
return false;
54+
}
55+
});
4356
}
4457
}

0 commit comments

Comments
 (0)