mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 12:15:00 +00:00
@UtilityClass handlers now more intelligent about inner types of implicitly static contexts (enums, interfaces, and annotation declarations). Also added tests to test for these.
This commit is contained in:
1 parent
74b38cd7d6
commit
58a7914027
11 files changed
+126
-25
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,11 @@ final class UtilityClassErrors1 {
|
||||
}
|
||||
enum UtilityClassErrors2 {
|
||||
;
|
||||
}
|
||||
class UtilityClassErrors3 {
|
||||
class NonStaticInner {
|
||||
class ThisShouldFail {
|
||||
private String member;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,4 +11,12 @@ class UtilityClassErrors1 {
|
||||
}
|
||||
@lombok.experimental.UtilityClass
|
||||
enum UtilityClassErrors2 {
|
||||
}
|
||||
class UtilityClassErrors3 {
|
||||
class NonStaticInner {
|
||||
@lombok.experimental.UtilityClass
|
||||
class ThisShouldFail {
|
||||
private String member;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
@@ -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)
|
||||
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.
|
||||
Reference in new issue
Block a user