From now on it is possible to specify annotations to be placed on the method

or the parameter of the generated getter/setter methods.
This commit is contained in:
Roel Spilker committed 2010-11-10 01:44:04 +01:00
1 parent 46d471e9c3
commit fe7f0db2fc
33 files changed
+634 -108

No files matched your search

+13 -1
View File
@@ -1,5 +1,5 @@
/*
* Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
* Copyright © 2009-2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -58,4 +58,16 @@ public @interface Getter {
* If you want your setter to be non-public, you can specify an alternate access level here.
*/
lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
/**
* If you want your getter method to have additional annotations, you can specify them here.<br/>
* If the {code @Getter} is put on a type, {code onMethod} may not be specified.
*/
AnyAnnotation[] onMethod() default {};
/**
* Placeholder annotation to enable the placement of annotations on the getter method.
*/
@Retention(RetentionPolicy.SOURCE)
@interface AnyAnnotation {}
}
+14 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
* Copyright © 2009-2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -21,7 +21,6 @@
*/
package lombok;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -57,9 +56,21 @@ public @interface Setter {
*/
lombok.AccessLevel value() default lombok.AccessLevel.PUBLIC;
/**
* If you want your setter method to have additional annotations, you can specify them here.
* If the {code @Setter} is put on a type, {code onMethod} may not be specified.
*/
AnyAnnotation[] onMethod() default {};
/**
* If you want the parameter of your setter to have additional annotations, you can specify them here.
* If the {code @Setter} is put on a type, {code onParam} may not be specified.
*/
AnyAnnotation[] onParam() default {};
/**
* Placeholder annotation to enable the placement of annotations on the setter method or its parameter.
*/
@Retention(RetentionPolicy.SOURCE)
@interface AnyAnnotation {}
}
}
+14 -15
View File
@@ -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);
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));
}
}
}
for (Annotation annotation : annotations2) {
outs[idx++] = copyAnnotation(annotation, source);
}
return outs;
if (allNull) return null;
return result.toArray(EMPTY_ANNOTATION_ARRAY);
}
public static Annotation copyAnnotation(Annotation annotation, ASTNode source) {
@@ -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;
}
}
@@ -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));
}
@@ -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;
}
@@ -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;
}
@@ -59,7 +59,7 @@ public class HandleData implements JavacAnnotationHandler<Data> {
// TODO move this to the end OR move it to the top in eclipse.
new HandleConstructor().generateRequiredArgsConstructor(typeNode, AccessLevel.PUBLIC, staticConstructorName, true);
new HandleGetter().generateGetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
new HandleSetter().generateSetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true, List.<JCExpression>nil(), List.<JCExpression>nil());
new HandleSetter().generateSetterForType(typeNode, annotationNode, AccessLevel.PUBLIC, true);
new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
new HandleToString().generateToStringForType(typeNode, annotationNode);
@@ -78,7 +78,7 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
}
for (JavacNode field : typeNode.down()) {
if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, errorNode.get(), level);
if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, errorNode.get(), level, List.<JCExpression>nil());
}
return true;
@@ -109,7 +109,7 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
* @param fieldNode The node representing the field you want a getter for.
* @param pos The node responsible for generating the getter (the {@code @Data} or {@code @Getter} annotation).
*/
public void generateGetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level) {
public void generateGetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, List<JCExpression> onMethod) {
for (JavacNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (Javac.annotationTypeMatches(Getter.class, child)) {
@@ -119,7 +119,7 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
}
}
createGetterForField(level, fieldNode, fieldNode, false);
createGetterForField(level, fieldNode, fieldNode, false, onMethod);
}
@Override public boolean handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacNode annotationNode) {
@@ -131,25 +131,28 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
if (level == AccessLevel.NONE) return true;
if (node == null) return false;
List<JCExpression> onMethod = getAndRemoveAnnotationParameter(ast, "onMethod");
if (node.getKind() == Kind.FIELD) {
return createGetterForFields(level, fields, annotationNode, true);
return createGetterForFields(level, fields, annotationNode, true, onMethod);
}
if (node.getKind() == Kind.TYPE) {
if (!onMethod.isEmpty()) 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<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists) {
private boolean createGetterForFields(AccessLevel level, Collection<JavacNode> fieldNodes, JavacNode errorNode, boolean whineIfExists, List<JCExpression> onMethod) {
for (JavacNode fieldNode : fieldNodes) {
createGetterForField(level, fieldNode, errorNode, whineIfExists);
createGetterForField(level, fieldNode, errorNode, whineIfExists, onMethod);
}
return true;
}
private boolean createGetterForField(AccessLevel level,
JavacNode fieldNode, JavacNode errorNode, boolean whineIfExists) {
JavacNode fieldNode, JavacNode errorNode, boolean whineIfExists, List<JCExpression> onMethod) {
if (fieldNode.getKind() != Kind.FIELD) {
errorNode.addError("@Getter is only supported on a class or a field.");
return true;
@@ -178,12 +181,12 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
long access = toJavacModifier(level) | (fieldDecl.mods.flags & Flags.STATIC);
injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker()));
injectMethod(fieldNode.up(), createGetter(access, fieldNode, fieldNode.getTreeMaker(), onMethod));
return true;
}
private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker) {
private JCMethodDecl createGetter(long access, JavacNode field, TreeMaker treeMaker, List<JCExpression> onMethod) {
JCVariableDecl fieldNode = (JCVariableDecl) field.get();
JCExpression fieldRef = createFieldAccessor(treeMaker, field, true);
JCStatement returnStatement = treeMaker.Return(fieldRef);
@@ -199,7 +202,10 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
List<JCAnnotation> nonNulls = findAnnotations(field, TransformationsUtil.NON_NULL_PATTERN);
List<JCAnnotation> nullables = findAnnotations(field, TransformationsUtil.NULLABLE_PATTERN);
return treeMaker.MethodDef(treeMaker.Modifiers(access, nonNulls.appendList(nullables)), methodName, methodType,
List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables);
return treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType,
methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue);
}
}
@@ -32,8 +32,8 @@ import javax.lang.model.type.TypeVisitor;
import lombok.AccessLevel;
import lombok.Setter;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.AST.Kind;
import lombok.core.handlers.TransformationsUtil;
import lombok.javac.Javac;
import lombok.javac.JavacAnnotationHandler;
@@ -44,28 +44,26 @@ import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.code.Type;
import com.sun.tools.javac.code.TypeTags;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCBlock;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCNewArray;
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.tree.TreeMaker;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.Name;
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
/**
* Handles the {@code lombok.Setter} annotation for javac.
*/
@ProviderFor(JavacAnnotationHandler.class)
public class HandleSetter implements JavacAnnotationHandler<Setter> {
public boolean generateSetterForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelSetter, List<JCExpression> onMethod, List<JCExpression> onParam) {
public boolean generateSetterForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelSetter) {
if (checkForTypeLevelSetter) {
if (typeNode != null) for (JavacNode child : typeNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
@@ -97,7 +95,7 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
//Skip final fields.
if ((fieldDecl.mods.flags & Flags.FINAL) != 0) continue;
generateSetterForField(field, errorNode.get(), level, onMethod, onParam);
generateSetterForField(field, errorNode.get(), level, List.<JCExpression>nil(), List.<JCExpression>nil());
}
return true;
}
@@ -140,47 +138,17 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
if (level == AccessLevel.NONE) return true;
if (node == null) return false;
List<JCExpression> params = List.nil();
List<JCExpression> onMethodList = List.nil();
List<JCExpression> onParamList = List.nil();
for (JCExpression param : ast.args) {
System.out.println("T: " + param.getClass());
if (param instanceof JCAssign) {
JCAssign assign = (JCAssign) param;
System.out.println("TL: " + assign.lhs.getClass());
if (assign.lhs instanceof JCIdent) {
JCIdent name = (JCIdent) assign.lhs;
if ("onMethod".equals(name.name.toString())) {
if (assign.rhs instanceof JCNewArray) {
onMethodList = ((JCNewArray) assign.rhs).elems;
} else {
onMethodList = onMethodList.append(assign.rhs);
}
continue;
} else if ("onParam".equals(name.name.toString())) {
if (assign.rhs instanceof JCNewArray) {
onParamList = ((JCNewArray) assign.rhs).elems;
} else {
onParamList = onParamList.append(assign.rhs);
}
continue;
}
}
}
params = params.append(param);
}
System.out.println("IN HANDLE SETTER5");
ast.args = params;
System.out.println("Args now: " + ast.args);
List<JCExpression> onParamList = getAndRemoveAnnotationParameter(ast, "onParam");
List<JCExpression> onMethodList = getAndRemoveAnnotationParameter(ast, "onMethod");
if (node.getKind() == Kind.FIELD) {
return createSetterForFields(level, fields, annotationNode, true, onMethodList, onParamList);
}
if (node.getKind() == Kind.TYPE) {
return generateSetterForType(node, annotationNode, level, false, onMethodList, onParamList);
if (!onMethodList.isEmpty()) annotationNode.addError("'onMethod' is not supported for @Setter on a type.");
if (!onParamList.isEmpty()) annotationNode.addError("'onParam' is not supported for @Setter on a type.");
return generateSetterForType(node, annotationNode, level, false);
}
return false;
}
@@ -261,15 +229,6 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue);
}
private static List<JCAnnotation> copyAnnotations(List<JCExpression> in) {
List<JCAnnotation> out = List.nil();
for (JCExpression expr : in) {
if (!(expr instanceof JCAnnotation)) continue;
out = out.append((JCAnnotation) expr.clone());
}
return out;
}
private static class JCNoType extends Type implements NoType {
public JCNoType(int tag) {
super(tag, null);
@@ -1,5 +1,5 @@
/*
* Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
* Copyright © 2009-2010 Reinier Zwitserloot, Roel Spilker and Robbert Jan Grootjans.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -42,12 +42,15 @@ import com.sun.tools.javac.tree.JCTree.JCLiteral;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCAssign;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.tree.JCTree.JCImport;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCNewArray;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
@@ -567,4 +570,39 @@ public class JavacHandlerUtil {
return problematic;
}
static List<JCExpression> getAndRemoveAnnotationParameter(JCAnnotation ast, String parameterName) {
List<JCExpression> params = List.nil();
List<JCExpression> result = List.nil();
for (JCExpression param : ast.args) {
if (param instanceof JCAssign) {
JCAssign assign = (JCAssign) param;
if (assign.lhs instanceof JCIdent) {
JCIdent ident = (JCIdent) assign.lhs;
if (parameterName.equals(ident.name.toString())) {
if (assign.rhs instanceof JCNewArray) {
result = ((JCNewArray) assign.rhs).elems;
} else {
result = result.append(assign.rhs);
}
continue;
}
}
}
params = params.append(param);
}
ast.args = params;
return result;
}
static List<JCAnnotation> copyAnnotations(List<JCExpression> in) {
List<JCAnnotation> out = List.nil();
for (JCExpression expr : in) {
if (!(expr instanceof JCAnnotation)) continue;
out = out.append((JCAnnotation) expr.clone());
}
return out;
}
}
@@ -182,3 +182,55 @@ final class Data4 extends java.util.Timer {
return result;
}
}
class Data5 {
@java.lang.SuppressWarnings("all")
public Data5() {
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof Data5)) return false;
final Data5 other = (Data5)o;
if (!other.canEqual(this)) return false;
return true;
}
@java.lang.SuppressWarnings("all")
public boolean canEqual(final java.lang.Object other) {
return other instanceof Data5;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public int hashCode() {
int result = 1;
return result;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public java.lang.String toString() {
return "Data5()";
}
}
final class Data6 {
@java.lang.SuppressWarnings("all")
public Data6() {
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public boolean equals(final java.lang.Object o) {
if (o == this) return true;
if (!(o instanceof Data6)) return false;
return true;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public int hashCode() {
int result = 1;
return result;
}
@java.lang.Override
@java.lang.SuppressWarnings("all")
public java.lang.String toString() {
return "Data6()";
}
}
@@ -0,0 +1,39 @@
class GetterOnMethod {
int i;
int j;
@Deprecated
@java.lang.SuppressWarnings("all")
public int getI() {
return this.i;
}
@java.lang.Deprecated
@java.lang.SuppressWarnings("all")
public int getJ() {
return this.j;
}
}
class GetterOnClassOnMethod {
int i;
int j;
@java.lang.SuppressWarnings("all")
public int getI() {
return this.i;
}
@java.lang.SuppressWarnings("all")
public int getJ() {
return this.j;
}
}
class GetterOnClassAndOnAField {
int i;
int j;
@java.lang.SuppressWarnings("all")
public int getI() {
return this.i;
}
@java.lang.Deprecated
@java.lang.SuppressWarnings("all")
public int getJ() {
return this.j;
}
}
@@ -0,0 +1,39 @@
class SetterOnMethod {
int i;
int j;
@Deprecated
@java.lang.SuppressWarnings("all")
public void setI(final int i) {
this.i = i;
}
@java.lang.Deprecated
@java.lang.SuppressWarnings("all")
public void setJ(final int j) {
this.j = j;
}
}
class SetterOnClassOnMethod {
int i;
int j;
@java.lang.SuppressWarnings("all")
public void setI(final int i) {
this.i = i;
}
@java.lang.SuppressWarnings("all")
public void setJ(final int j) {
this.j = j;
}
}
class SetterOnClassAndOnAField {
int i;
int j;
@java.lang.SuppressWarnings("all")
public void setI(final int i) {
this.i = i;
}
@java.lang.Deprecated
@java.lang.SuppressWarnings("all")
public void setJ(final int j) {
this.j = j;
}
}
@@ -0,0 +1,36 @@
class SetterOnParam {
int i;
int j;
@java.lang.SuppressWarnings("all")
public void setI(@SuppressWarnings("all") final int i) {
this.i = i;
}
@java.lang.SuppressWarnings("all")
public void setJ(@java.lang.SuppressWarnings("all") final int j) {
this.j = j;
}
}
class SetterOnClassOnParam {
int i;
int j;
@java.lang.SuppressWarnings("all")
public void setI(final int i) {
this.i = i;
}
@java.lang.SuppressWarnings("all")
public void setJ(final int j) {
this.j = j;
}
}
class SetterOnClassAndOnAFieldParam {
int i;
int j;
@java.lang.SuppressWarnings("all")
public void setI(final int i) {
this.i = i;
}
@java.lang.SuppressWarnings("all")
public void setJ(@java.lang.SuppressWarnings("all") final int j) {
this.j = j;
}
}
@@ -0,0 +1,8 @@
class SetterOnParamAndOnMethod {
int i;
@Deprecated
@java.lang.SuppressWarnings("all")
public void setI(@SuppressWarnings("all") final int i) {
this.i = i;
}
}
@@ -162,3 +162,33 @@ final @Data @lombok.EqualsAndHashCode(callSuper = true) class Data4 extends java
super();
}
}
@Data class Data5 {
public @java.lang.SuppressWarnings("all") Data5() {
super();
}
public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
if ((o == this))
return true;
if ((! (o instanceof Data5)))
return false;
final Data5 other = (Data5) o;
if ((! other.canEqual(this)))
return false;
return true;
}
public @java.lang.SuppressWarnings("all") boolean canEqual(final java.lang.Object other) {
return (other instanceof Data5);
}
}
final @Data class Data6 {
public @java.lang.SuppressWarnings("all") Data6() {
super();
}
public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
if ((o == this))
return true;
if ((! (o instanceof Data6)))
return false;
return true;
}
}
@@ -0,0 +1,40 @@
import lombok.Getter;
class GetterOnMethod {
@lombok.Getter() int i;
@lombok.Getter() int j;
public @Deprecated @java.lang.SuppressWarnings("all") int getI() {
return this.i;
}
public @java.lang.Deprecated @java.lang.SuppressWarnings("all") int getJ() {
return this.j;
}
GetterOnMethod() {
super();
}
}
@lombok.Getter() class GetterOnClassOnMethod {
int i;
int j;
public @java.lang.SuppressWarnings("all") int getI() {
return this.i;
}
public @java.lang.SuppressWarnings("all") int getJ() {
return this.j;
}
GetterOnClassOnMethod() {
super();
}
}
@lombok.Getter() class GetterOnClassAndOnAField {
int i;
@lombok.Getter() int j;
public @java.lang.Deprecated @java.lang.SuppressWarnings("all") int getJ() {
return this.j;
}
public @java.lang.SuppressWarnings("all") int getI() {
return this.i;
}
GetterOnClassAndOnAField() {
super();
}
}
@@ -0,0 +1,40 @@
import lombok.Setter;
class SetterOnMethod {
@lombok.Setter() int i;
@lombok.Setter() int j;
public @Deprecated @java.lang.SuppressWarnings("all") void setI(final int i) {
this.i = i;
}
public @java.lang.Deprecated @java.lang.SuppressWarnings("all") void setJ(final int j) {
this.j = j;
}
SetterOnMethod() {
super();
}
}
@lombok.Setter() class SetterOnClassOnMethod {
int i;
int j;
public @java.lang.SuppressWarnings("all") void setI(final int i) {
this.i = i;
}
public @java.lang.SuppressWarnings("all") void setJ(final int j) {
this.j = j;
}
SetterOnClassOnMethod() {
super();
}
}
@lombok.Setter() class SetterOnClassAndOnAField {
int i;
@lombok.Setter() int j;
public @java.lang.Deprecated @java.lang.SuppressWarnings("all") void setJ(final int j) {
this.j = j;
}
public @java.lang.SuppressWarnings("all") void setI(final int i) {
this.i = i;
}
SetterOnClassAndOnAField() {
super();
}
}
@@ -0,0 +1,40 @@
import lombok.Setter;
class SetterOnParam {
@lombok.Setter() int i;
@lombok.Setter() int j;
public @java.lang.SuppressWarnings("all") void setI(final @SuppressWarnings("all") int i) {
this.i = i;
}
public @java.lang.SuppressWarnings("all") void setJ(final @java.lang.SuppressWarnings("all") int j) {
this.j = j;
}
SetterOnParam() {
super();
}
}
@lombok.Setter() class SetterOnClassOnParam {
int i;
int j;
public @java.lang.SuppressWarnings("all") void setI(final int i) {
this.i = i;
}
public @java.lang.SuppressWarnings("all") void setJ(final int j) {
this.j = j;
}
SetterOnClassOnParam() {
super();
}
}
@lombok.Setter() class SetterOnClassAndOnAFieldParam {
int i;
@lombok.Setter() int j;
public @java.lang.SuppressWarnings("all") void setJ(final @java.lang.SuppressWarnings("all") int j) {
this.j = j;
}
public @java.lang.SuppressWarnings("all") void setI(final int i) {
this.i = i;
}
SetterOnClassAndOnAFieldParam() {
super();
}
}
@@ -0,0 +1,9 @@
class SetterOnParamAndOnMethod {
@lombok.Setter() int i;
public @Deprecated @java.lang.SuppressWarnings("all") void setI(final @SuppressWarnings("all") int i) {
this.i = i;
}
SetterOnParamAndOnMethod() {
super();
}
}
@@ -19,3 +19,9 @@ final class Data4 extends java.util.Timer {
super();
}
}
@Data
class Data5 {
}
@Data
final class Data6 {
}
@@ -0,0 +1,15 @@
import lombok.Getter;
class GetterOnMethod {
@lombok.Getter(onMethod=@Deprecated) int i;
@lombok.Getter(onMethod={@java.lang.Deprecated}) int j;
}
@lombok.Getter(onMethod=@Deprecated)
class GetterOnClassOnMethod {
int i;
int j;
}
@lombok.Getter(onMethod=@Deprecated)
class GetterOnClassAndOnAField {
int i;
@lombok.Getter(onMethod={@java.lang.Deprecated}) int j;
}
@@ -0,0 +1,15 @@
import lombok.Setter;
class SetterOnMethod {
@lombok.Setter(onMethod=@Deprecated) int i;
@lombok.Setter(onMethod={@java.lang.Deprecated}) int j;
}
@lombok.Setter(onMethod=@Deprecated)
class SetterOnClassOnMethod {
int i;
int j;
}
@lombok.Setter(onMethod=@Deprecated)
class SetterOnClassAndOnAField {
int i;
@lombok.Setter(onMethod={@java.lang.Deprecated}) int j;
}
@@ -0,0 +1,15 @@
import lombok.Setter;
class SetterOnParam {
@lombok.Setter(onParam=@SuppressWarnings("all")) int i;
@lombok.Setter(onParam={@java.lang.SuppressWarnings("all")}) int j;
}
@lombok.Setter(onParam=@SuppressWarnings("all"))
class SetterOnClassOnParam {
int i;
int j;
}
@lombok.Setter(onParam=@SuppressWarnings("all"))
class SetterOnClassAndOnAFieldParam {
int i;
@lombok.Setter(onParam={@java.lang.SuppressWarnings("all")}) int j;
}
@@ -0,0 +1,3 @@
class SetterOnParamAndOnMethod {
@lombok.Setter(onMethod=@Deprecated,onParam=@SuppressWarnings("all")) int i;
}
@@ -0,0 +1,17 @@
3:34 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Getter.AnyAnnotation
4:44 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Getter.AnyAnnotation
6:26 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Getter.AnyAnnotation
11:26 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Getter.AnyAnnotation
14:44 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Getter.AnyAnnotation
6:1 ERROR 'onMethod' is not supported for @Getter on a type.
11:1 ERROR 'onMethod' is not supported for @Getter on a type.
@@ -0,0 +1,17 @@
3:34 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Setter.AnyAnnotation
4:44 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Setter.AnyAnnotation
6:26 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Setter.AnyAnnotation
11:26 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Setter.AnyAnnotation
14:44 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Setter.AnyAnnotation
6:1 ERROR 'onMethod' is not supported for @Setter on a type.
11:1 ERROR 'onMethod' is not supported for @Setter on a type.
@@ -0,0 +1,17 @@
3:33 ERROR incompatible types
found : java.lang.SuppressWarnings
required: lombok.Setter.AnyAnnotation
4:43 ERROR incompatible types
found : java.lang.SuppressWarnings
required: lombok.Setter.AnyAnnotation
6:25 ERROR incompatible types
found : java.lang.SuppressWarnings
required: lombok.Setter.AnyAnnotation
11:25 ERROR incompatible types
found : java.lang.SuppressWarnings
required: lombok.Setter.AnyAnnotation
14:43 ERROR incompatible types
found : java.lang.SuppressWarnings
required: lombok.Setter.AnyAnnotation
6:1 ERROR 'onParam' is not supported for @Setter on a type.
11:1 ERROR 'onParam' is not supported for @Setter on a type.
@@ -0,0 +1,6 @@
2:34 ERROR incompatible types
found : java.lang.Deprecated
required: lombok.Setter.AnyAnnotation
2:54 ERROR incompatible types
found : java.lang.SuppressWarnings
required: lombok.Setter.AnyAnnotation
@@ -0,0 +1,2 @@
6 error 'onMethod' is not supported for @Getter on a type.
11 error 'onMethod' is not supported for @Getter on a type.
@@ -0,0 +1,2 @@
6 error 'onMethod' is not supported for @Setter on a type.
11 error 'onMethod' is not supported for @Setter on a type.
@@ -0,0 +1,2 @@
6 error 'onParam' is not supported for @Setter on a type.
11 error 'onParam' is not supported for @Setter on a type.