diff options
author | Roel Spilker <r.spilker@gmail.com> | 2009-08-01 01:42:52 +0200 |
---|---|---|
committer | Roel Spilker <r.spilker@gmail.com> | 2009-08-01 01:42:52 +0200 |
commit | f2c837bb47771a7eba5ad5a885af162d8d133559 (patch) | |
tree | 23be7f4b58a82b3c573edcd0e927d55cb4c7a290 /src/lombok | |
parent | 0cfa9e99d99fc353d0c486e96cc53f5214ab031c (diff) | |
download | lombok-f2c837bb47771a7eba5ad5a885af162d8d133559.tar.gz lombok-f2c837bb47771a7eba5ad5a885af162d8d133559.tar.bz2 lombok-f2c837bb47771a7eba5ad5a885af162d8d133559.zip |
@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
Diffstat (limited to 'src/lombok')
-rw-r--r-- | src/lombok/eclipse/Eclipse.java | 31 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleGetter.java | 14 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/HandleSetter.java | 17 | ||||
-rw-r--r-- | src/lombok/eclipse/handlers/PKG.java | 12 | ||||
-rw-r--r-- | src/lombok/javac/handlers/HandleGetter.java | 3 | ||||
-rw-r--r-- | src/lombok/javac/handlers/HandleSetter.java | 8 | ||||
-rw-r--r-- | src/lombok/javac/handlers/PKG.java | 11 |
7 files changed, 71 insertions, 25 deletions
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<Getter> { 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<Getter> { } 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<Getter> { } 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<Getter> { 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<Setter> { 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<Setter> { 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<Annotation> result = new ArrayList<Annotation>(); 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<Getter> { List<JCExpression> throwsClauses = List.nil(); JCExpression annotationMethodDefaultValue = null; - return treeMaker.MethodDef(treeMaker.Modifiers(access, List.<JCAnnotation>nil()), methodName, methodType, + List<JCAnnotation> 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<Setter> { JCFieldAccess thisX = treeMaker.Select(treeMaker.Ident(field.toName("this")), fieldDecl.name); JCAssign assign = treeMaker.Assign(thisX, treeMaker.Ident(fieldDecl.name)); - List<JCStatement> statements; - JCAnnotation nonNull = findNonNullAnnotation(field); - if (nonNull == null) { + List<JCAnnotation> nonNulls = findNonNullAnnotations(field); + if (nonNulls.isEmpty()) { statements = List.<JCStatement>of(treeMaker.Exec(assign)); } else { @@ -137,7 +136,8 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> { 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<JCTypeParameter> 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<JCAnnotation> findNonNullAnnotations(Node fieldNode) { + List<JCAnnotation> 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; } } |