diff options
author | Reinier Zwitserloot <reinier@zwitserloot.com> | 2015-02-04 00:08:48 +0100 |
---|---|---|
committer | Reinier Zwitserloot <reinier@zwitserloot.com> | 2015-02-04 00:08:48 +0100 |
commit | 58a7914027e3373faa942aa4ce7df2d3ebfb9a20 (patch) | |
tree | cb0627b028f9753a7b4c94ec2373c07a4f3fd9f8 | |
parent | 74b38cd7d6806723145f6183273468996ea7dd57 (diff) | |
download | lombok-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.
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 |