mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-15 00:17:45 +00:00
Hey, the sneaky throws remover works, at least when run separately.
This commit is contained in:
1 parent
11fcdbee72
commit
40466c3e2d
4 files changed
+133
-1
No files matched your search
@@ -0,0 +1,80 @@
|
||||
package lombok.bytecode;
|
||||
|
||||
import lombok.core.DiagnosticsReceiver;
|
||||
import lombok.core.PostCompilerTransformation;
|
||||
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
import org.objectweb.asm.ClassAdapter;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.MethodAdapter;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.commons.JSRInlinerAdapter;
|
||||
|
||||
@ProviderFor(PostCompilerTransformation.class)
|
||||
public class SneakyThrowsRemover implements PostCompilerTransformation {
|
||||
private static class FixedClassWriter extends ClassWriter {
|
||||
FixedClassWriter(ClassReader classReader, int flags) {
|
||||
super(classReader, flags);
|
||||
}
|
||||
|
||||
@Override protected String getCommonSuperClass(String type1, String type2) {
|
||||
//By default, ASM will attempt to live-load the class types, which will fail if meddling with classes in an
|
||||
//environment with custom classloaders, such as Equinox. It's just an optimization; returning Object is always legal.
|
||||
try {
|
||||
return super.getCommonSuperClass(type1, type2);
|
||||
} catch (Exception e) {
|
||||
return "java/lang/Object";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected byte[] fixJSRInlining(byte[] byteCode) {
|
||||
ClassReader reader = new ClassReader(byteCode);
|
||||
ClassWriter writer = new FixedClassWriter(reader, 0);
|
||||
|
||||
ClassVisitor visitor = new ClassAdapter(writer) {
|
||||
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
return new JSRInlinerAdapter(super.visitMethod(access, name, desc, signature, exceptions), access, name, desc, signature, exceptions);
|
||||
}
|
||||
};
|
||||
|
||||
reader.accept(visitor, 0);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
@Override public byte[] applyTransformations(byte[] original, String className, DiagnosticsReceiver diagnostics) {
|
||||
byte[] fixedByteCode = fixJSRInlining(original);
|
||||
|
||||
ClassReader reader = new ClassReader(fixedByteCode);
|
||||
ClassWriter writer = new FixedClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
|
||||
|
||||
reader.accept(new ClassAdapter(writer) {
|
||||
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
|
||||
return new SneakyThrowsRemoverVisitor(super.visitMethod(access, name, desc, signature, exceptions));
|
||||
}
|
||||
}, 0);
|
||||
return writer.toByteArray();
|
||||
}
|
||||
|
||||
private class SneakyThrowsRemoverVisitor extends MethodAdapter {
|
||||
SneakyThrowsRemoverVisitor(MethodVisitor mv) {
|
||||
super(mv);
|
||||
}
|
||||
|
||||
@Override public void visitMethodInsn(int opcode, String owner, String name, String desc) {
|
||||
boolean hit = true;
|
||||
if (hit && opcode != Opcodes.INVOKESTATIC) hit = false;
|
||||
if (hit && !"sneakyThrow".equals(name)) hit = false;
|
||||
if (hit && !"lombok/Lombok".equals(owner)) hit = false;
|
||||
if (hit && !"(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;".equals(desc)) hit = false;
|
||||
if (hit) {
|
||||
super.visitInsn(Opcodes.ATHROW);
|
||||
} else {
|
||||
super.visitMethodInsn(opcode, owner, name, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,17 @@
|
||||
package lombok.core;
|
||||
|
||||
public interface DiagnosticsReceiver {
|
||||
DiagnosticsReceiver CONSOLE = new DiagnosticsReceiver() {
|
||||
|
||||
@Override public void addError(String message) {
|
||||
System.err.println(message);
|
||||
}
|
||||
|
||||
@Override public void addWarning(String message) {
|
||||
System.out.println(message);
|
||||
}
|
||||
};
|
||||
|
||||
/** Generate a compiler error on this node. */
|
||||
void addError(String message);
|
||||
|
||||
|
||||
@@ -21,10 +21,46 @@
|
||||
*/
|
||||
package lombok.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
public final class PostCompiler {
|
||||
private PostCompiler() {/* prevent instantiation*/};
|
||||
|
||||
private static List<PostCompilerTransformation> transformations;
|
||||
|
||||
public static byte[] applyTransformations(byte[] original, String className, DiagnosticsReceiver diagnostics) {
|
||||
return original;
|
||||
init(diagnostics);
|
||||
byte[] previous = original;
|
||||
for (PostCompilerTransformation transformation : transformations) {
|
||||
try {
|
||||
byte[] next = transformation.applyTransformations(previous, className, diagnostics);
|
||||
if (next != null) {
|
||||
previous = next;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
diagnostics.addWarning(String.format("Error during the transformation of '%s'; post-compiler '%s' caused an exception: %s", className, transformation.getClass().getName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
return previous;
|
||||
}
|
||||
|
||||
private static synchronized void init(DiagnosticsReceiver diagnostics) {
|
||||
if (transformations != null) return;
|
||||
transformations = new ArrayList<PostCompilerTransformation>();
|
||||
try {
|
||||
Iterator<PostCompilerTransformation> discovered = SpiLoadUtil.findServices(PostCompilerTransformation.class).iterator();
|
||||
while (discovered.hasNext()) {
|
||||
try {
|
||||
transformations.add(discovered.next());
|
||||
} catch (Exception e) {
|
||||
diagnostics.addWarning("Error during loading post-compile transformers: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
diagnostics.addWarning("Could not load post-compile transformers: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package lombok.core;
|
||||
|
||||
public interface PostCompilerTransformation {
|
||||
byte[] applyTransformations(byte[] original, String className, DiagnosticsReceiver diagnostics);
|
||||
}
|
||||
Reference in new issue
Block a user