aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok
diff options
context:
space:
mode:
authorReinier Zwitserloot <reinier@zwitserloot.com>2010-07-17 06:54:33 +0200
committerReinier Zwitserloot <reinier@zwitserloot.com>2010-07-17 06:54:33 +0200
commit32a23d77866093c5ba97eefdd5482868cf505de5 (patch)
treef97477bdc0cc3547a90e6d2798a1f34337f30798 /src/core/lombok
parent99f763a7294065333bee1d269dc28a744e072bcc (diff)
downloadlombok-32a23d77866093c5ba97eefdd5482868cf505de5.tar.gz
lombok-32a23d77866093c5ba97eefdd5482868cf505de5.tar.bz2
lombok-32a23d77866093c5ba97eefdd5482868cf505de5.zip
Implements issue #129: @Getter and @Setter are now legal on entire types.
Diffstat (limited to 'src/core/lombok')
-rw-r--r--src/core/lombok/Getter.java7
-rw-r--r--src/core/lombok/Setter.java7
-rw-r--r--src/core/lombok/eclipse/handlers/HandleData.java6
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java44
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSetter.java45
-rw-r--r--src/core/lombok/javac/handlers/HandleData.java7
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java45
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java44
8 files changed, 173 insertions, 32 deletions
diff --git a/src/core/lombok/Getter.java b/src/core/lombok/Getter.java
index fa84954c..bff21abc 100644
--- a/src/core/lombok/Getter.java
+++ b/src/core/lombok/Getter.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -47,8 +47,11 @@ import java.lang.annotation.Target;
* <p>
* If any method named {@code getFoo}/{@code isFoo} exists, regardless of return type or parameters, no method is generated,
* and instead a compiler warning is emitted.
+ * <p>
+ * This annotation can also be applied to a class, in which case it'll be as if all non-static fields that don't already have
+ * a {@code @Getter} annotation have the annotation.
*/
-@Target(ElementType.FIELD)
+@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Getter {
/**
diff --git a/src/core/lombok/Setter.java b/src/core/lombok/Setter.java
index 778bb00d..6e0485c2 100644
--- a/src/core/lombok/Setter.java
+++ b/src/core/lombok/Setter.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -44,8 +44,11 @@ import java.lang.annotation.Target;
*
* If any method named {@code setFoo} exists, regardless of return type or parameters, no method is generated,
* and instead a compiler warning is emitted.
+ * <p>
+ * This annotation can also be applied to a class, in which case it'll be as if all non-static fields that don't already have
+ * a {@code Setter} annotation have the annotation.
*/
-@Target(ElementType.FIELD)
+@Target({ElementType.FIELD, ElementType.TYPE})
@Retention(RetentionPolicy.SOURCE)
public @interface Setter {
/**
diff --git a/src/core/lombok/eclipse/handlers/HandleData.java b/src/core/lombok/eclipse/handlers/HandleData.java
index bbf1822e..68b4682c 100644
--- a/src/core/lombok/eclipse/handlers/HandleData.java
+++ b/src/core/lombok/eclipse/handlers/HandleData.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -127,8 +127,8 @@ public class HandleData implements EclipseAnnotationHandler<Data> {
}
for (Map.Entry<EclipseNode, Boolean> field : gettersAndSetters.entrySet()) {
- new HandleGetter().generateGetterForField(field.getKey(), annotationNode.get());
- if (field.getValue()) new HandleSetter().generateSetterForField(field.getKey(), annotationNode.get());
+ new HandleGetter().generateGetterForField(field.getKey(), annotationNode.get(), AccessLevel.PUBLIC, true);
+ if (field.getValue()) new HandleSetter().generateSetterForField(field.getKey(), annotationNode.get(), AccessLevel.PUBLIC, true);
}
new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java
index d786f20f..43197ae4 100644
--- a/src/core/lombok/eclipse/handlers/HandleGetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleGetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -62,7 +62,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) {
+ public void generateGetterForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, boolean checkForTypeLevelGetter) {
for (EclipseNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (annotationTypeMatches(Getter.class, child)) {
@@ -72,15 +72,49 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> {
}
}
- createGetterForField(AccessLevel.PUBLIC, fieldNode, fieldNode, pos, false);
+ if (checkForTypeLevelGetter) {
+ EclipseNode containingType = fieldNode.up();
+ if (containingType != null) for (EclipseNode child : containingType.down()) {
+ if (child.getKind() == Kind.ANNOTATION) {
+ if (annotationTypeMatches(Getter.class, child)) {
+ //The annotation will make it happen, so we can skip it.
+ return;
+ }
+ }
+ }
+ }
+
+ createGetterForField(level, fieldNode, fieldNode, pos, false);
}
public boolean handle(AnnotationValues<Getter> annotation, Annotation ast, EclipseNode annotationNode) {
- EclipseNode fieldNode = annotationNode.up();
+ EclipseNode node = annotationNode.up();
AccessLevel level = annotation.getInstance().value();
if (level == AccessLevel.NONE) return true;
- return createGetterForField(level, fieldNode, annotationNode, annotationNode.get(), true);
+ if (node == null) return false;
+ if (node.getKind() == Kind.FIELD) {
+ return createGetterForField(level, node, annotationNode, annotationNode.get(), true);
+ }
+ if (node.getKind() == Kind.TYPE) {
+ TypeDeclaration typeDecl = null;
+ if (node.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) node.get();
+ int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
+ boolean notAClass = (modifiers &
+ (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0;
+
+ if (typeDecl == null || notAClass) {
+ annotationNode.addError("@Getter is only supported on a class.");
+ return false;
+ }
+
+ for (EclipseNode field : node.down()) {
+ if (field.getKind() != Kind.FIELD) continue;
+ generateGetterForField(field, ast, level, false);
+ }
+ return true;
+ }
+ return false;
}
private boolean createGetterForField(AccessLevel level,
diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java
index 7760acd9..3dbbb2b5 100644
--- a/src/core/lombok/eclipse/handlers/HandleSetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleSetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -69,7 +69,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) {
+ public void generateSetterForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, boolean checkForTypeLevelSetter) {
for (EclipseNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (annotationTypeMatches(Setter.class, child)) {
@@ -79,16 +79,49 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> {
}
}
- createSetterForField(AccessLevel.PUBLIC, fieldNode, fieldNode, pos, false);
+ if (checkForTypeLevelSetter) {
+ EclipseNode containingType = fieldNode.up();
+ if (containingType != null) for (EclipseNode child : containingType.down()) {
+ if (child.getKind() == Kind.ANNOTATION) {
+ if (annotationTypeMatches(Setter.class, child)) {
+ //The annotation will make it happen, so we can skip it.
+ return;
+ }
+ }
+ }
+ }
+
+ createSetterForField(level, fieldNode, fieldNode, pos, false);
}
public boolean handle(AnnotationValues<Setter> annotation, Annotation ast, EclipseNode annotationNode) {
- EclipseNode fieldNode = annotationNode.up();
- if (fieldNode.getKind() != Kind.FIELD) return false;
+ EclipseNode node = annotationNode.up();
AccessLevel level = annotation.getInstance().value();
if (level == AccessLevel.NONE) return true;
- return createSetterForField(level, fieldNode, annotationNode, annotationNode.get(), true);
+ if (node == null) return false;
+ if (node.getKind() == Kind.FIELD) {
+ return createSetterForField(level, node, annotationNode, annotationNode.get(), true);
+ }
+ if (node.getKind() == Kind.TYPE) {
+ TypeDeclaration typeDecl = null;
+ if (node.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) node.get();
+ int modifiers = typeDecl == null ? 0 : typeDecl.modifiers;
+ boolean notAClass = (modifiers &
+ (ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0;
+
+ if (typeDecl == null || notAClass) {
+ annotationNode.addError("@Setter is only supported on a class.");
+ return false;
+ }
+
+ for (EclipseNode field : node.down()) {
+ if (field.getKind() != Kind.FIELD) continue;
+ generateSetterForField(field, ast, level, false);
+ }
+ return true;
+ }
+ return false;
}
private boolean createSetterForField(AccessLevel level,
diff --git a/src/core/lombok/javac/handlers/HandleData.java b/src/core/lombok/javac/handlers/HandleData.java
index 88c0553c..efd86bba 100644
--- a/src/core/lombok/javac/handlers/HandleData.java
+++ b/src/core/lombok/javac/handlers/HandleData.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -32,6 +32,7 @@ import java.lang.reflect.Modifier;
import java.util.LinkedHashMap;
import java.util.Map;
+import lombok.AccessLevel;
import lombok.Data;
import lombok.core.AnnotationValues;
import lombok.core.AST.Kind;
@@ -107,8 +108,8 @@ public class HandleData implements JavacAnnotationHandler<Data> {
}
for (Map.Entry<JavacNode, Boolean> field : gettersAndSetters.entrySet()) {
- new HandleGetter().generateGetterForField(field.getKey(), annotationNode.get());
- if (field.getValue()) new HandleSetter().generateSetterForField(field.getKey(), annotationNode.get());
+ new HandleGetter().generateGetterForField(field.getKey(), annotationNode.get(), AccessLevel.PUBLIC, true);
+ if (field.getValue()) new HandleSetter().generateSetterForField(field.getKey(), annotationNode.get(), AccessLevel.PUBLIC, true);
}
new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index 14570187..5af05c7c 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -37,6 +37,7 @@ import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
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.JCMethodDecl;
import com.sun.tools.javac.tree.JCTree.JCStatement;
@@ -66,7 +67,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) {
+ public void generateGetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, boolean checkForTypeLevelGetter) {
for (JavacNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (Javac.annotationTypeMatches(Getter.class, child)) {
@@ -76,17 +77,49 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
}
}
- createGetterForField(AccessLevel.PUBLIC, fieldNode, fieldNode, false);
+ if (checkForTypeLevelGetter) {
+ JavacNode containingType = fieldNode.up();
+ if (containingType != null) for (JavacNode child : containingType.down()) {
+ if (child.getKind() == Kind.ANNOTATION) {
+ if (Javac.annotationTypeMatches(Getter.class, child)) {
+ //The annotation will make it happen, so we can skip it.
+ return;
+ }
+ }
+ }
+ }
+
+ createGetterForField(level, fieldNode, fieldNode, false);
}
@Override public boolean handle(AnnotationValues<Getter> annotation, JCAnnotation ast, JavacNode annotationNode) {
markAnnotationAsProcessed(annotationNode, Getter.class);
- JavacNode fieldNode = annotationNode.up();
+ JavacNode node = annotationNode.up();
AccessLevel level = annotation.getInstance().value();
-
if (level == AccessLevel.NONE) return true;
- return createGetterForField(level, fieldNode, annotationNode, true);
+ if (node == null) return false;
+ if (node.getKind() == Kind.FIELD) {
+ return createGetterForField(level, node, annotationNode, true);
+ }
+ if (node.getKind() == Kind.TYPE) {
+ JCClassDecl typeDecl = null;
+ if (node.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) node.get();
+ long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
+ boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0;
+
+ if (typeDecl == null || notAClass) {
+ annotationNode.addError("@Getter is only supported on a class.");
+ return false;
+ }
+
+ for (JavacNode field : node.down()) {
+ if (field.getKind() != Kind.FIELD) continue;
+ generateGetterForField(field, ast, level, false);
+ }
+ return true;
+ }
+ return false;
}
private boolean createGetterForField(AccessLevel level,
diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java
index e7f20f6c..a3822daa 100644
--- a/src/core/lombok/javac/handlers/HandleSetter.java
+++ b/src/core/lombok/javac/handlers/HandleSetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright © 2009 Reinier Zwitserloot and Roel Spilker.
+ * Copyright © 2009-2010 Reinier Zwitserloot and Roel Spilker.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -46,6 +46,7 @@ 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.JCFieldAccess;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
@@ -76,7 +77,7 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
* @param fieldNode The node representing the field you want a setter for.
* @param pos The node responsible for generating the setter (the {@code @Data} or {@code @Setter} annotation).
*/
- public void generateSetterForField(JavacNode fieldNode, DiagnosticPosition pos) {
+ public void generateSetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level, boolean checkForTypeLevelSetter) {
for (JavacNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (Javac.annotationTypeMatches(Setter.class, child)) {
@@ -86,17 +87,50 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
}
}
- createSetterForField(AccessLevel.PUBLIC, fieldNode, fieldNode, false);
+ if (checkForTypeLevelSetter) {
+ JavacNode containingType = fieldNode.up();
+ if (containingType != null) for (JavacNode child : containingType.down()) {
+ if (child.getKind() == Kind.ANNOTATION) {
+ if (Javac.annotationTypeMatches(Setter.class, child)) {
+ //The annotation will make it happen, so we can skip it.
+ return;
+ }
+ }
+ }
+ }
+
+ createSetterForField(level, fieldNode, fieldNode, false);
}
@Override public boolean handle(AnnotationValues<Setter> annotation, JCAnnotation ast, JavacNode annotationNode) {
markAnnotationAsProcessed(annotationNode, Setter.class);
- JavacNode fieldNode = annotationNode.up();
+ JavacNode node = annotationNode.up();
AccessLevel level = annotation.getInstance().value();
if (level == AccessLevel.NONE) return true;
- return createSetterForField(level, fieldNode, annotationNode, true);
+ if (node == null) return false;
+ if (node.getKind() == Kind.FIELD) {
+ return createSetterForField(level, node, annotationNode, true);
+ }
+ if (node.getKind() == Kind.TYPE) {
+ JCClassDecl typeDecl = null;
+ if (node.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) node.get();
+ long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
+ boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0;
+
+ if (typeDecl == null || notAClass) {
+ annotationNode.addError("@Setter is only supported on a class.");
+ return false;
+ }
+
+ for (JavacNode field : node.down()) {
+ if (field.getKind() != Kind.FIELD) continue;
+ generateSetterForField(field, ast, level, false);
+ }
+ return true;
+ }
+ return false;
}
private boolean createSetterForField(AccessLevel level,