diff options
author | Roel Spilker <r.spilker@gmail.com> | 2010-11-10 01:44:04 +0100 |
---|---|---|
committer | Roel Spilker <r.spilker@gmail.com> | 2010-11-10 01:44:04 +0100 |
commit | fe7f0db2fce7b4c80853b9aed100908ff1f55f40 (patch) | |
tree | 41f7c7a289237153307402b7ebe25e372254ae40 /src/core/lombok/eclipse | |
parent | 46d471e9c3dc32b03c34804df1819739a4dffc50 (diff) | |
download | lombok-fe7f0db2fce7b4c80853b9aed100908ff1f55f40.tar.gz lombok-fe7f0db2fce7b4c80853b9aed100908ff1f55f40.tar.bz2 lombok-fe7f0db2fce7b4c80853b9aed100908ff1f55f40.zip |
From now on it is possible to specify annotations to be placed on the method
or the parameter of the generated getter/setter methods.
Diffstat (limited to 'src/core/lombok/eclipse')
-rw-r--r-- | src/core/lombok/eclipse/Eclipse.java | 29 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java | 42 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleConstructor.java | 6 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleGetter.java | 21 | ||||
-rw-r--r-- | src/core/lombok/eclipse/handlers/HandleSetter.java | 32 |
5 files changed, 90 insertions, 40 deletions
diff --git a/src/core/lombok/eclipse/Eclipse.java b/src/core/lombok/eclipse/Eclipse.java index f5b80552..8354215b 100644 --- a/src/core/lombok/eclipse/Eclipse.java +++ b/src/core/lombok/eclipse/Eclipse.java @@ -452,23 +452,22 @@ public class Eclipse { } - public static Annotation[] copyAnnotations(Annotation[] annotations, ASTNode source) { - return copyAnnotations(annotations, null, source); - } + private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; - public static Annotation[] copyAnnotations(Annotation[] annotations1, Annotation[] annotations2, ASTNode source) { - 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 : annotations1) { - outs[idx++] = copyAnnotation(annotation, source); - } - for (Annotation annotation : annotations2) { - outs[idx++] = copyAnnotation(annotation, source); + public static Annotation[] copyAnnotations(ASTNode source, Annotation[]... allAnnotations) { + boolean allNull = true; + + List<Annotation> result = new ArrayList<Annotation>(); + for (Annotation[] annotations : allAnnotations) { + if (annotations != null) { + allNull = false; + for (Annotation annotation : annotations) { + result.add(copyAnnotation(annotation, source)); + } + } } - return outs; + if (allNull) return null; + return result.toArray(EMPTY_ANNOTATION_ARRAY); } public static Annotation copyAnnotation(Annotation annotation, ASTNode source) { diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java index 019ae637..7aa12b01 100644 --- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java +++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java @@ -32,8 +32,8 @@ import java.util.regex.Pattern; import lombok.AccessLevel; import lombok.Data; import lombok.Getter; -import lombok.core.AST.Kind; import lombok.core.AnnotationValues; +import lombok.core.AST.Kind; import lombok.core.handlers.TransformationsUtil; import lombok.eclipse.Eclipse; import lombok.eclipse.EclipseNode; @@ -43,6 +43,7 @@ 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.ArrayInitializer; import org.eclipse.jdt.internal.compiler.ast.Clinit; import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration; import org.eclipse.jdt.internal.compiler.ast.EqualExpression; @@ -51,9 +52,11 @@ 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.MarkerAnnotation; +import org.eclipse.jdt.internal.compiler.ast.MemberValuePair; import org.eclipse.jdt.internal.compiler.ast.MessageSend; import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration; import org.eclipse.jdt.internal.compiler.ast.NameReference; +import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation; import org.eclipse.jdt.internal.compiler.ast.NullLiteral; import org.eclipse.jdt.internal.compiler.ast.OperatorIds; import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference; @@ -610,4 +613,41 @@ public class EclipseHandlerUtil { return problematic; } + + private static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; + static Annotation[] getAndRemoveAnnotationParameter(Annotation annotation, String annotationName) { + + List<Annotation> result = new ArrayList<Annotation>(); + if (annotation instanceof NormalAnnotation) { + NormalAnnotation normalAnnotation = (NormalAnnotation)annotation; + MemberValuePair[] memberValuePairs = normalAnnotation.memberValuePairs; + List<MemberValuePair> pairs = new ArrayList<MemberValuePair>(); + if (memberValuePairs != null) for (MemberValuePair memberValuePair : memberValuePairs) { + if (annotationName.equals(new String(memberValuePair.name))) { + Expression value = memberValuePair.value; + if (value instanceof ArrayInitializer) { + ArrayInitializer array = (ArrayInitializer) value; + for(Expression expression : array.expressions) { + if (expression instanceof Annotation) { + result.add((Annotation)expression); + } + } + } + else if (value instanceof Annotation) { + result.add((Annotation)value); + } + continue; + } + pairs.add(memberValuePair); + } + + if (!result.isEmpty()) { + normalAnnotation.memberValuePairs = pairs.isEmpty() ? null : pairs.toArray(new MemberValuePair[0]); + return result.toArray(EMPTY_ANNOTATION_ARRAY); + } + } + + return EMPTY_ANNOTATION_ARRAY; + } + } diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java index 91733839..826d4c1c 100644 --- a/src/core/lombok/eclipse/handlers/HandleConstructor.java +++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java @@ -247,7 +247,7 @@ public class HandleConstructor { Statement nullCheck = generateNullCheck(field, source); if (nullCheck != null) nullChecks.add(nullCheck); } - Annotation[] copiedAnnotations = copyAnnotations(nonNulls, nullables, source); + Annotation[] copiedAnnotations = copyAnnotations(source, nonNulls, nullables); if (copiedAnnotations.length != 0) parameter.annotations = copiedAnnotations; params.add(parameter); } @@ -316,9 +316,7 @@ public class HandleConstructor { Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL); Eclipse.setGeneratedBy(parameter, source); - Annotation[] copiedAnnotations = copyAnnotations( - findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), - findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN), source); + Annotation[] copiedAnnotations = copyAnnotations(source, findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN)); if (copiedAnnotations.length != 0) parameter.annotations = copiedAnnotations; params.add(new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL)); } diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java index 1a2a10ac..38a6b468 100644 --- a/src/core/lombok/eclipse/handlers/HandleGetter.java +++ b/src/core/lombok/eclipse/handlers/HandleGetter.java @@ -76,7 +76,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { } for (EclipseNode field : typeNode.down()) { - if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, pos.get(), level); + if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, pos.get(), level, null); } return true; } @@ -103,7 +103,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { * If not, the getter is still generated if it isn't already there, though there will not * be a warning if its already there. The default access level is used. */ - public void generateGetterForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level) { + public void generateGetterForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, Annotation[] onMethod) { for (EclipseNode child : fieldNode.down()) { if (child.getKind() == Kind.ANNOTATION) { if (annotationTypeMatches(Getter.class, child)) { @@ -113,7 +113,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { } } - createGetterForField(level, fieldNode, fieldNode, pos, false); + createGetterForField(level, fieldNode, fieldNode, pos, false, onMethod); } public boolean handle(AnnotationValues<Getter> annotation, Annotation ast, EclipseNode annotationNode) { @@ -122,24 +122,27 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { if (level == AccessLevel.NONE) return true; if (node == null) return false; + + Annotation[] onMethod = getAndRemoveAnnotationParameter(ast, "onMethod"); if (node.getKind() == Kind.FIELD) { - return createGetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true); + return createGetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, onMethod); } if (node.getKind() == Kind.TYPE) { + if (onMethod != null && onMethod.length != 0) annotationNode.addError("'onMethod' is not supported for @Getter on a type."); return generateGetterForType(node, annotationNode, level, false); } return false; } - private boolean createGetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists) { + private boolean createGetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod) { for (EclipseNode fieldNode : fieldNodes) { - createGetterForField(level, fieldNode, errorNode, source, whineIfExists); + createGetterForField(level, fieldNode, errorNode, source, whineIfExists, onMethod); } return true; } private boolean createGetterForField(AccessLevel level, - EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists) { + EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod) { if (fieldNode.getKind() != Kind.FIELD) { errorNode.addError("@Getter is only supported on a class or a field."); return true; @@ -172,9 +175,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> { } MethodDeclaration method = generateGetter((TypeDeclaration) fieldNode.up().get(), fieldNode, getterName, modifier, source); - Annotation[] copiedAnnotations = copyAnnotations( - findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), - findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN), source); + Annotation[] copiedAnnotations = copyAnnotations(source, findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN), findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN), onMethod); if (copiedAnnotations.length != 0) { method.annotations = copiedAnnotations; } diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java index 7c4aaabb..48e688fd 100644 --- a/src/core/lombok/eclipse/handlers/HandleSetter.java +++ b/src/core/lombok/eclipse/handlers/HandleSetter.java @@ -57,6 +57,7 @@ import org.mangosdk.spi.ProviderFor; */ @ProviderFor(EclipseAnnotationHandler.class) public class HandleSetter implements EclipseAnnotationHandler<Setter> { + private static final Annotation[] EMPTY_ANNOTATIONS_ARRAY = new Annotation[0]; public boolean generateSetterForType(EclipseNode typeNode, EclipseNode pos, AccessLevel level, boolean checkForTypeLevelSetter) { if (checkForTypeLevelSetter) { if (typeNode != null) for (EclipseNode child : typeNode.down()) { @@ -90,7 +91,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { //Skip final fields. if ((fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0) continue; - generateSetterForField(field, pos.get(), level); + generateSetterForField(field, pos.get(), level, EMPTY_ANNOTATIONS_ARRAY, EMPTY_ANNOTATIONS_ARRAY); } return true; } @@ -107,7 +108,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { * If not, the setter is still generated if it isn't already there, though there will not * be a warning if its already there. The default access level is used. */ - public void generateSetterForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level) { + public void generateSetterForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, Annotation[] onMethod , Annotation[] onParam) { for (EclipseNode child : fieldNode.down()) { if (child.getKind() == Kind.ANNOTATION) { if (annotationTypeMatches(Setter.class, child)) { @@ -117,7 +118,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { } } - createSetterForField(level, fieldNode, fieldNode, pos, false); + createSetterForField(level, fieldNode, fieldNode, pos, false, onMethod, onParam); } public boolean handle(AnnotationValues<Setter> annotation, Annotation ast, EclipseNode annotationNode) { @@ -126,24 +127,31 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { if (level == AccessLevel.NONE) return true; if (node == null) return false; + + Annotation[] onMethod = getAndRemoveAnnotationParameter(ast, "onMethod"); + Annotation[] onParam = getAndRemoveAnnotationParameter(ast, "onParam"); + if (node.getKind() == Kind.FIELD) { - return createSetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true); + return createSetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, onMethod, onParam); + } if (node.getKind() == Kind.TYPE) { + if (onMethod != null && onMethod.length != 0) annotationNode.addError("'onMethod' is not supported for @Setter on a type."); + if (onParam != null && onParam.length != 0) annotationNode.addError("'onParam' is not supported for @Setter on a type."); return generateSetterForType(node, annotationNode, level, false); } return false; } - private boolean createSetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists) { + private boolean createSetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod , Annotation[] onParam) { for (EclipseNode fieldNode : fieldNodes) { - createSetterForField(level, fieldNode, errorNode, source, whineIfExists); + createSetterForField(level, fieldNode, errorNode, source, whineIfExists, onMethod, onParam); } return true; } private boolean createSetterForField(AccessLevel level, - EclipseNode fieldNode, EclipseNode errorNode, ASTNode pos, boolean whineIfExists) { + EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod , Annotation[] onParam) { if (fieldNode.getKind() != Kind.FIELD) { errorNode.addError("@Setter is only supported on a class or a field."); return true; @@ -167,14 +175,18 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { //continue with creating the setter } - MethodDeclaration method = generateSetter((TypeDeclaration) fieldNode.up().get(), fieldNode, setterName, modifier, pos); + MethodDeclaration method = generateSetter((TypeDeclaration) fieldNode.up().get(), fieldNode, setterName, modifier, source, onParam); + Annotation[] copiedAnnotations = copyAnnotations(source, onMethod); + if (copiedAnnotations.length != 0) { + method.annotations = copiedAnnotations; + } injectMethod(fieldNode.up(), method); return true; } - private MethodDeclaration generateSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source) { + private MethodDeclaration generateSetter(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, ASTNode source, Annotation[] onParam) { FieldDeclaration field = (FieldDeclaration) fieldNode.get(); int pS = source.sourceStart, pE = source.sourceEnd; long p = (long)pS << 32 | pE; @@ -212,7 +224,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> { if (nullCheck != null) method.statements = new Statement[] { nullCheck, assignment }; else method.statements = new Statement[] { assignment }; } - Annotation[] copiedAnnotations = copyAnnotations(nonNulls, nullables, source); + Annotation[] copiedAnnotations = copyAnnotations(source, nonNulls, nullables, onParam); if (copiedAnnotations.length != 0) param.annotations = copiedAnnotations; return method; } |