diff options
Diffstat (limited to 'src/core/lombok/bytecode')
-rw-r--r-- | src/core/lombok/bytecode/PreventNullAnalysisRemover.java | 2 | ||||
-rw-r--r-- | src/core/lombok/bytecode/SneakyThrowsRemover.java | 115 |
2 files changed, 111 insertions, 6 deletions
diff --git a/src/core/lombok/bytecode/PreventNullAnalysisRemover.java b/src/core/lombok/bytecode/PreventNullAnalysisRemover.java index 3342eacb..751e691f 100644 --- a/src/core/lombok/bytecode/PreventNullAnalysisRemover.java +++ b/src/core/lombok/bytecode/PreventNullAnalysisRemover.java @@ -44,7 +44,7 @@ public class PreventNullAnalysisRemover implements PostCompilerTransformation { byte[] fixedByteCode = fixJSRInlining(original); ClassReader reader = new ClassReader(fixedByteCode); - ClassWriter writer = new FixedClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + ClassWriter writer = new FixedClassWriter(reader, 0); final AtomicBoolean changesMade = new AtomicBoolean(); diff --git a/src/core/lombok/bytecode/SneakyThrowsRemover.java b/src/core/lombok/bytecode/SneakyThrowsRemover.java index c54495d4..914c313a 100644 --- a/src/core/lombok/bytecode/SneakyThrowsRemover.java +++ b/src/core/lombok/bytecode/SneakyThrowsRemover.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 The Project Lombok Authors. + * Copyright (C) 2010-2013 The Project Lombok Authors. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -32,19 +32,21 @@ import org.mangosdk.spi.ProviderFor; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; +import org.objectweb.asm.Handle; +import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; @ProviderFor(PostCompilerTransformation.class) public class SneakyThrowsRemover implements PostCompilerTransformation { - @Override public byte[] applyTransformations(byte[] original, String fileName, DiagnosticsReceiver diagnostics) { + @Override public byte[] applyTransformations(byte[] original, String fileName, final DiagnosticsReceiver diagnostics) { if (!new ClassFileMetaData(original).usesMethod("lombok/Lombok", "sneakyThrow")) return null; byte[] fixedByteCode = fixJSRInlining(original); ClassReader reader = new ClassReader(fixedByteCode); - ClassWriter writer = new FixedClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); + ClassWriter writer = new ClassWriter(reader, 0); final AtomicBoolean changesMade = new AtomicBoolean(); @@ -53,6 +55,8 @@ public class SneakyThrowsRemover implements PostCompilerTransformation { super(Opcodes.ASM4, mv); } + private boolean methodInsnQueued = false; + @Override public void visitMethodInsn(int opcode, String owner, String name, String desc) { if ( opcode == Opcodes.INVOKESTATIC && @@ -60,16 +64,117 @@ public class SneakyThrowsRemover implements PostCompilerTransformation { "lombok/Lombok".equals(owner) && "(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;".equals(desc)) { - changesMade.set(true); if (System.getProperty("lombok.debugAsmOnly", null) != null) { super.visitMethodInsn(opcode, owner, name, desc); // DEBUG for issue 470! } else { - super.visitInsn(Opcodes.ATHROW); + methodInsnQueued = true; } } else { super.visitMethodInsn(opcode, owner, name, desc); } } + + private void handleQueue() { + if (!methodInsnQueued) return; + super.visitMethodInsn(Opcodes.INVOKESTATIC, "lombok/Lombok", "sneakyThrow", "(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;"); + methodInsnQueued = false; + diagnostics.addWarning("Proper usage is: throw lombok.Lombok.sneakyThrow(someException);. You did not 'throw' it. Because of this, the call to sneakyThrow " + + "remains in your classfile and you will need lombok.jar on the classpath at runtime."); + } + + @Override public void visitInsn(int arg0) { + if (methodInsnQueued && arg0 == Opcodes.ATHROW) { + changesMade.set(true); + // As expected, the required ATHROW. We can now safely 'eat' the previous call. + methodInsnQueued = false; + } + handleQueue(); + super.visitInsn(arg0); + } + @Override public void visitFrame(int arg0, int arg1, Object[] arg2, int arg3, Object[] arg4) { + handleQueue(); + super.visitFrame(arg0, arg1, arg2, arg3, arg4); + } + + @Override public void visitIincInsn(int arg0, int arg1) { + handleQueue(); + super.visitIincInsn(arg0, arg1); + } + + @Override public void visitFieldInsn(int arg0, String arg1, String arg2, String arg3) { + handleQueue(); + super.visitFieldInsn(arg0, arg1, arg2, arg3); + } + + @Override public void visitIntInsn(int arg0, int arg1) { + handleQueue(); + super.visitIntInsn(arg0, arg1); + } + + @Override public void visitEnd() { + handleQueue(); + super.visitEnd(); + } + + @Override public void visitInvokeDynamicInsn(String arg0, String arg1, Handle arg2, Object... arg3) { + handleQueue(); + super.visitInvokeDynamicInsn(arg0, arg1, arg2, arg3); + } + + @Override public void visitLabel(Label arg0) { + handleQueue(); + super.visitLabel(arg0); + } + + @Override public void visitJumpInsn(int arg0, Label arg1) { + handleQueue(); + super.visitJumpInsn(arg0, arg1); + } + + @Override public void visitLdcInsn(Object arg0) { + handleQueue(); + super.visitLdcInsn(arg0); + } + + @Override public void visitLocalVariable(String arg0, String arg1, String arg2, Label arg3, Label arg4, int arg5) { + handleQueue(); + super.visitLocalVariable(arg0, arg1, arg2, arg3, arg4, arg5); + } + + @Override public void visitMaxs(int arg0, int arg1) { + handleQueue(); + super.visitMaxs(arg0, arg1); + } + + @Override public void visitLookupSwitchInsn(Label arg0, int[] arg1, Label[] arg2) { + handleQueue(); + super.visitLookupSwitchInsn(arg0, arg1, arg2); + } + + @Override public void visitMultiANewArrayInsn(String arg0, int arg1) { + handleQueue(); + super.visitMultiANewArrayInsn(arg0, arg1); + } + + @Override public void visitVarInsn(int arg0, int arg1) { + handleQueue(); + super.visitVarInsn(arg0, arg1); + } + + @Override public void visitTryCatchBlock(Label arg0, Label arg1, Label arg2, String arg3) { + handleQueue(); + super.visitTryCatchBlock(arg0, arg1, arg2, arg3); + } + + @Override public void visitTableSwitchInsn(int arg0, int arg1, Label arg2, Label... arg3) { + handleQueue(); + super.visitTableSwitchInsn(arg0, arg1, arg2, arg3); + } + + @Override public void visitTypeInsn(int arg0, String arg1) { + handleQueue(); + super.visitTypeInsn(arg0, arg1); + } } reader.accept(new ClassVisitor(Opcodes.ASM4, writer) { |