mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-15 02:17:12 +00:00
Post Compiler now works, including the sneaky throws remover. Also added a lombok app for it. Not yet in eclipse, though
This commit is contained in:
1 parent
40466c3e2d
commit
57bb88a769
4 files changed
+222
-31
No files matched your search
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright © 2010 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package lombok.bytecode;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.core.DiagnosticsReceiver;
|
||||
import lombok.core.LombokApp;
|
||||
import lombok.core.PostCompiler;
|
||||
|
||||
import org.mangosdk.spi.ProviderFor;
|
||||
|
||||
import com.zwitserloot.cmdreader.CmdReader;
|
||||
import com.zwitserloot.cmdreader.Description;
|
||||
import com.zwitserloot.cmdreader.InvalidCommandLineException;
|
||||
import com.zwitserloot.cmdreader.Mandatory;
|
||||
import com.zwitserloot.cmdreader.Sequential;
|
||||
import com.zwitserloot.cmdreader.Shorthand;
|
||||
|
||||
@ProviderFor(LombokApp.class)
|
||||
public class PostCompilerApp implements LombokApp {
|
||||
@Override public List<String> getAppAliases() {
|
||||
return Arrays.asList("post", "postcompile");
|
||||
}
|
||||
|
||||
@Override public String getAppDescription() {
|
||||
return "Runs registered post compiler handlers to against existing class files, modifying them in the process.";
|
||||
}
|
||||
|
||||
@Override public String getAppName() {
|
||||
return "post-compile";
|
||||
}
|
||||
|
||||
public static class CmdArgs {
|
||||
@Sequential
|
||||
@Mandatory
|
||||
@Description("paths to class files to be converted. If a directory is named, all files (recursively) in that directory will be converted.")
|
||||
private List<String> classFiles = new ArrayList<String>();
|
||||
|
||||
@Shorthand("v")
|
||||
@Description("Prints lots of status information as the post compiler runs")
|
||||
boolean verbose = false;
|
||||
|
||||
@Shorthand({"h", "?"})
|
||||
@Description("Shows this help text")
|
||||
boolean help = false;
|
||||
}
|
||||
|
||||
@Override public int runApp(List<String> raw) throws Exception {
|
||||
CmdReader<CmdArgs> reader = CmdReader.of(CmdArgs.class);
|
||||
CmdArgs args;
|
||||
try {
|
||||
args = reader.make(raw.toArray(new String[0]));
|
||||
if (args.help) {
|
||||
System.out.println(reader.generateCommandLineHelp("java -jar lombok.jar post-compile"));
|
||||
return 0;
|
||||
}
|
||||
} catch (InvalidCommandLineException e) {
|
||||
System.err.println(e.getMessage());
|
||||
System.err.println(reader.generateCommandLineHelp("java -jar lombok.jar post-compile"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
List<File> filesToProcess = new ArrayList<File>();
|
||||
for (String f : args.classFiles) addFiles(filesToProcess, f);
|
||||
|
||||
int filesVisited = 0, filesTouched = 0;
|
||||
for (File file : filesToProcess) {
|
||||
if (!file.exists() || !file.isFile()) {
|
||||
System.out.printf("Cannot find file '%s'\n", file);
|
||||
continue;
|
||||
}
|
||||
filesVisited++;
|
||||
if (args.verbose) System.out.println("Processing " + file.getAbsolutePath());
|
||||
byte[] original = readFile(file);
|
||||
byte[] clone = original.clone();
|
||||
byte[] transformed = PostCompiler.applyTransformations(clone, file.toString(), DiagnosticsReceiver.CONSOLE);
|
||||
if (clone != transformed && !Arrays.equals(clone, transformed)) {
|
||||
filesTouched++;
|
||||
if (args.verbose) System.out.println("Rewriting " + file.getAbsolutePath());
|
||||
writeFile(file, transformed);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.verbose) {
|
||||
System.out.printf("Total files visited: %d total files changed: %d\n", filesVisited, filesTouched);
|
||||
}
|
||||
|
||||
return filesVisited == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
private void addFiles(List<File> filesToProcess, String f) {
|
||||
File file = new File(f);
|
||||
if (file.isDirectory()) {
|
||||
addRecursively(filesToProcess, file);
|
||||
} else {
|
||||
filesToProcess.add(file);
|
||||
}
|
||||
}
|
||||
|
||||
private void addRecursively(List<File> filesToProcess, File file) {
|
||||
for (File f : file.listFiles()) {
|
||||
if (f.isDirectory()) addRecursively(filesToProcess, f);
|
||||
else if (f.getName().endsWith(".class")) filesToProcess.add(f);
|
||||
}
|
||||
}
|
||||
|
||||
private static byte[] readFile(File file) throws IOException {
|
||||
byte[] buffer = new byte[1024];
|
||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
|
||||
FileInputStream fileInputStream = new FileInputStream(file);
|
||||
while (true) {
|
||||
int read = fileInputStream.read(buffer);
|
||||
if (read == -1) break;
|
||||
bytes.write(buffer, 0, read);
|
||||
}
|
||||
fileInputStream.close();
|
||||
return bytes.toByteArray();
|
||||
}
|
||||
|
||||
private static void writeFile(File file, byte[] transformed) throws IOException {
|
||||
FileOutputStream out = new FileOutputStream(file);
|
||||
out.write(transformed);
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,28 @@
|
||||
/*
|
||||
* Copyright © 2010 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package lombok.bytecode;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import lombok.core.DiagnosticsReceiver;
|
||||
import lombok.core.PostCompilerTransformation;
|
||||
|
||||
@@ -51,30 +74,33 @@ public class SneakyThrowsRemover implements PostCompilerTransformation {
|
||||
ClassReader reader = new ClassReader(fixedByteCode);
|
||||
ClassWriter writer = new FixedClassWriter(reader, ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
|
||||
|
||||
final AtomicBoolean changesMade = new AtomicBoolean();
|
||||
|
||||
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) {
|
||||
changesMade.set(true);
|
||||
super.visitInsn(Opcodes.ATHROW);
|
||||
} else {
|
||||
super.visitMethodInsn(opcode, owner, name, desc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
return changesMade.get() ? writer.toByteArray() : null;
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,7 @@
|
||||
package lombok.core;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public final class PostCompiler {
|
||||
@@ -49,17 +48,10 @@ public final class PostCompiler {
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
transformations = SpiLoadUtil.readAllFromIterator(SpiLoadUtil.findServices(PostCompilerTransformation.class, PostCompilerTransformation.class.getClassLoader()));
|
||||
} catch (IOException e) {
|
||||
transformations = Collections.emptyList();
|
||||
diagnostics.addWarning("Could not load post-compile transformers: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,24 @@
|
||||
/*
|
||||
* Copyright © 2010 Reinier Zwitserloot and Roel Spilker.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
package lombok.core;
|
||||
|
||||
public interface PostCompilerTransformation {
|
||||
|
||||
Reference in new issue
Block a user