aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2015-02-04 00:08:48 +0100
committerReinier Zwitserloot <reinier@zwitserloot.com>2015-02-04 00:08:48 +0100
commit58a7914027e3373faa942aa4ce7df2d3ebfb9a20 (patch)
treecb0627b028f9753a7b4c94ec2373c07a4f3fd9f8
parent74b38cd7d6806723145f6183273468996ea7dd57 (diff)
downloadlombok-58a7914027e3373faa942aa4ce7df2d3ebfb9a20.tar.gz
lombok-58a7914027e3373faa942aa4ce7df2d3ebfb9a20.tar.bz2
lombok-58a7914027e3373faa942aa4ce7df2d3ebfb9a20.zip
@UtilityClass handlers now more intelligent about inner types of implicitly static contexts (enums, interfaces, and annotation declarations). Also added tests to test for these.
-rw-r--r--src/core/lombok/eclipse/handlers/HandleUtilityClass.java16
-rw-r--r--src/core/lombok/javac/handlers/HandleUtilityClass.java22
-rw-r--r--src/utils/lombok/javac/TreeMirrorMaker.java14
-rw-r--r--test/transform/resource/after-delombok/UtilityClass.java22
-rw-r--r--test/transform/resource/after-delombok/UtilityClassErrors.java7
-rw-r--r--test/transform/resource/after-ecj/UtilityClass.java25
-rw-r--r--test/transform/resource/after-ecj/UtilityClassErrors.java16
-rw-r--r--test/transform/resource/before/UtilityClass.java17
-rw-r--r--test/transform/resource/before/UtilityClassErrors.java8
-rw-r--r--test/transform/resource/messages-delombok/UtilityClassErrors.java.messages1
-rw-r--r--test/transform/resource/messages-ecj/UtilityClassErrors.java.messages3
11 files changed, 126 insertions, 25 deletions
diff --git a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java
index 36a7dc9c..176ff2d8 100644
--- a/src/core/lombok/eclipse/handlers/HandleUtilityClass.java
+++ b/src/core/lombok/eclipse/handlers/HandleUtilityClass.java
@@ -83,8 +83,10 @@ public class HandleUtilityClass extends EclipseAnnotationHandler<UtilityClass> {
typeWalk = typeWalk.up();
switch (typeWalk.getKind()) {
case TYPE:
- if ((((TypeDeclaration) typeWalk.get()).modifiers & ClassFileConstants.AccStatic) != 0) continue;
+ if ((((TypeDeclaration) typeWalk.get()).modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0) continue;
if (typeWalk.up().getKind() == Kind.COMPILATION_UNIT) return true;
+ errorNode.addError("@UtilityClass automatically makes the class static, however, this class cannot be made static.");
+ return false;
case COMPILATION_UNIT:
return true;
default:
@@ -101,7 +103,15 @@ public class HandleUtilityClass extends EclipseAnnotationHandler<UtilityClass> {
classDecl.modifiers |= ClassFileConstants.AccFinal;
- if (typeNode.up().getKind() != Kind.COMPILATION_UNIT) classDecl.modifiers |= ClassFileConstants.AccStatic;
+ boolean markStatic = true;
+
+ if (typeNode.up().getKind() == Kind.COMPILATION_UNIT) markStatic = false;
+ if (markStatic && typeNode.up().getKind() == Kind.TYPE) {
+ TypeDeclaration typeDecl = (TypeDeclaration) typeNode.up().get();
+ if ((typeDecl.modifiers & ClassFileConstants.AccInterface) != 0) markStatic = false;
+ }
+
+ if (markStatic) classDecl.modifiers |= ClassFileConstants.AccStatic;
for (EclipseNode element : typeNode.down()) {
if (element.getKind() == Kind.FIELD) {
@@ -155,7 +165,7 @@ public class HandleUtilityClass extends EclipseAnnotationHandler<UtilityClass> {
AllocationExpression exception = new AllocationExpression();
setGeneratedBy(exception, source);
- long[] ps = new long[3];
+ long[] ps = new long[JAVA_LANG_UNSUPPORTED_OPERATION_EXCEPTION.length];
Arrays.fill(ps, p);
exception.type = new QualifiedTypeReference(JAVA_LANG_UNSUPPORTED_OPERATION_EXCEPTION, ps);
setGeneratedBy(exception.type, source);
diff --git a/src/core/lombok/javac/handlers/HandleUtilityClass.java b/src/core/lombok/javac/handlers/HandleUtilityClass.java
index 9a37653e..a4f8cb45 100644
--- a/src/core/lombok/javac/handlers/HandleUtilityClass.java
+++ b/src/core/lombok/javac/handlers/HandleUtilityClass.java
@@ -44,7 +44,6 @@ import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
-import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
/**
@@ -79,8 +78,11 @@ public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> {
typeWalk = typeWalk.up();
switch (typeWalk.getKind()) {
case TYPE:
- if ((((JCClassDecl) typeWalk.get()).mods.flags & Flags.STATIC) != 0) continue;
+ JCClassDecl typeDef = (JCClassDecl) typeWalk.get();
+ if ((typeDef.mods.flags & (Flags.STATIC | Flags.ANNOTATION | Flags.ENUM | Flags.INTERFACE)) != 0) continue;
if (typeWalk.up().getKind() == Kind.COMPILATION_UNIT) return true;
+ errorNode.addError("@UtilityClass automatically makes the class static, however, this class cannot be made static.");
+ return false;
case COMPILATION_UNIT:
return true;
default:
@@ -97,7 +99,15 @@ public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> {
classDecl.mods.flags |= Flags.FINAL;
- if (typeNode.up().getKind() != Kind.COMPILATION_UNIT) classDecl.mods.flags |= Flags.STATIC;
+ boolean markStatic = true;
+
+ if (typeNode.up().getKind() == Kind.COMPILATION_UNIT) markStatic = false;
+ if (markStatic && typeNode.up().getKind() == Kind.TYPE) {
+ JCClassDecl typeDecl = (JCClassDecl) typeNode.up().get();
+ if ((typeDecl.mods.flags & Flags.INTERFACE) != 0) markStatic = false;
+ }
+
+ if (markStatic) classDecl.mods.flags |= Flags.STATIC;
for (JavacNode element : typeNode.down()) {
if (element.getKind() == Kind.FIELD) {
@@ -135,13 +145,11 @@ public class HandleUtilityClass extends JavacAnnotationHandler<UtilityClass> {
}
private List<JCStatement> createThrowStatement(JavacNode typeNode, JavacTreeMaker maker) {
- ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
- JCExpression exceptionType = genTypeRef(typeNode, "java.lang.UnsupportedOperationException");
+ JCExpression exceptionType = genJavaLangTypeRef(typeNode, "UnsupportedOperationException");
List<JCExpression> jceBlank = List.nil();
JCExpression message = maker.Literal("This is a utility class and cannot be instantiated");
JCExpression exceptionInstance = maker.NewClass(null, jceBlank, exceptionType, List.of(message), null);
JCStatement throwStatement = maker.Throw(exceptionInstance);
- statements.add(throwStatement);
- return statements.toList();
+ return List.of(throwStatement);
}
}
diff --git a/src/utils/lombok/javac/TreeMirrorMaker.java b/src/utils/lombok/javac/TreeMirrorMaker.java
index 093839d7..918a3242 100644
--- a/src/utils/lombok/javac/TreeMirrorMaker.java
+++ b/src/utils/lombok/javac/TreeMirrorMaker.java
@@ -29,13 +29,9 @@ import java.util.Map;
import static lombok.javac.Javac.*;
import lombok.javac.JavacTreeMaker.TypeTag;
-import com.sun.source.tree.ClassTree;
import com.sun.source.tree.LabeledStatementTree;
-import com.sun.source.tree.NewClassTree;
import com.sun.source.tree.VariableTree;
import com.sun.tools.javac.tree.JCTree;
-import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.tree.JCTree.JCNewClass;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.tree.TreeCopier;
import com.sun.tools.javac.util.Context;
@@ -123,14 +119,4 @@ public class TreeMirrorMaker extends TreeCopier<Void> {
@Override public JCTree visitLabeledStatement(LabeledStatementTree node, Void p) {
return node.getStatement().accept(this, p);
}
-
- @Override public JCTree visitNewClass(NewClassTree node, Void p) {
- JCNewClass copy = (JCNewClass) super.visitNewClass(node, p);
- return copy;
- }
-
- @Override public JCTree visitClass(ClassTree node, Void p) {
- JCClassDecl copy = (JCClassDecl) super.visitClass(node, p);
- return copy;
- }
}
diff --git a/test/transform/resource/after-delombok/UtilityClass.java b/test/transform/resource/after-delombok/UtilityClass.java
index f9fe02a0..eb7eef09 100644
--- a/test/transform/resource/after-delombok/UtilityClass.java
+++ b/test/transform/resource/after-delombok/UtilityClass.java
@@ -23,4 +23,26 @@ class UtilityInner {
}
}
}
+ enum UtilityInsideEnum {
+ FOO,
+ BAR;
+ static final class InsideEnum {
+ static int member;
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
+ private InsideEnum() {
+ throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
+ }
+ }
+ }
+ interface UtilityInsideInterface {
+ final class InsideInterface {
+ static int member;
+ @java.lang.SuppressWarnings("all")
+ @javax.annotation.Generated("lombok")
+ private InsideInterface() {
+ throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
+ }
+ }
+ }
} \ No newline at end of file
diff --git a/test/transform/resource/after-delombok/UtilityClassErrors.java b/test/transform/resource/after-delombok/UtilityClassErrors.java
index b19b4e72..9626461a 100644
--- a/test/transform/resource/after-delombok/UtilityClassErrors.java
+++ b/test/transform/resource/after-delombok/UtilityClassErrors.java
@@ -9,4 +9,11 @@ final class UtilityClassErrors1 {
}
enum UtilityClassErrors2 {
;
+}
+class UtilityClassErrors3 {
+ class NonStaticInner {
+ class ThisShouldFail {
+ private String member;
+ }
+ }
} \ No newline at end of file
diff --git a/test/transform/resource/after-ecj/UtilityClass.java b/test/transform/resource/after-ecj/UtilityClass.java
index c3e06fbc..e8db6a21 100644
--- a/test/transform/resource/after-ecj/UtilityClass.java
+++ b/test/transform/resource/after-ecj/UtilityClass.java
@@ -27,6 +27,31 @@ class UtilityInner {
super();
}
}
+ enum UtilityInsideEnum {
+ static final @lombok.experimental.UtilityClass class InsideEnum {
+ static int member;
+ private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") InsideEnum() {
+ super();
+ throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
+ }
+ }
+ FOO(),
+ BAR(),
+ <clinit>() {
+ }
+ UtilityInsideEnum() {
+ super();
+ }
+ }
+ interface UtilityInsideInterface {
+ final @lombok.experimental.UtilityClass class InsideInterface {
+ static int member;
+ private @java.lang.SuppressWarnings("all") @javax.annotation.Generated("lombok") InsideInterface() {
+ super();
+ throw new java.lang.UnsupportedOperationException("This is a utility class and cannot be instantiated");
+ }
+ }
+ }
UtilityInner() {
super();
}
diff --git a/test/transform/resource/after-ecj/UtilityClassErrors.java b/test/transform/resource/after-ecj/UtilityClassErrors.java
index 03206592..26b331a1 100644
--- a/test/transform/resource/after-ecj/UtilityClassErrors.java
+++ b/test/transform/resource/after-ecj/UtilityClassErrors.java
@@ -18,3 +18,19 @@ final @lombok.experimental.UtilityClass class UtilityClassErrors1 {
super();
}
}
+class UtilityClassErrors3 {
+ class NonStaticInner {
+ @lombok.experimental.UtilityClass class ThisShouldFail {
+ private String member;
+ ThisShouldFail() {
+ super();
+ }
+ }
+ NonStaticInner() {
+ super();
+ }
+ }
+ UtilityClassErrors3() {
+ super();
+ }
+}
diff --git a/test/transform/resource/before/UtilityClass.java b/test/transform/resource/before/UtilityClass.java
index ccfa43e1..0f9875f0 100644
--- a/test/transform/resource/before/UtilityClass.java
+++ b/test/transform/resource/before/UtilityClass.java
@@ -10,6 +10,7 @@ class UtilityClass {
private String innerInnerMember;
}
}
+
class UtilityInner {
static class InnerInner {
@lombok.experimental.UtilityClass
@@ -17,4 +18,20 @@ class UtilityInner {
int member;
}
}
+
+ enum UtilityInsideEnum {
+ FOO, BAR;
+
+ @lombok.experimental.UtilityClass
+ class InsideEnum {
+ int member;
+ }
+ }
+
+ interface UtilityInsideInterface {
+ @lombok.experimental.UtilityClass
+ class InsideInterface {
+ int member;
+ }
+ }
}
diff --git a/test/transform/resource/before/UtilityClassErrors.java b/test/transform/resource/before/UtilityClassErrors.java
index 5f72274b..d750e2bd 100644
--- a/test/transform/resource/before/UtilityClassErrors.java
+++ b/test/transform/resource/before/UtilityClassErrors.java
@@ -11,4 +11,12 @@ class UtilityClassErrors1 {
}
@lombok.experimental.UtilityClass
enum UtilityClassErrors2 {
+}
+class UtilityClassErrors3 {
+ class NonStaticInner {
+ @lombok.experimental.UtilityClass
+ class ThisShouldFail {
+ private String member;
+ }
+ }
} \ No newline at end of file
diff --git a/test/transform/resource/messages-delombok/UtilityClassErrors.java.messages b/test/transform/resource/messages-delombok/UtilityClassErrors.java.messages
index 230ba04f..4afa12ec 100644
--- a/test/transform/resource/messages-delombok/UtilityClassErrors.java.messages
+++ b/test/transform/resource/messages-delombok/UtilityClassErrors.java.messages
@@ -1,3 +1,4 @@
4 @UtilityClasses cannot have declared constructors.
7 @UtilityClass cannot be placed on a method local or anonymous inner class, or any class nested in such a class.
12 @UtilityClass is only supported on a class (can't be an interface, enum, or annotation).
+17 @UtilityClass automatically makes the class static, however, this class cannot be made static. \ No newline at end of file
diff --git a/test/transform/resource/messages-ecj/UtilityClassErrors.java.messages b/test/transform/resource/messages-ecj/UtilityClassErrors.java.messages
index c80a18dc..15c9b10f 100644
--- a/test/transform/resource/messages-ecj/UtilityClassErrors.java.messages
+++ b/test/transform/resource/messages-ecj/UtilityClassErrors.java.messages
@@ -1,3 +1,4 @@
4 @UtilityClasses cannot have declared constructors.
7 @UtilityClass cannot be placed on a method local or anonymous inner class, or any class nested in such a class.
-12 @UtilityClass is only supported on a class (can't be an interface, enum, or annotation) \ No newline at end of file
+12 @UtilityClass is only supported on a class (can't be an interface, enum, or annotation)
+17 @UtilityClass automatically makes the class static, however, this class cannot be made static. \ No newline at end of file