From 56150952c451f0d8c2018424191d4480ac5e8460 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Mon, 11 Mar 2013 22:04:27 +0100 Subject: Added @Log4j2 support. --- website/features/Log.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'website/features') diff --git a/website/features/Log.html b/website/features/Log.html index fb529426..2fb91956 100644 --- a/website/features/Log.html +++ b/website/features/Log.html @@ -16,9 +16,9 @@

Overview

NEW in lombok 0.10: You can annotate any class with a log annotation to let lombok generate a logger field.
- The logger is named log and field's type depends on which logger you have selected. + The logger is named log and the field's type depends on which logger you have selected.

- There are four choices available:
+ There are six choices available:

@CommonsLog
Creates private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
@@ -26,6 +26,8 @@
Creates private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
@Log4j
Creates private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);
+
@Log4j2
+
Creates private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);
@Slf4j
Creates private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);
@XSlf4j
-- cgit From cb9b907839aa0c72ffa41f8a13bfab5cb1341258 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Tue, 12 Mar 2013 01:29:15 +0100 Subject: In delombok, we mark the AST as changed if we remove an annotation; this fixes the issue where delombok would leave lombok annotations in the file if that annotation had no actual effect (such as @Getter on a field if there is an explicit getX method for that field). issue #443: delombok would screw up @SneakyThrows on methods or constructors with empty bodies. Now we generate warnings for this. --- .../eclipse/handlers/HandleSneakyThrows.java | 24 ++++++++++++++++++---- .../lombok/javac/handlers/HandleSneakyThrows.java | 19 +++++++++++++++-- .../lombok/javac/handlers/JavacHandlerUtil.java | 1 + website/features/SneakyThrows.html | 6 +++++- 4 files changed, 43 insertions(+), 7 deletions(-) (limited to 'website/features') diff --git a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java index b7c8a5d8..aa78ca3b 100644 --- a/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/eclipse/handlers/HandleSneakyThrows.java @@ -40,6 +40,8 @@ import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Argument; import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; import org.eclipse.jdt.internal.compiler.ast.Block; +import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; +import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.eclipse.jdt.internal.compiler.ast.MessageSend; @@ -147,7 +149,21 @@ public class HandleSneakyThrows extends EclipseAnnotationHandler { return; } - if (method.statements == null) return; + if (method.statements == null || method.statements.length == 0) { + boolean hasConstructorCall = false; + if (method instanceof ConstructorDeclaration) { + ExplicitConstructorCall constructorCall = ((ConstructorDeclaration) method).constructorCall; + hasConstructorCall = constructorCall != null && !constructorCall.isImplicitSuper() && !constructorCall.isImplicitThis(); + } + + if (hasConstructorCall) { + annotation.addWarning("Calls to sibling / super constructors are always excluded from @SneakyThrows; @SneakyThrows has been ignored because there is no other code in this constructor."); + } else { + annotation.addWarning("This method or constructor is empty; @SneakyThrows has been ignored."); + } + + return; + } Statement[] contents = method.statements; @@ -160,9 +176,9 @@ public class HandleSneakyThrows extends EclipseAnnotationHandler { } private Statement buildTryCatchBlock(Statement[] contents, DeclaredException exception, ASTNode source, AbstractMethodDeclaration method) { - int methodStart = method.bodyStart; - int methodEnd = method.bodyEnd; - long methodPosEnd = methodEnd << 32 | (methodEnd & 0xFFFFFFFFL); + int methodStart = method.bodyStart; + int methodEnd = method.bodyEnd; + long methodPosEnd = ((long) methodEnd) << 32 | (methodEnd & 0xFFFFFFFFL); TryStatement tryStatement = new TryStatement(); setGeneratedBy(tryStatement, source); diff --git a/src/core/lombok/javac/handlers/HandleSneakyThrows.java b/src/core/lombok/javac/handlers/HandleSneakyThrows.java index a5bd74e7..c2394fc8 100644 --- a/src/core/lombok/javac/handlers/HandleSneakyThrows.java +++ b/src/core/lombok/javac/handlers/HandleSneakyThrows.java @@ -84,13 +84,20 @@ public class HandleSneakyThrows extends JavacAnnotationHandler { return; } - if (method.body == null) return; - if (method.body.stats.isEmpty()) return; + if (method.body == null || method.body.stats.isEmpty()) { + generateEmptyBlockWarning(methodNode, annotation, false); + return; + } final JCStatement constructorCall = method.body.stats.get(0); final boolean isConstructorCall = isConstructorCall(constructorCall); List contents = isConstructorCall ? method.body.stats.tail : method.body.stats; + if (contents == null || contents.isEmpty()) { + generateEmptyBlockWarning(methodNode, annotation, true); + return; + } + for (String exception : exceptions) { contents = List.of(buildTryCatchBlock(methodNode, contents, exception, annotation.get())); } @@ -99,6 +106,14 @@ public class HandleSneakyThrows extends JavacAnnotationHandler { methodNode.rebuild(); } + private void generateEmptyBlockWarning(JavacNode methodNode, JavacNode annotation, boolean hasConstructorCall) { + if (hasConstructorCall) { + annotation.addWarning("Calls to sibling / super constructors are always excluded from @SneakyThrows; @SneakyThrows has been ignored because there is no other code in this constructor."); + } else { + annotation.addWarning("This method or constructor is empty; @SneakyThrows has been ignored."); + } + } + private boolean isConstructorCall(final JCStatement supect) { if (!(supect instanceof JCExpressionStatement)) return false; final JCExpression supectExpression = ((JCExpressionStatement) supect).expr; diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java index c2de5b05..e79dd5dc 100644 --- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java +++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java @@ -305,6 +305,7 @@ public class JavacHandlerUtil { return; } + parentNode.getAst().setChanged(); deleteImportFromCompilationUnit(annotation, annotationType.getName()); } diff --git a/website/features/SneakyThrows.html b/website/features/SneakyThrows.html index 0f04b7d9..808a7879 100644 --- a/website/features/SneakyThrows.html +++ b/website/features/SneakyThrows.html @@ -64,7 +64,11 @@ statement in a try/catch block with just e.printStackTrace() in the catch block. This is so spectacularly non-productive compared to just sneakily throwing the exception onwards, that Roel and Reinier feel more than justified in claiming that the checked exception system is far from perfect, and thus an opt-out mechanism is warranted. -

+

+ If you put @SneakyThrows on a constructor, any call to a sibling or super constructor is excluded from the @SneakyThrows treatment. This is a + java restriction we cannot work around: Calls to sibling/super constructors MUST be the first statement in the constructor; they cannot be placed inside try/catch blocks. +

+ @SneakyThrows on an empty method, or a constructor that is empty or only has a call to a sibling / super constructor results in no try/catch block and a warning.