From 0cfa9e99d99fc353d0c486e96cc53f5214ab031c Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Fri, 31 Jul 2009 18:44:13 +0200 Subject: Added support for @NonNull in the @Setter annotation --- src/lombok/javac/handlers/HandleSetter.java | 18 +++++++++++++++++- src/lombok/javac/handlers/PKG.java | 25 ++++++++++++++++++++----- 2 files changed, 37 insertions(+), 6 deletions(-) (limited to 'src/lombok/javac/handlers') diff --git a/src/lombok/javac/handlers/HandleSetter.java b/src/lombok/javac/handlers/HandleSetter.java index d11b4250..b4720387 100644 --- a/src/lombok/javac/handlers/HandleSetter.java +++ b/src/lombok/javac/handlers/HandleSetter.java @@ -34,6 +34,8 @@ import lombok.javac.JavacAST.Node; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; @@ -119,7 +121,21 @@ public class HandleSetter implements JavacAnnotationHandler { JCFieldAccess thisX = treeMaker.Select(treeMaker.Ident(field.toName("this")), fieldDecl.name); JCAssign assign = treeMaker.Assign(thisX, treeMaker.Ident(fieldDecl.name)); - JCBlock methodBody = treeMaker.Block(0, List.of(treeMaker.Exec(assign))); + + List statements; + JCAnnotation nonNull = findNonNullAnnotation(field); + if (nonNull == null) { + statements = List.of(treeMaker.Exec(assign)); + } + else { + JCExpression npe = chainDots(treeMaker, field, "java", "lang", "NullPointerException"); + JCTree exception = treeMaker.NewClass(null, List.nil(), npe, List.of(treeMaker.Literal(fieldDecl.name.toString())), null); + JCStatement throwStatement = treeMaker.Throw(exception); + JCStatement nullCheck = treeMaker.If(treeMaker.Binary(JCTree.EQ, treeMaker.Ident(fieldDecl.name), treeMaker.Literal(TypeTags.BOT, null)), throwStatement, null); + statements = List.of(nullCheck, treeMaker.Exec(assign)); + } + + JCBlock methodBody = treeMaker.Block(0, statements); Name methodName = field.toName(toSetterName(fieldDecl)); JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0), fieldDecl.name, fieldDecl.vartype, null); JCExpression methodType = treeMaker.Type(field.getSymbolTable().voidType); diff --git a/src/lombok/javac/handlers/PKG.java b/src/lombok/javac/handlers/PKG.java index 205a2b6e..bc5b691c 100644 --- a/src/lombok/javac/handlers/PKG.java +++ b/src/lombok/javac/handlers/PKG.java @@ -23,20 +23,22 @@ package lombok.javac.handlers; import java.lang.reflect.Modifier; +import lombok.AccessLevel; +import lombok.core.TransformationsUtil; +import lombok.core.AST.Kind; +import lombok.javac.JavacAST; +import lombok.javac.JavacAST.Node; + import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; +import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; -import lombok.AccessLevel; -import lombok.core.TransformationsUtil; -import lombok.core.AST.Kind; -import lombok.javac.JavacAST; - /** * Container for static utility methods relevant to this package. */ @@ -251,4 +253,17 @@ class PKG { return e; } + + static JCAnnotation findNonNullAnnotation(Node fieldNode) { + for ( Node child : fieldNode.down() ) { + if ( child.getKind() == Kind.ANNOTATION ) { + JCAnnotation annotation = (JCAnnotation) child.get(); + String name = annotation.annotationType.toString(); + if (name.equals("NonNull") || name.endsWith(".NonNull")) { + return annotation; + } + } + } + return null; + } } -- cgit From f2c837bb47771a7eba5ad5a885af162d8d133559 Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 1 Aug 2009 01:42:52 +0200 Subject: @Setter will copy all NotNull and NonNull (case-insensitive) annotations to the parameter @Getter will copy them to the getter method Added @NonNull to lombok to support null-checks in the setter --- src/lombok/eclipse/Eclipse.java | 31 +++++++++++++++++++++++++++ src/lombok/eclipse/handlers/HandleGetter.java | 14 +++++++----- src/lombok/eclipse/handlers/HandleSetter.java | 17 +++++++++------ src/lombok/eclipse/handlers/PKG.java | 12 +++++++---- src/lombok/javac/handlers/HandleGetter.java | 3 ++- src/lombok/javac/handlers/HandleSetter.java | 8 +++---- src/lombok/javac/handlers/PKG.java | 11 ++++++---- 7 files changed, 71 insertions(+), 25 deletions(-) (limited to 'src/lombok/javac/handlers') diff --git a/src/lombok/eclipse/Eclipse.java b/src/lombok/eclipse/Eclipse.java index b1860984..33164ab5 100644 --- a/src/lombok/eclipse/Eclipse.java +++ b/src/lombok/eclipse/Eclipse.java @@ -49,11 +49,14 @@ import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.Literal; +import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation; import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; +import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference; import org.eclipse.jdt.internal.compiler.ast.TypeParameter; @@ -251,6 +254,34 @@ public class Eclipse { return ref; } + public static Annotation[] copyAnnotations(Annotation[] annotations) { + if (annotations == null) return null; + Annotation[] outs = new Annotation[annotations.length]; + int idx = 0; + for ( Annotation annotation : annotations ) { + outs[idx++] = copyAnnotation(annotation); + } + return outs; + } + + public static Annotation copyAnnotation(Annotation annotation) { + if (annotation instanceof MarkerAnnotation) { + return new MarkerAnnotation(copyType(annotation.type), annotation.sourceStart); + } + + if (annotation instanceof SingleMemberAnnotation) { + SingleMemberAnnotation result = new SingleMemberAnnotation(copyType(annotation.type), annotation.sourceStart); + result.memberValue = ((SingleMemberAnnotation)annotation).memberValue; + } + + if (annotation instanceof NormalAnnotation) { + NormalAnnotation result = new NormalAnnotation(copyType(annotation.type), annotation.sourceStart); + result.memberValuePairs = ((NormalAnnotation)annotation).memberValuePairs; + } + + return annotation; + } + /** * Checks if the provided annotation type is likely to be the intended type for the given annotation node. * diff --git a/src/lombok/eclipse/handlers/HandleGetter.java b/src/lombok/eclipse/handlers/HandleGetter.java index 982ccc97..6a4c5ceb 100644 --- a/src/lombok/eclipse/handlers/HandleGetter.java +++ b/src/lombok/eclipse/handlers/HandleGetter.java @@ -27,7 +27,7 @@ import lombok.Getter; import lombok.core.AnnotationValues; import lombok.core.TransformationsUtil; import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; +import static lombok.eclipse.Eclipse.*; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseAST.Node; @@ -64,7 +64,7 @@ public class HandleGetter implements EclipseAnnotationHandler { public void generateGetterForField(Node fieldNode, ASTNode pos) { for ( Node child : fieldNode.down() ) { if ( child.getKind() == Kind.ANNOTATION ) { - if ( Eclipse.annotationTypeMatches(Getter.class, child) ) { + if ( annotationTypeMatches(Getter.class, child) ) { //The annotation will make it happen, so we can skip it. return; } @@ -87,7 +87,7 @@ public class HandleGetter implements EclipseAnnotationHandler { } FieldDeclaration field = (FieldDeclaration) fieldNode.get(); - TypeReference fieldType = Eclipse.copyType(field.type); + TypeReference fieldType = copyType(field.type); String fieldName = new String(field.name); boolean isBoolean = nameEquals(fieldType.getTypeName(), "boolean") && fieldType.dimensions() == 0; String getterName = TransformationsUtil.toGetterName(fieldName, isBoolean); @@ -113,6 +113,10 @@ public class HandleGetter implements EclipseAnnotationHandler { } MethodDeclaration method = generateGetter((TypeDeclaration) fieldNode.up().get(), field, getterName, modifier, pos); + Annotation[] nonNulls = findNonNullAnnotations(field); + if (nonNulls.length != 0) { + method.annotations = copyAnnotations(nonNulls); + } injectMethod(fieldNode.up(), method); @@ -123,14 +127,14 @@ public class HandleGetter implements EclipseAnnotationHandler { int modifier, ASTNode pos) { MethodDeclaration method = new MethodDeclaration(parent.compilationResult); method.modifiers = modifier; - method.returnType = Eclipse.copyType(field.type); + method.returnType = copyType(field.type); method.annotations = null; method.arguments = null; method.selector = name.toCharArray(); method.binding = null; method.thrownExceptions = null; method.typeParameters = null; - method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; + method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; Expression fieldExpression = new SingleNameReference(field.name, (field.declarationSourceStart << 32) | field.declarationSourceEnd); Statement returnStatement = new ReturnStatement(fieldExpression, field.sourceStart, field.sourceEnd); method.bodyStart = method.declarationSourceStart = method.sourceStart = pos.sourceStart; diff --git a/src/lombok/eclipse/handlers/HandleSetter.java b/src/lombok/eclipse/handlers/HandleSetter.java index 567a7fbe..f3e61e3e 100644 --- a/src/lombok/eclipse/handlers/HandleSetter.java +++ b/src/lombok/eclipse/handlers/HandleSetter.java @@ -22,12 +22,13 @@ package lombok.eclipse.handlers; import static lombok.eclipse.handlers.PKG.*; + import lombok.AccessLevel; import lombok.Setter; import lombok.core.AnnotationValues; import lombok.core.TransformationsUtil; import lombok.core.AST.Kind; -import lombok.eclipse.Eclipse; +import static lombok.eclipse.Eclipse.*; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseAST.Node; @@ -77,7 +78,7 @@ public class HandleSetter implements EclipseAnnotationHandler { public void generateSetterForField(Node fieldNode, ASTNode pos) { for ( Node child : fieldNode.down() ) { if ( child.getKind() == Kind.ANNOTATION ) { - if ( Eclipse.annotationTypeMatches(Setter.class, child) ) { + if ( annotationTypeMatches(Setter.class, child) ) { //The annotation will make it happen, so we can skip it. return; } @@ -134,27 +135,29 @@ public class HandleSetter implements EclipseAnnotationHandler { method.modifiers = modifier; method.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0); method.annotations = null; - Argument param = new Argument(field.name, pos, Eclipse.copyType(field.type), 0); + Argument param = new Argument(field.name, pos, copyType(field.type), 0); method.arguments = new Argument[] { param }; method.selector = name.toCharArray(); method.binding = null; method.thrownExceptions = null; method.typeParameters = null; method.scope = parent.scope == null ? null : new MethodScope(parent.scope, method, false); - method.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; + method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG; FieldReference thisX = new FieldReference(field.name, pos); thisX.receiver = new ThisReference(ast.sourceStart, ast.sourceEnd); Assignment assignment = new Assignment(thisX, new SingleNameReference(field.name, pos), (int)pos); method.bodyStart = method.declarationSourceStart = method.sourceStart = ast.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = ast.sourceEnd; - Annotation nonNull = findNonNullannotation(field); - if (nonNull == null) { + Annotation[] nonNulls = findNonNullAnnotations(field); + if (nonNulls.length == 0) { method.statements = new Statement[] { assignment }; } else { + param.annotations = copyAnnotations(nonNulls); + AllocationExpression exception = new AllocationExpression(); - exception.type = new QualifiedTypeReference(Eclipse.fromQualifiedName("java.lang.NullPointerException"), new long[]{0, 0, 0}); + exception.type = new QualifiedTypeReference(fromQualifiedName("java.lang.NullPointerException"), new long[]{0, 0, 0}); exception.arguments = new Expression[] { new StringLiteral(field.name, 0, field.name.length - 1, 0)}; ThrowStatement throwStatement = new ThrowStatement(exception, 0, 0); diff --git a/src/lombok/eclipse/handlers/PKG.java b/src/lombok/eclipse/handlers/PKG.java index db38e3df..6d524e8c 100644 --- a/src/lombok/eclipse/handlers/PKG.java +++ b/src/lombok/eclipse/handlers/PKG.java @@ -22,6 +22,8 @@ package lombok.eclipse.handlers; import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.List; import lombok.AccessLevel; import lombok.core.AST.Kind; @@ -215,16 +217,18 @@ class PKG { type.add(method, Kind.METHOD).recursiveSetHandled(); } - static Annotation findNonNullannotation(FieldDeclaration field) { + static Annotation[] findNonNullAnnotations(FieldDeclaration field) { + List result = new ArrayList(); for (Annotation annotation : field.annotations) { TypeReference typeRef = annotation.type; if ( typeRef != null && typeRef.getTypeName()!= null ) { char[][] typeName = typeRef.getTypeName(); - if (new String(typeName[typeName.length - 1]).equals("NonNull")) { - return annotation; + String suspect = new String(typeName[typeName.length - 1]); + if (suspect.equalsIgnoreCase("NonNull") || suspect.equalsIgnoreCase("NotNull")) { + result.add(annotation); } } } - return null; + return result.toArray(new Annotation[0]); } } diff --git a/src/lombok/javac/handlers/HandleGetter.java b/src/lombok/javac/handlers/HandleGetter.java index 3d3227e4..370a405b 100644 --- a/src/lombok/javac/handlers/HandleGetter.java +++ b/src/lombok/javac/handlers/HandleGetter.java @@ -128,7 +128,8 @@ public class HandleGetter implements JavacAnnotationHandler { List throwsClauses = List.nil(); JCExpression annotationMethodDefaultValue = null; - return treeMaker.MethodDef(treeMaker.Modifiers(access, List.nil()), methodName, methodType, + List annotations = findNonNullAnnotations(field); + return treeMaker.MethodDef(treeMaker.Modifiers(access, annotations), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue); } } diff --git a/src/lombok/javac/handlers/HandleSetter.java b/src/lombok/javac/handlers/HandleSetter.java index b4720387..2f41e716 100644 --- a/src/lombok/javac/handlers/HandleSetter.java +++ b/src/lombok/javac/handlers/HandleSetter.java @@ -121,10 +121,9 @@ public class HandleSetter implements JavacAnnotationHandler { JCFieldAccess thisX = treeMaker.Select(treeMaker.Ident(field.toName("this")), fieldDecl.name); JCAssign assign = treeMaker.Assign(thisX, treeMaker.Ident(fieldDecl.name)); - List statements; - JCAnnotation nonNull = findNonNullAnnotation(field); - if (nonNull == null) { + List nonNulls = findNonNullAnnotations(field); + if (nonNulls.isEmpty()) { statements = List.of(treeMaker.Exec(assign)); } else { @@ -137,7 +136,8 @@ public class HandleSetter implements JavacAnnotationHandler { JCBlock methodBody = treeMaker.Block(0, statements); Name methodName = field.toName(toSetterName(fieldDecl)); - JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0), fieldDecl.name, fieldDecl.vartype, null); + + JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0, nonNulls), fieldDecl.name, fieldDecl.vartype, null); JCExpression methodType = treeMaker.Type(field.getSymbolTable().voidType); List methodGenericParams = List.nil(); diff --git a/src/lombok/javac/handlers/PKG.java b/src/lombok/javac/handlers/PKG.java index bc5b691c..ea794296 100644 --- a/src/lombok/javac/handlers/PKG.java +++ b/src/lombok/javac/handlers/PKG.java @@ -254,16 +254,19 @@ class PKG { return e; } - static JCAnnotation findNonNullAnnotation(Node fieldNode) { + static List findNonNullAnnotations(Node fieldNode) { + List result = List.nil(); for ( Node child : fieldNode.down() ) { if ( child.getKind() == Kind.ANNOTATION ) { JCAnnotation annotation = (JCAnnotation) child.get(); String name = annotation.annotationType.toString(); - if (name.equals("NonNull") || name.endsWith(".NonNull")) { - return annotation; + int idx = name.lastIndexOf("."); + String suspect = idx == -1 ? name : name.substring(idx + 1); + if (suspect.equalsIgnoreCase("NonNull") || suspect.equalsIgnoreCase("NotNull")) { + result = result.append(annotation); } } } - return null; + return result; } } -- cgit From c4d97b008afc85e495784929c312c6828aefde1d Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 1 Aug 2009 02:10:29 +0200 Subject: Moved the check to see if a variable is null to the PKG utility classes --- src/lombok/eclipse/handlers/HandleSetter.java | 32 +++++++++------------------ src/lombok/eclipse/handlers/PKG.java | 25 +++++++++++++++++++++ src/lombok/javac/handlers/HandleSetter.java | 15 ++++++------- src/lombok/javac/handlers/PKG.java | 11 +++++++++ 4 files changed, 53 insertions(+), 30 deletions(-) (limited to 'src/lombok/javac/handlers') diff --git a/src/lombok/eclipse/handlers/HandleSetter.java b/src/lombok/eclipse/handlers/HandleSetter.java index f3e61e3e..d850e549 100644 --- a/src/lombok/eclipse/handlers/HandleSetter.java +++ b/src/lombok/eclipse/handlers/HandleSetter.java @@ -21,36 +21,33 @@ */ package lombok.eclipse.handlers; -import static lombok.eclipse.handlers.PKG.*; - +import static lombok.eclipse.Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; +import static lombok.eclipse.Eclipse.annotationTypeMatches; +import static lombok.eclipse.Eclipse.copyAnnotations; +import static lombok.eclipse.Eclipse.copyType; +import static lombok.eclipse.handlers.PKG.findNonNullAnnotations; +import static lombok.eclipse.handlers.PKG.generateNullCheck; +import static lombok.eclipse.handlers.PKG.injectMethod; +import static lombok.eclipse.handlers.PKG.methodExists; +import static lombok.eclipse.handlers.PKG.toModifier; import lombok.AccessLevel; import lombok.Setter; import lombok.core.AnnotationValues; import lombok.core.TransformationsUtil; import lombok.core.AST.Kind; -import static lombok.eclipse.Eclipse.*; import lombok.eclipse.EclipseAnnotationHandler; import lombok.eclipse.EclipseAST.Node; import org.eclipse.jdt.internal.compiler.ast.ASTNode; -import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.Argument; import org.eclipse.jdt.internal.compiler.ast.Assignment; -import org.eclipse.jdt.internal.compiler.ast.EqualExpression; -import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; import org.eclipse.jdt.internal.compiler.ast.FieldReference; -import org.eclipse.jdt.internal.compiler.ast.IfStatement; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.NullLiteral; -import org.eclipse.jdt.internal.compiler.ast.OperatorIds; -import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; import org.eclipse.jdt.internal.compiler.ast.Statement; -import org.eclipse.jdt.internal.compiler.ast.StringLiteral; import org.eclipse.jdt.internal.compiler.ast.ThisReference; -import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; @@ -155,16 +152,7 @@ public class HandleSetter implements EclipseAnnotationHandler { } else { param.annotations = copyAnnotations(nonNulls); - - AllocationExpression exception = new AllocationExpression(); - exception.type = new QualifiedTypeReference(fromQualifiedName("java.lang.NullPointerException"), new long[]{0, 0, 0}); - exception.arguments = new Expression[] { new StringLiteral(field.name, 0, field.name.length - 1, 0)}; - ThrowStatement throwStatement = new ThrowStatement(exception, 0, 0); - - IfStatement nullCheck = new IfStatement(new EqualExpression(new SingleNameReference(field.name, 0), - new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL), throwStatement, 0, 0); - - method.statements = new Statement[] { nullCheck, assignment }; + method.statements = new Statement[] { generateNullCheck(field), assignment }; } return method; } diff --git a/src/lombok/eclipse/handlers/PKG.java b/src/lombok/eclipse/handlers/PKG.java index 6d524e8c..2eae1edf 100644 --- a/src/lombok/eclipse/handlers/PKG.java +++ b/src/lombok/eclipse/handlers/PKG.java @@ -21,6 +21,8 @@ */ package lombok.eclipse.handlers; +import static lombok.eclipse.Eclipse.fromQualifiedName; + import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; @@ -31,9 +33,21 @@ import lombok.eclipse.EclipseAST; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; +import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration; +import org.eclipse.jdt.internal.compiler.ast.AllocationExpression; import org.eclipse.jdt.internal.compiler.ast.Annotation; import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; +import org.eclipse.jdt.internal.compiler.ast.EqualExpression; +import org.eclipse.jdt.internal.compiler.ast.Expression; import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; +import org.eclipse.jdt.internal.compiler.ast.IfStatement; +import org.eclipse.jdt.internal.compiler.ast.NullLiteral; +import org.eclipse.jdt.internal.compiler.ast.OperatorIds; +import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference; +import org.eclipse.jdt.internal.compiler.ast.SingleNameReference; +import org.eclipse.jdt.internal.compiler.ast.Statement; +import org.eclipse.jdt.internal.compiler.ast.StringLiteral; +import org.eclipse.jdt.internal.compiler.ast.ThrowStatement; import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; import org.eclipse.jdt.internal.compiler.ast.TypeReference; @@ -231,4 +245,15 @@ class PKG { } return result.toArray(new Annotation[0]); } + + + static Statement generateNullCheck(AbstractVariableDeclaration variable) { + AllocationExpression exception = new AllocationExpression(); + exception.type = new QualifiedTypeReference(fromQualifiedName("java.lang.NullPointerException"), new long[]{0, 0, 0}); + exception.arguments = new Expression[] { new StringLiteral(variable.name, 0, variable.name.length - 1, 0)}; + ThrowStatement throwStatement = new ThrowStatement(exception, 0, 0); + + return new IfStatement(new EqualExpression(new SingleNameReference(variable.name, 0), + new NullLiteral(0, 0), OperatorIds.EQUAL_EQUAL), throwStatement, 0, 0); + } } diff --git a/src/lombok/javac/handlers/HandleSetter.java b/src/lombok/javac/handlers/HandleSetter.java index 2f41e716..9fb995e4 100644 --- a/src/lombok/javac/handlers/HandleSetter.java +++ b/src/lombok/javac/handlers/HandleSetter.java @@ -21,7 +21,12 @@ */ package lombok.javac.handlers; -import static lombok.javac.handlers.PKG.*; +import static lombok.javac.handlers.PKG.findNonNullAnnotations; +import static lombok.javac.handlers.PKG.generateNullCheck; +import static lombok.javac.handlers.PKG.injectMethod; +import static lombok.javac.handlers.PKG.methodExists; +import static lombok.javac.handlers.PKG.toJavacModifier; +import static lombok.javac.handlers.PKG.toSetterName; import lombok.AccessLevel; import lombok.Setter; import lombok.core.AnnotationValues; @@ -34,8 +39,6 @@ import lombok.javac.JavacAST.Node; import org.mangosdk.spi.ProviderFor; import com.sun.tools.javac.code.Flags; -import com.sun.tools.javac.code.TypeTags; -import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; @@ -127,11 +130,7 @@ public class HandleSetter implements JavacAnnotationHandler { statements = List.of(treeMaker.Exec(assign)); } else { - JCExpression npe = chainDots(treeMaker, field, "java", "lang", "NullPointerException"); - JCTree exception = treeMaker.NewClass(null, List.nil(), npe, List.of(treeMaker.Literal(fieldDecl.name.toString())), null); - JCStatement throwStatement = treeMaker.Throw(exception); - JCStatement nullCheck = treeMaker.If(treeMaker.Binary(JCTree.EQ, treeMaker.Ident(fieldDecl.name), treeMaker.Literal(TypeTags.BOT, null)), throwStatement, null); - statements = List.of(nullCheck, treeMaker.Exec(assign)); + statements = List.of(generateNullCheck(treeMaker, field), treeMaker.Exec(assign)); } JCBlock methodBody = treeMaker.Block(0, statements); diff --git a/src/lombok/javac/handlers/PKG.java b/src/lombok/javac/handlers/PKG.java index ea794296..006e92a3 100644 --- a/src/lombok/javac/handlers/PKG.java +++ b/src/lombok/javac/handlers/PKG.java @@ -30,14 +30,17 @@ import lombok.javac.JavacAST; import lombok.javac.JavacAST.Node; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.TreeMaker; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; +import com.sun.tools.javac.tree.JCTree.JCStatement; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.List; +import com.sun.tools.javac.util.Name; /** * Container for static utility methods relevant to this package. @@ -269,4 +272,12 @@ class PKG { } return result; } + + static JCStatement generateNullCheck(TreeMaker treeMaker, JavacAST.Node variable) { + Name fieldName = ((JCVariableDecl) variable.get()).name; + JCExpression npe = chainDots(treeMaker, variable, "java", "lang", "NullPointerException"); + JCTree exception = treeMaker.NewClass(null, List.nil(), npe, List.of(treeMaker.Literal(fieldName.toString())), null); + JCStatement throwStatement = treeMaker.Throw(exception); + return treeMaker.If(treeMaker.Binary(JCTree.EQ, treeMaker.Ident(fieldName), treeMaker.Literal(TypeTags.BOT, null)), throwStatement, null); + } } -- cgit From dd593a3af08d9fd300ecd3a11a3551507aa35b6f Mon Sep 17 00:00:00 2001 From: Roel Spilker Date: Sat, 1 Aug 2009 02:38:56 +0200 Subject: The constructors will now also add non-final fields if they have a NonNull annotation The constructor will test for null-values The constructor and static constructor will copy the NonNull annotations from the fields --- src/lombok/eclipse/handlers/HandleData.java | 22 +++++++++++++++++++--- src/lombok/javac/handlers/HandleData.java | 17 +++++++++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) (limited to 'src/lombok/javac/handlers') diff --git a/src/lombok/eclipse/handlers/HandleData.java b/src/lombok/eclipse/handlers/HandleData.java index f1623e39..0296d5e4 100644 --- a/src/lombok/eclipse/handlers/HandleData.java +++ b/src/lombok/eclipse/handlers/HandleData.java @@ -89,7 +89,8 @@ public class HandleData implements EclipseAnnotationHandler { //Skip static fields. if ( (fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0 ) continue; boolean isFinal = (fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0; - if ( isFinal && fieldDecl.initialization == null ) nodesForConstructor.add(child); + boolean isNonNull = findNonNullAnnotations(fieldDecl).length != 0; + if ( (isFinal || isNonNull) && fieldDecl.initialization == null ) nodesForConstructor.add(child); new HandleGetter().generateGetterForField(child, annotationNode.get()); if ( !isFinal ) new HandleSetter().generateSetterForField(child, annotationNode.get()); } @@ -139,18 +140,27 @@ public class HandleData implements EclipseAnnotationHandler { List args = new ArrayList(); List assigns = new ArrayList(); + List nullChecks = new ArrayList(); for ( Node fieldNode : fields ) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); FieldReference thisX = new FieldReference(("this." + new String(field.name)).toCharArray(), p); thisX.receiver = new ThisReference((int)(p >> 32), (int)p); thisX.token = field.name; + assigns.add(new Assignment(thisX, new SingleNameReference(field.name, p), (int)p)); long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd; - args.add(new Argument(field.name, fieldPos, copyType(field.type), 0)); + Argument argument = new Argument(field.name, fieldPos, copyType(field.type), 0); + Annotation[] nonNulls = findNonNullAnnotations(field); + if (nonNulls.length != 0) { + nullChecks.add(generateNullCheck(field)); + argument.annotations = copyAnnotations(nonNulls); + } + args.add(argument); } - constructor.statements = assigns.isEmpty() ? null : assigns.toArray(new Statement[assigns.size()]); + nullChecks.addAll(assigns); + constructor.statements = nullChecks.isEmpty() ? null : nullChecks.toArray(new Statement[nullChecks.size()]); constructor.arguments = args.isEmpty() ? null : args.toArray(new Argument[args.size()]); return constructor; } @@ -188,6 +198,12 @@ public class HandleData implements EclipseAnnotationHandler { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd; assigns.add(new SingleNameReference(field.name, fieldPos)); + + Argument argument = new Argument(field.name, fieldPos, copyType(field.type), 0); + Annotation[] nonNulls = findNonNullAnnotations(field); + if (nonNulls.length != 0) { + argument.annotations = copyAnnotations(nonNulls); + } args.add(new Argument(field.name, fieldPos, copyType(field.type), 0)); } diff --git a/src/lombok/javac/handlers/HandleData.java b/src/lombok/javac/handlers/HandleData.java index 003b8808..e65462d8 100644 --- a/src/lombok/javac/handlers/HandleData.java +++ b/src/lombok/javac/handlers/HandleData.java @@ -79,7 +79,8 @@ public class HandleData implements JavacAnnotationHandler { if ( (fieldFlags & Flags.STATIC) != 0 ) continue; if ( (fieldFlags & Flags.TRANSIENT) == 0 ) nodesForEquality = nodesForEquality.append(child); boolean isFinal = (fieldFlags & Flags.FINAL) != 0; - if ( isFinal && fieldDecl.init == null ) nodesForConstructor = nodesForConstructor.append(child); + boolean isNonNull = !findNonNullAnnotations(child).isEmpty(); + if ( (isFinal || isNonNull) && fieldDecl.init == null ) nodesForConstructor = nodesForConstructor.append(child); new HandleGetter().generateGetterForField(child, annotationNode.get()); if ( !isFinal ) new HandleSetter().generateSetterForField(child, annotationNode.get()); } @@ -106,21 +107,29 @@ public class HandleData implements JavacAnnotationHandler { TreeMaker maker = typeNode.getTreeMaker(); JCClassDecl type = (JCClassDecl) typeNode.get(); + List nullChecks = List.nil(); List assigns = List.nil(); List params = List.nil(); for ( Node fieldNode : fields ) { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); - JCVariableDecl param = maker.VarDef(maker.Modifiers(0), field.name, field.vartype, null); + + List nonNulls = findNonNullAnnotations(fieldNode); + JCVariableDecl param = maker.VarDef(maker.Modifiers(0, nonNulls), field.name, field.vartype, null); + params = params.append(param); JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), field.name); JCAssign assign = maker.Assign(thisX, maker.Ident(field.name)); assigns = assigns.append(maker.Exec(assign)); + + if (!nonNulls.isEmpty()) { + nullChecks = nullChecks.append(generateNullCheck(maker, fieldNode)); + } } JCModifiers mods = maker.Modifiers(isPublic ? Modifier.PUBLIC : Modifier.PRIVATE); return maker.MethodDef(mods, typeNode.toName(""), - null, type.typarams, params, List.nil(), maker.Block(0L, assigns), null); + null, type.typarams, params, List.nil(), maker.Block(0L, nullChecks.appendList(assigns)), null); } private JCMethodDecl createStaticConstructor(String name, Node typeNode, List fields) { @@ -160,7 +169,7 @@ public class HandleData implements JavacAnnotationHandler { for ( JCExpression arg : typeApply.arguments ) tArgs = tArgs.append(arg); pType = maker.TypeApply(typeApply.clazz, tArgs); } else pType = field.vartype; - JCVariableDecl param = maker.VarDef(maker.Modifiers(0), field.name, pType, null); + JCVariableDecl param = maker.VarDef(maker.Modifiers(0, findNonNullAnnotations(fieldNode)), field.name, pType, null); params = params.append(param); args = args.append(maker.Ident(field.name)); } -- cgit From fe0da3f53f1e88b704e21463cc5fea3d998e394a Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Thu, 27 Aug 2009 23:05:14 +0200 Subject: Now @Nullable is also copied over. --- src/lombok/eclipse/Eclipse.java | 15 ++++++++++++--- src/lombok/eclipse/handlers/HandleData.java | 19 +++++++++---------- .../eclipse/handlers/HandleEqualsAndHashCode.java | 8 ++++---- src/lombok/eclipse/handlers/HandleGetter.java | 7 ++++--- src/lombok/eclipse/handlers/HandleSetter.java | 20 +++++++------------- src/lombok/eclipse/handlers/PKG.java | 9 ++++++--- src/lombok/javac/handlers/HandleData.java | 12 ++++++++---- .../javac/handlers/HandleEqualsAndHashCode.java | 8 ++++---- src/lombok/javac/handlers/HandleGetter.java | 5 +++-- src/lombok/javac/handlers/HandleSetter.java | 12 ++++-------- src/lombok/javac/handlers/PKG.java | 8 ++++++-- 11 files changed, 67 insertions(+), 56 deletions(-) (limited to 'src/lombok/javac/handlers') diff --git a/src/lombok/eclipse/Eclipse.java b/src/lombok/eclipse/Eclipse.java index 33164ab5..017affa1 100644 --- a/src/lombok/eclipse/Eclipse.java +++ b/src/lombok/eclipse/Eclipse.java @@ -255,10 +255,19 @@ public class Eclipse { } public static Annotation[] copyAnnotations(Annotation[] annotations) { - if (annotations == null) return null; - Annotation[] outs = new Annotation[annotations.length]; + return copyAnnotations(annotations, null); + } + + public static Annotation[] copyAnnotations(Annotation[] annotations1, Annotation[] annotations2) { + if (annotations1 == null && annotations2 == null) return null; + if (annotations1 == null) annotations1 = new Annotation[0]; + if (annotations2 == null) annotations2 = new Annotation[0]; + Annotation[] outs = new Annotation[annotations1.length + annotations2.length]; int idx = 0; - for ( Annotation annotation : annotations ) { + for ( Annotation annotation : annotations1 ) { + outs[idx++] = copyAnnotation(annotation); + } + for ( Annotation annotation : annotations2 ) { outs[idx++] = copyAnnotation(annotation); } return outs; diff --git a/src/lombok/eclipse/handlers/HandleData.java b/src/lombok/eclipse/handlers/HandleData.java index 0296d5e4..38e3135d 100644 --- a/src/lombok/eclipse/handlers/HandleData.java +++ b/src/lombok/eclipse/handlers/HandleData.java @@ -89,7 +89,7 @@ public class HandleData implements EclipseAnnotationHandler { //Skip static fields. if ( (fieldDecl.modifiers & ClassFileConstants.AccStatic) != 0 ) continue; boolean isFinal = (fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0; - boolean isNonNull = findNonNullAnnotations(fieldDecl).length != 0; + boolean isNonNull = findAnnotations(fieldDecl, NON_NULL_PATTERN).length != 0; if ( (isFinal || isNonNull) && fieldDecl.initialization == null ) nodesForConstructor.add(child); new HandleGetter().generateGetterForField(child, annotationNode.get()); if ( !isFinal ) new HandleSetter().generateSetterForField(child, annotationNode.get()); @@ -151,11 +151,11 @@ public class HandleData implements EclipseAnnotationHandler { assigns.add(new Assignment(thisX, new SingleNameReference(field.name, p), (int)p)); long fieldPos = (((long)field.sourceStart) << 32) | field.sourceEnd; Argument argument = new Argument(field.name, fieldPos, copyType(field.type), 0); - Annotation[] nonNulls = findNonNullAnnotations(field); - if (nonNulls.length != 0) { - nullChecks.add(generateNullCheck(field)); - argument.annotations = copyAnnotations(nonNulls); - } + Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); + Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); + if (nonNulls.length != 0) nullChecks.add(generateNullCheck(field)); + Annotation[] copiedAnnotations = copyAnnotations(nonNulls, nullables); + if (copiedAnnotations.length != 0) argument.annotations = copiedAnnotations; args.add(argument); } @@ -200,10 +200,9 @@ public class HandleData implements EclipseAnnotationHandler { assigns.add(new SingleNameReference(field.name, fieldPos)); Argument argument = new Argument(field.name, fieldPos, copyType(field.type), 0); - Annotation[] nonNulls = findNonNullAnnotations(field); - if (nonNulls.length != 0) { - argument.annotations = copyAnnotations(nonNulls); - } + Annotation[] copiedAnnotations = copyAnnotations( + findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN)); + if (copiedAnnotations.length != 0) argument.annotations = copiedAnnotations; args.add(new Argument(field.name, fieldPos, copyType(field.type), 0)); } diff --git a/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index d8e1562e..f837d4a6 100644 --- a/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -153,19 +153,19 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler { } MethodDeclaration method = generateGetter((TypeDeclaration) fieldNode.up().get(), field, getterName, modifier, pos); - Annotation[] nonNulls = findNonNullAnnotations(field); - if (nonNulls.length != 0) { - method.annotations = copyAnnotations(nonNulls); + Annotation[] copiedAnnotations = copyAnnotations( + findAnnotations(field, NON_NULL_PATTERN), findAnnotations(field, NULLABLE_PATTERN)); + if (copiedAnnotations.length != 0) { + method.annotations = copiedAnnotations; } injectMethod(fieldNode.up(), method); diff --git a/src/lombok/eclipse/handlers/HandleSetter.java b/src/lombok/eclipse/handlers/HandleSetter.java index d850e549..6214c86d 100644 --- a/src/lombok/eclipse/handlers/HandleSetter.java +++ b/src/lombok/eclipse/handlers/HandleSetter.java @@ -21,15 +21,8 @@ */ package lombok.eclipse.handlers; -import static lombok.eclipse.Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG; -import static lombok.eclipse.Eclipse.annotationTypeMatches; -import static lombok.eclipse.Eclipse.copyAnnotations; -import static lombok.eclipse.Eclipse.copyType; -import static lombok.eclipse.handlers.PKG.findNonNullAnnotations; -import static lombok.eclipse.handlers.PKG.generateNullCheck; -import static lombok.eclipse.handlers.PKG.injectMethod; -import static lombok.eclipse.handlers.PKG.methodExists; -import static lombok.eclipse.handlers.PKG.toModifier; +import static lombok.eclipse.Eclipse.*; +import static lombok.eclipse.handlers.PKG.*; import lombok.AccessLevel; import lombok.Setter; import lombok.core.AnnotationValues; @@ -146,14 +139,15 @@ public class HandleSetter implements EclipseAnnotationHandler { method.bodyStart = method.declarationSourceStart = method.sourceStart = ast.sourceStart; method.bodyEnd = method.declarationSourceEnd = method.sourceEnd = ast.sourceEnd; - Annotation[] nonNulls = findNonNullAnnotations(field); + Annotation[] nonNulls = findAnnotations(field, NON_NULL_PATTERN); + Annotation[] nullables = findAnnotations(field, NULLABLE_PATTERN); if (nonNulls.length == 0) { method.statements = new Statement[] { assignment }; - } - else { - param.annotations = copyAnnotations(nonNulls); + } else { method.statements = new Statement[] { generateNullCheck(field), assignment }; } + Annotation[] copiedAnnotations = copyAnnotations(nonNulls, nullables); + if (copiedAnnotations.length != 0) param.annotations = copiedAnnotations; return method; } } diff --git a/src/lombok/eclipse/handlers/PKG.java b/src/lombok/eclipse/handlers/PKG.java index 2eae1edf..17096b70 100644 --- a/src/lombok/eclipse/handlers/PKG.java +++ b/src/lombok/eclipse/handlers/PKG.java @@ -26,6 +26,7 @@ import static lombok.eclipse.Eclipse.fromQualifiedName; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.List; +import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.core.AST.Kind; @@ -231,14 +232,17 @@ class PKG { type.add(method, Kind.METHOD).recursiveSetHandled(); } - static Annotation[] findNonNullAnnotations(FieldDeclaration field) { + static final Pattern NON_NULL_PATTERN = Pattern.compile("^no[tn]null$", Pattern.CASE_INSENSITIVE); + static final Pattern NULLABLE_PATTERN = Pattern.compile("^nullable$", Pattern.CASE_INSENSITIVE); + + static Annotation[] findAnnotations(FieldDeclaration field, Pattern namePattern) { List result = new ArrayList(); for (Annotation annotation : field.annotations) { TypeReference typeRef = annotation.type; if ( typeRef != null && typeRef.getTypeName()!= null ) { char[][] typeName = typeRef.getTypeName(); String suspect = new String(typeName[typeName.length - 1]); - if (suspect.equalsIgnoreCase("NonNull") || suspect.equalsIgnoreCase("NotNull")) { + if ( namePattern.matcher(suspect).matches() ) { result.add(annotation); } } @@ -246,7 +250,6 @@ class PKG { return result.toArray(new Annotation[0]); } - static Statement generateNullCheck(AbstractVariableDeclaration variable) { AllocationExpression exception = new AllocationExpression(); exception.type = new QualifiedTypeReference(fromQualifiedName("java.lang.NullPointerException"), new long[]{0, 0, 0}); diff --git a/src/lombok/javac/handlers/HandleData.java b/src/lombok/javac/handlers/HandleData.java index e65462d8..648ff91e 100644 --- a/src/lombok/javac/handlers/HandleData.java +++ b/src/lombok/javac/handlers/HandleData.java @@ -79,7 +79,7 @@ public class HandleData implements JavacAnnotationHandler { if ( (fieldFlags & Flags.STATIC) != 0 ) continue; if ( (fieldFlags & Flags.TRANSIENT) == 0 ) nodesForEquality = nodesForEquality.append(child); boolean isFinal = (fieldFlags & Flags.FINAL) != 0; - boolean isNonNull = !findNonNullAnnotations(child).isEmpty(); + boolean isNonNull = !findAnnotations(child, NON_NULL_PATTERN).isEmpty(); if ( (isFinal || isNonNull) && fieldDecl.init == null ) nodesForConstructor = nodesForConstructor.append(child); new HandleGetter().generateGetterForField(child, annotationNode.get()); if ( !isFinal ) new HandleSetter().generateSetterForField(child, annotationNode.get()); @@ -114,8 +114,9 @@ public class HandleData implements JavacAnnotationHandler { for ( Node fieldNode : fields ) { JCVariableDecl field = (JCVariableDecl) fieldNode.get(); - List nonNulls = findNonNullAnnotations(fieldNode); - JCVariableDecl param = maker.VarDef(maker.Modifiers(0, nonNulls), field.name, field.vartype, null); + List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); + List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); + JCVariableDecl param = maker.VarDef(maker.Modifiers(0, nonNulls.appendList(nullables)), field.name, field.vartype, null); params = params.append(param); JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), field.name); @@ -169,7 +170,10 @@ public class HandleData implements JavacAnnotationHandler { for ( JCExpression arg : typeApply.arguments ) tArgs = tArgs.append(arg); pType = maker.TypeApply(typeApply.clazz, tArgs); } else pType = field.vartype; - JCVariableDecl param = maker.VarDef(maker.Modifiers(0, findNonNullAnnotations(fieldNode)), field.name, pType, null); + + List nonNulls = findAnnotations(fieldNode, NON_NULL_PATTERN); + List nullables = findAnnotations(fieldNode, NULLABLE_PATTERN); + JCVariableDecl param = maker.VarDef(maker.Modifiers(0, nonNulls.appendList(nullables)), field.name, pType, null); params = params.append(param); args = args.append(maker.Ident(field.name)); } diff --git a/src/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/lombok/javac/handlers/HandleEqualsAndHashCode.java index 1a1158eb..e3e7c1ac 100644 --- a/src/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -119,20 +119,20 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler { List throwsClauses = List.nil(); JCExpression annotationMethodDefaultValue = null; - List annotations = findNonNullAnnotations(field); - return treeMaker.MethodDef(treeMaker.Modifiers(access, annotations), methodName, methodType, + List nonNulls = findAnnotations(field, NON_NULL_PATTERN); + List nullables = findAnnotations(field, NULLABLE_PATTERN); + return treeMaker.MethodDef(treeMaker.Modifiers(access, nonNulls.appendList(nullables)), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue); } } diff --git a/src/lombok/javac/handlers/HandleSetter.java b/src/lombok/javac/handlers/HandleSetter.java index 9fb995e4..c10e731c 100644 --- a/src/lombok/javac/handlers/HandleSetter.java +++ b/src/lombok/javac/handlers/HandleSetter.java @@ -21,12 +21,7 @@ */ package lombok.javac.handlers; -import static lombok.javac.handlers.PKG.findNonNullAnnotations; -import static lombok.javac.handlers.PKG.generateNullCheck; -import static lombok.javac.handlers.PKG.injectMethod; -import static lombok.javac.handlers.PKG.methodExists; -import static lombok.javac.handlers.PKG.toJavacModifier; -import static lombok.javac.handlers.PKG.toSetterName; +import static lombok.javac.handlers.PKG.*; import lombok.AccessLevel; import lombok.Setter; import lombok.core.AnnotationValues; @@ -125,7 +120,8 @@ public class HandleSetter implements JavacAnnotationHandler { JCAssign assign = treeMaker.Assign(thisX, treeMaker.Ident(fieldDecl.name)); List statements; - List nonNulls = findNonNullAnnotations(field); + List nonNulls = findAnnotations(field, NON_NULL_PATTERN); + List nullables = findAnnotations(field, NULLABLE_PATTERN); if (nonNulls.isEmpty()) { statements = List.of(treeMaker.Exec(assign)); } @@ -136,7 +132,7 @@ public class HandleSetter implements JavacAnnotationHandler { JCBlock methodBody = treeMaker.Block(0, statements); Name methodName = field.toName(toSetterName(fieldDecl)); - JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0, nonNulls), fieldDecl.name, fieldDecl.vartype, null); + JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(0, nonNulls.appendList(nullables)), fieldDecl.name, fieldDecl.vartype, null); JCExpression methodType = treeMaker.Type(field.getSymbolTable().voidType); List methodGenericParams = List.nil(); diff --git a/src/lombok/javac/handlers/PKG.java b/src/lombok/javac/handlers/PKG.java index 006e92a3..42cfed13 100644 --- a/src/lombok/javac/handlers/PKG.java +++ b/src/lombok/javac/handlers/PKG.java @@ -22,6 +22,7 @@ package lombok.javac.handlers; import java.lang.reflect.Modifier; +import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.core.TransformationsUtil; @@ -257,7 +258,10 @@ class PKG { return e; } - static List findNonNullAnnotations(Node fieldNode) { + static final Pattern NON_NULL_PATTERN = Pattern.compile("^no[tn]null$", Pattern.CASE_INSENSITIVE); + static final Pattern NULLABLE_PATTERN = Pattern.compile("^nullable$", Pattern.CASE_INSENSITIVE); + + static List findAnnotations(Node fieldNode, Pattern namePattern) { List result = List.nil(); for ( Node child : fieldNode.down() ) { if ( child.getKind() == Kind.ANNOTATION ) { @@ -265,7 +269,7 @@ class PKG { String name = annotation.annotationType.toString(); int idx = name.lastIndexOf("."); String suspect = idx == -1 ? name : name.substring(idx + 1); - if (suspect.equalsIgnoreCase("NonNull") || suspect.equalsIgnoreCase("NotNull")) { + if (namePattern.matcher(suspect).matches()) { result = result.append(annotation); } } -- cgit