aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/javac/handlers')
-rw-r--r--src/core/lombok/javac/handlers/HandleConstructor.java42
-rw-r--r--src/core/lombok/javac/handlers/HandleData.java37
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java71
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java75
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java60
5 files changed, 170 insertions, 115 deletions
diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java
index fe5f8566..e24c19d1 100644
--- a/src/core/lombok/javac/handlers/HandleConstructor.java
+++ b/src/core/lombok/javac/handlers/HandleConstructor.java
@@ -65,7 +65,7 @@ public class HandleConstructor {
String staticName = ann.staticName();
if (level == AccessLevel.NONE) return true;
List<JavacNode> fields = List.nil();
- new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, false);
+ new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, false, false);
return true;
}
}
@@ -82,24 +82,28 @@ public class HandleConstructor {
@SuppressWarnings("deprecation")
boolean suppressConstructorProperties = ann.suppressConstructorProperties();
if (level == AccessLevel.NONE) return true;
- List<JavacNode> fields = List.nil();
- for (JavacNode child : typeNode.down()) {
- if (child.getKind() != Kind.FIELD) continue;
- JCVariableDecl fieldDecl = (JCVariableDecl) child.get();
- //Skip fields that start with $
- if (fieldDecl.name.toString().startsWith("$")) continue;
- long fieldFlags = fieldDecl.mods.flags;
- //Skip static fields.
- if ((fieldFlags & Flags.STATIC) != 0) continue;
- boolean isFinal = (fieldFlags & Flags.FINAL) != 0;
- boolean isNonNull = !findAnnotations(child, TransformationsUtil.NON_NULL_PATTERN).isEmpty();
- if ((isFinal || isNonNull) && fieldDecl.init == null) fields = fields.append(child);
- }
- new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, suppressConstructorProperties);
+ new HandleConstructor().generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, false, suppressConstructorProperties);
return true;
}
}
+ private static List<JavacNode> findRequiredFields(JavacNode typeNode) {
+ List<JavacNode> fields = List.nil();
+ for (JavacNode child : typeNode.down()) {
+ if (child.getKind() != Kind.FIELD) continue;
+ JCVariableDecl fieldDecl = (JCVariableDecl) child.get();
+ //Skip fields that start with $
+ if (fieldDecl.name.toString().startsWith("$")) continue;
+ long fieldFlags = fieldDecl.mods.flags;
+ //Skip static fields.
+ if ((fieldFlags & Flags.STATIC) != 0) continue;
+ boolean isFinal = (fieldFlags & Flags.FINAL) != 0;
+ boolean isNonNull = !findAnnotations(child, TransformationsUtil.NON_NULL_PATTERN).isEmpty();
+ if ((isFinal || isNonNull) && fieldDecl.init == null) fields = fields.append(child);
+ }
+ return fields;
+ }
+
@ProviderFor(JavacAnnotationHandler.class)
public static class HandleAllArgsConstructor implements JavacAnnotationHandler<AllArgsConstructor> {
@Override public boolean handle(AnnotationValues<AllArgsConstructor> annotation, JCAnnotation ast, JavacNode annotationNode) {
@@ -123,12 +127,16 @@ public class HandleConstructor {
if ((fieldFlags & Flags.STATIC) != 0) continue;
fields = fields.append(child);
}
- new HandleConstructor().generateConstructor(level, typeNode, fields, staticName, false, suppressConstructorProperties);
+ new HandleConstructor().generateConstructor(typeNode, level, fields, staticName, false, suppressConstructorProperties);
return true;
}
}
- public void generateConstructor(AccessLevel level, JavacNode typeNode, List<JavacNode> fields, String staticName, boolean skipIfConstructorExists, boolean suppressConstructorProperties) {
+ public void generateRequiredArgsConstructor(JavacNode typeNode, AccessLevel level, String staticName, boolean skipIfConstructorExists) {
+ generateConstructor(typeNode, level, findRequiredFields(typeNode), staticName, skipIfConstructorExists, false);
+ }
+
+ public void generateConstructor(JavacNode typeNode, AccessLevel level, List<JavacNode> fields, String staticName, boolean skipIfConstructorExists, boolean suppressConstructorProperties) {
if (skipIfConstructorExists && constructorExists(typeNode) != MemberExistsResult.NOT_EXISTS) return;
if (skipIfConstructorExists) {
for (JavacNode child : typeNode.down()) {
diff --git a/src/core/lombok/javac/handlers/HandleData.java b/src/core/lombok/javac/handlers/HandleData.java
index e20b230e..2087c133 100644
--- a/src/core/lombok/javac/handlers/HandleData.java
+++ b/src/core/lombok/javac/handlers/HandleData.java
@@ -21,16 +21,10 @@
*/
package lombok.javac.handlers;
-import static lombok.javac.handlers.JavacHandlerUtil.*;
-
-import java.util.LinkedHashMap;
-import java.util.Map;
-
+import static lombok.javac.handlers.JavacHandlerUtil.markAnnotationAsProcessed;
import lombok.AccessLevel;
import lombok.Data;
-import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
-import lombok.core.handlers.TransformationsUtil;
import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacNode;
@@ -39,8 +33,6 @@ import org.mangosdk.spi.ProviderFor;
import com.sun.tools.javac.code.Flags;
import com.sun.tools.javac.tree.JCTree.JCAnnotation;
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
-import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
-import com.sun.tools.javac.util.List;
/**
* Handles the {@code lombok.Data} annotation for javac.
@@ -60,31 +52,12 @@ public class HandleData implements JavacAnnotationHandler<Data> {
return false;
}
- List<JavacNode> nodesForConstructor = List.nil();
- Map<JavacNode, Boolean> gettersAndSetters = new LinkedHashMap<JavacNode, Boolean>();
- for (JavacNode child : typeNode.down()) {
- if (child.getKind() != Kind.FIELD) continue;
- JCVariableDecl fieldDecl = (JCVariableDecl) child.get();
- //Skip fields that start with $
- if (fieldDecl.name.toString().startsWith("$")) continue;
- long fieldFlags = fieldDecl.mods.flags;
- //Skip static fields.
- if ((fieldFlags & Flags.STATIC) != 0) continue;
- boolean isFinal = (fieldFlags & Flags.FINAL) != 0;
- boolean isNonNull = !findAnnotations(child, TransformationsUtil.NON_NULL_PATTERN).isEmpty();
- if ((isFinal || isNonNull) && fieldDecl.init == null) nodesForConstructor = nodesForConstructor.append(child);
- gettersAndSetters.put(child, !isFinal);
- }
-
String staticConstructorName = annotation.getInstance().staticConstructor();
- new HandleConstructor().generateConstructor(AccessLevel.PUBLIC, typeNode, nodesForConstructor, staticConstructorName, true, false);
-
- for (Map.Entry<JavacNode, Boolean> field : gettersAndSetters.entrySet()) {
- new HandleGetter().generateGetterForField(field.getKey(), annotationNode.get(), AccessLevel.PUBLIC, true);
- if (field.getValue()) new HandleSetter().generateSetterForField(field.getKey(), annotationNode.get(), AccessLevel.PUBLIC, true);
- }
-
+ // 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);
new HandleEqualsAndHashCode().generateEqualsAndHashCodeForType(typeNode, annotationNode);
new HandleToString().generateToStringForType(typeNode, annotationNode);
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index 582aa02b..28402346 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -56,6 +56,45 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
*/
@ProviderFor(JavacAnnotationHandler.class)
public class HandleGetter implements JavacAnnotationHandler<Getter> {
+ public boolean generateGetterForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean checkForTypeLevelGetter) {
+ if (checkForTypeLevelGetter) {
+ if (typeNode != null) for (JavacNode child : typeNode.down()) {
+ if (child.getKind() == Kind.ANNOTATION) {
+ if (Javac.annotationTypeMatches(Getter.class, child)) {
+ //The annotation will make it happen, so we can skip it.
+ return true;
+ }
+ }
+ }
+ }
+
+ JCClassDecl typeDecl = null;
+ if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get();
+ long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
+ boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0;
+
+ if (typeDecl == null || notAClass) {
+ errorNode.addError("@Getter is only supported on a class or a field.");
+ return false;
+ }
+
+ for (JavacNode field : typeNode.down()) {
+ if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, errorNode.get(), level);
+ }
+
+ return true;
+ }
+
+ public boolean fieldQualifiesForGetterGeneration(JavacNode field) {
+ if (field.getKind() != Kind.FIELD) return false;
+ JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
+ //Skip fields that start with $
+ if (fieldDecl.name.toString().startsWith("$")) return false;
+ //Skip static fields.
+ if ((fieldDecl.mods.flags & Flags.STATIC) != 0) return false;
+ return true;
+ }
+
/**
* Generates a getter on the stated field.
*
@@ -71,7 +110,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, boolean checkForTypeLevelGetter) {
+ public void generateGetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level) {
for (JavacNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (Javac.annotationTypeMatches(Getter.class, child)) {
@@ -81,18 +120,6 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
}
}
- 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);
}
@@ -109,21 +136,7 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
return createGetterForFields(level, fields, 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 generateGetterForType(node, annotationNode, level, false);
}
return false;
}
@@ -139,7 +152,7 @@ public class HandleGetter implements JavacAnnotationHandler<Getter> {
private boolean createGetterForField(AccessLevel level,
JavacNode fieldNode, JavacNode errorNode, boolean whineIfExists) {
if (fieldNode.getKind() != Kind.FIELD) {
- errorNode.addError("@Getter is only supported on a field.");
+ errorNode.addError("@Getter is only supported on a class or a field.");
return true;
}
diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java
index 8728ceb3..0c248527 100644
--- a/src/core/lombok/javac/handlers/HandleSetter.java
+++ b/src/core/lombok/javac/handlers/HandleSetter.java
@@ -32,8 +32,8 @@ import javax.lang.model.type.TypeVisitor;
import lombok.AccessLevel;
import lombok.Setter;
-import lombok.core.AnnotationValues;
import lombok.core.AST.Kind;
+import lombok.core.AnnotationValues;
import lombok.core.handlers.TransformationsUtil;
import lombok.javac.Javac;
import lombok.javac.JavacAnnotationHandler;
@@ -44,7 +44,6 @@ 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;
@@ -55,15 +54,53 @@ import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
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) {
+ if (checkForTypeLevelSetter) {
+ if (typeNode != null) for (JavacNode child : typeNode.down()) {
+ if (child.getKind() == Kind.ANNOTATION) {
+ if (Javac.annotationTypeMatches(Setter.class, child)) {
+ //The annotation will make it happen, so we can skip it.
+ return true;
+ }
+ }
+ }
+ }
+
+ JCClassDecl typeDecl = null;
+ if (typeNode.get() instanceof JCClassDecl) typeDecl = (JCClassDecl) typeNode.get();
+ long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
+ boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION | Flags.ENUM)) != 0;
+
+ if (typeDecl == null || notAClass) {
+ errorNode.addError("@Setter is only supported on a class or a field.");
+ return false;
+ }
+
+ for (JavacNode field : typeNode.down()) {
+ if (field.getKind() != Kind.FIELD) continue;
+ JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
+ //Skip fields that start with $
+ if (fieldDecl.name.toString().startsWith("$")) continue;
+ //Skip static fields.
+ if ((fieldDecl.mods.flags & Flags.STATIC) != 0) continue;
+ //Skip final fields.
+ if ((fieldDecl.mods.flags & Flags.FINAL) != 0) continue;
+
+ generateSetterForField(field, errorNode.get(), level);
+ }
+ return true;
+ }
+
/**
* Generates a setter on the stated field.
*
@@ -79,7 +116,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, AccessLevel level, boolean checkForTypeLevelSetter) {
+ public void generateSetterForField(JavacNode fieldNode, DiagnosticPosition pos, AccessLevel level) {
for (JavacNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (Javac.annotationTypeMatches(Setter.class, child)) {
@@ -89,18 +126,6 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
}
}
- 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);
}
@@ -118,21 +143,7 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
return createSetterForFields(level, fields, 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 generateSetterForType(node, annotationNode, level, false);
}
return false;
}
@@ -148,7 +159,7 @@ public class HandleSetter implements JavacAnnotationHandler<Setter> {
private boolean createSetterForField(AccessLevel level,
JavacNode fieldNode, JavacNode errorNode, boolean whineIfExists) {
if (fieldNode.getKind() != Kind.FIELD) {
- fieldNode.addError("@Setter is only supported on a field.");
+ fieldNode.addError("@Setter is only supported on a class or a field.");
return true;
}
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index cb2697f1..09d5c3fe 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -21,12 +21,18 @@
*/
package lombok.javac.handlers;
+import static lombok.javac.Javac.annotationTypeMatches;
+
import java.lang.annotation.Annotation;
import java.util.regex.Pattern;
import lombok.AccessLevel;
+import lombok.Data;
+import lombok.Getter;
+import lombok.core.AnnotationValues;
import lombok.core.AST.Kind;
import lombok.core.handlers.TransformationsUtil;
+import lombok.javac.Javac;
import lombok.javac.JavacNode;
import com.sun.tools.javac.code.Flags;
@@ -270,7 +276,17 @@ public class JavacHandlerUtil {
}
}
- private static JCMethodDecl findGetter(JavacNode field) {
+ private static class GetterMethod {
+ private final Name name;
+ private final JCExpression type;
+
+ GetterMethod(Name name, JCExpression type) {
+ this.name = name;
+ this.type = type;
+ }
+ }
+
+ private static GetterMethod findGetter(JavacNode field) {
JCVariableDecl decl = (JCVariableDecl)field.get();
JavacNode typeNode = field.up();
for (String potentialGetterName : toAllGetterNames(decl)) {
@@ -280,15 +296,49 @@ public class JavacHandlerUtil {
for (JavacNode potentialGetter : typeNode.down()) {
if (potentialGetter.getKind() != Kind.METHOD) continue;
JCMethodDecl method = (JCMethodDecl) potentialGetter.get();
+ if (!method.name.contentEquals(potentialGetterName)) continue;
/** static getX() methods don't count. */
if ((method.mods.flags & Flags.STATIC) != 0) continue;
/** Nor do getters with a non-empty parameter list. */
if (method.params != null && method.params.size() > 0) continue;
- return method;
+ return new GetterMethod(method.name, method.restype);
+ }
+ }
+ }
+
+ // Check if the field has a @Getter annotation.
+
+ boolean hasGetterAnnotation = false;
+
+ for (JavacNode child : field.down()) {
+ if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Getter.class, child)) {
+ AnnotationValues<Getter> ann = Javac.createAnnotation(Getter.class, child);
+ if (ann.getInstance().value() == AccessLevel.NONE) return null; //Definitely WONT have a getter.
+ hasGetterAnnotation = true;
+ }
+ }
+
+ // Check if the class has a @Getter annotation.
+
+ if (!hasGetterAnnotation && new HandleGetter().fieldQualifiesForGetterGeneration(field)) {
+ //Check if the class has @Getter or @Data annotation.
+
+ JavacNode containingType = field.up();
+ if (containingType != null) for (JavacNode child : containingType.down()) {
+ if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Data.class, child)) hasGetterAnnotation = true;
+ if (child.getKind() == Kind.ANNOTATION && annotationTypeMatches(Getter.class, child)) {
+ AnnotationValues<Getter> ann = Javac.createAnnotation(Getter.class, child);
+ if (ann.getInstance().value() == AccessLevel.NONE) return null; //Definitely WONT have a getter.
+ hasGetterAnnotation = true;
}
}
}
+ if (hasGetterAnnotation) {
+ String getterName = toGetterName(decl);
+ return new GetterMethod(field.toName(getterName), decl.vartype);
+ }
+
return null;
}
@@ -298,13 +348,13 @@ public class JavacHandlerUtil {
* @see #createFieldAccessor(TreeMaker, JavacNode)
*/
static JCExpression getFieldType(JavacNode field, boolean useFieldsDirectly) {
- JCMethodDecl getter = useFieldsDirectly ? null : findGetter(field);
+ GetterMethod getter = useFieldsDirectly ? null : findGetter(field);
if (getter == null) {
return ((JCVariableDecl)field.get()).vartype;
}
- return getter.restype;
+ return getter.type;
}
/**
@@ -315,7 +365,7 @@ public class JavacHandlerUtil {
}
static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, boolean useFieldsDirectly, JCExpression receiver) {
- JCMethodDecl getter = useFieldsDirectly ? null : findGetter(field);
+ GetterMethod getter = useFieldsDirectly ? null : findGetter(field);
if (getter == null) {
return maker.Select(receiver, ((JCVariableDecl)field.get()).name);