aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/eclipse
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/eclipse')
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java37
-rw-r--r--src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java34
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java39
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSetter.java3
-rw-r--r--src/core/lombok/eclipse/handlers/HandleToString.java17
5 files changed, 90 insertions, 40 deletions
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index f252793d..ba34df77 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -175,8 +175,29 @@ public class EclipseHandlerUtil {
return null;
}
- static TypeReference getFieldType(EclipseNode field, boolean useFieldsDirectly) {
- GetterMethod getter = useFieldsDirectly ? null : findGetter(field);
+ enum FieldAccess {
+ GETTER, PREFER_FIELD, ALWAYS_FIELD;
+ }
+
+ static boolean lookForGetter(EclipseNode field, FieldAccess fieldAccess) {
+ if (fieldAccess == FieldAccess.GETTER) return true;
+ if (fieldAccess == FieldAccess.ALWAYS_FIELD) return false;
+
+ // If @Getter(lazy = true) is used, then using it is mandatory.
+ for (EclipseNode child : field.down()) {
+ if (child.getKind() != Kind.ANNOTATION) continue;
+ if (Eclipse.annotationTypeMatches(Getter.class, child)) {
+ AnnotationValues<Getter> ann = Eclipse.createAnnotation(Getter.class, child);
+ if (ann.getInstance().lazy()) return true;
+ }
+ }
+ return false;
+ }
+
+ static TypeReference getFieldType(EclipseNode field, FieldAccess fieldAccess) {
+ boolean lookForGetter = lookForGetter(field, fieldAccess);
+
+ GetterMethod getter = lookForGetter ? findGetter(field) : null;
if (getter == null) {
return ((FieldDeclaration)field.get()).type;
}
@@ -184,11 +205,13 @@ public class EclipseHandlerUtil {
return getter.type;
}
- static Expression createFieldAccessor(EclipseNode field, boolean useFieldsDirectly, ASTNode source) {
+ static Expression createFieldAccessor(EclipseNode field, FieldAccess fieldAccess, ASTNode source) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
- GetterMethod getter = useFieldsDirectly ? null : findGetter(field);
+ boolean lookForGetter = lookForGetter(field, fieldAccess);
+
+ GetterMethod getter = lookForGetter ? findGetter(field) : null;
if (getter == null) {
FieldDeclaration fieldDecl = (FieldDeclaration)field.get();
@@ -219,11 +242,13 @@ public class EclipseHandlerUtil {
return call;
}
- static Expression createFieldAccessor(EclipseNode field, boolean useFieldsDirectly, ASTNode source, char[] receiver) {
+ static Expression createFieldAccessor(EclipseNode field, FieldAccess fieldAccess, ASTNode source, char[] receiver) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
- GetterMethod getter = useFieldsDirectly ? null : findGetter(field);
+ boolean lookForGetter = lookForGetter(field, fieldAccess);
+
+ GetterMethod getter = lookForGetter ? findGetter(field) : null;
if (getter == null) {
NameReference ref;
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index 2b830241..895c076e 100644
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -113,7 +113,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
}
}
- generateMethods(typeNode, errorNode, null, null, null, false, false);
+ generateMethods(typeNode, errorNode, null, null, null, false, FieldAccess.GETTER);
}
@Override public boolean handle(AnnotationValues<EqualsAndHashCode> annotation,
@@ -135,11 +135,13 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored.");
}
- return generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, ann.doNotUseGetters());
+ FieldAccess fieldAccess = ann.doNotUseGetters() ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER;
+
+ return generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, fieldAccess);
}
public boolean generateMethods(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes,
- Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) {
+ Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) {
assert excludes == null || includes == null;
TypeDeclaration typeDecl = null;
@@ -209,7 +211,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
boolean isFinal = (typeDecl.modifiers & ClassFileConstants.AccFinal) != 0;
needsCanEqual = !isDirectDescendantOfObject || !isFinal;
- MethodDeclaration equals = createEquals(typeNode, nodesForEquality, callSuper, errorNode.get(), useFieldsDirectly, needsCanEqual);
+ MethodDeclaration equals = createEquals(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess, needsCanEqual);
injectMethod(typeNode, equals);
break;
case EXISTS_BY_LOMBOK:
@@ -237,7 +239,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
switch (methodExists("hashCode", typeNode)) {
case NOT_EXISTS:
- MethodDeclaration hashCode = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get(), useFieldsDirectly);
+ MethodDeclaration hashCode = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess);
injectMethod(typeNode, hashCode);
break;
case EXISTS_BY_LOMBOK:
@@ -253,7 +255,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
return true;
}
- private MethodDeclaration createHashCode(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, boolean useFieldsDirectly) {
+ private MethodDeclaration createHashCode(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, FieldAccess fieldAccess) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
@@ -318,9 +320,9 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
int tempCounter = 0;
for (EclipseNode field : fields) {
- TypeReference fType = getFieldType(field, useFieldsDirectly);
+ TypeReference fType = getFieldType(field, fieldAccess);
char[] token = fType.getLastToken();
- Expression fieldAccessor = createFieldAccessor(field, useFieldsDirectly, source);
+ Expression fieldAccessor = createFieldAccessor(field, fieldAccess, source);
if (fType.dimensions() == 0 && token != null) {
if (Arrays.equals(TypeConstants.FLOAT, token)) {
/* Float.floatToIntBits(fieldName) */
@@ -363,7 +365,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
Eclipse.setGeneratedBy(int1231or1237, source);
intoResult.add(int1231or1237);
} else if (Arrays.equals(TypeConstants.LONG, token)) {
- intoResult.add(longToIntForHashCode(fieldAccessor, createFieldAccessor(field, useFieldsDirectly, source), source));
+ intoResult.add(longToIntForHashCode(fieldAccessor, createFieldAccessor(field, fieldAccess, source), source));
} else if (BUILT_IN_TYPES.contains(new String(token))) {
intoResult.add(fieldAccessor);
} else /* objects */ {
@@ -371,7 +373,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
MessageSend hashCodeCall = new MessageSend();
hashCodeCall.sourceStart = pS; hashCodeCall.sourceEnd = pE;
Eclipse.setGeneratedBy(hashCodeCall, source);
- hashCodeCall.receiver = createFieldAccessor(field, useFieldsDirectly, source);
+ hashCodeCall.receiver = createFieldAccessor(field, fieldAccess, source);
hashCodeCall.selector = "hashCode".toCharArray();
NullLiteral nullLiteral = new NullLiteral(pS, pE);
Eclipse.setGeneratedBy(nullLiteral, source);
@@ -433,7 +435,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
return method;
}
- private MethodDeclaration createEquals(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, boolean useFieldsDirectly, boolean needsCanEqual) {
+ private MethodDeclaration createEquals(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, FieldAccess fieldAccess, boolean needsCanEqual) {
int pS = source.sourceStart; int pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
TypeDeclaration typeDecl = (TypeDeclaration)type.get();
@@ -589,10 +591,10 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
}
for (EclipseNode field : fields) {
- TypeReference fType = getFieldType(field, useFieldsDirectly);
+ TypeReference fType = getFieldType(field, fieldAccess);
char[] token = fType.getLastToken();
- Expression thisFieldAccessor = createFieldAccessor(field, useFieldsDirectly, source);
- Expression otherFieldAccessor = createFieldAccessor(field, useFieldsDirectly, source, otherName);
+ Expression thisFieldAccessor = createFieldAccessor(field, fieldAccess, source);
+ Expression otherFieldAccessor = createFieldAccessor(field, fieldAccess, source, otherName);
if (fType.dimensions() == 0 && token != null) {
if (Arrays.equals(TypeConstants.FLOAT, token)) {
@@ -619,9 +621,9 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
MessageSend equalsCall = new MessageSend();
equalsCall.sourceStart = pS; equalsCall.sourceEnd = pE;
Eclipse.setGeneratedBy(equalsCall, source);
- equalsCall.receiver = createFieldAccessor(field, useFieldsDirectly, source);
+ equalsCall.receiver = createFieldAccessor(field, fieldAccess, source);
equalsCall.selector = "equals".toCharArray();
- equalsCall.arguments = new Expression[] { createFieldAccessor(field, useFieldsDirectly, source, otherName) };
+ equalsCall.arguments = new Expression[] { createFieldAccessor(field, fieldAccess, source, otherName) };
UnaryExpression fieldsNotEqual = new UnaryExpression(equalsCall, OperatorIds.NOT);
fieldsNotEqual.sourceStart = pS; fieldsNotEqual.sourceEnd = pE;
Eclipse.setGeneratedBy(fieldsNotEqual, source);
diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java
index 38a6b468..e5ddbc3f 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, null);
+ if (fieldQualifiesForGetterGeneration(field)) generateGetterForField(field, pos.get(), level, null, false);
}
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, Annotation[] onMethod) {
+ public void generateGetterForField(EclipseNode fieldNode, ASTNode pos, AccessLevel level, Annotation[] onMethod, boolean lazy) {
for (EclipseNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
if (annotationTypeMatches(Getter.class, child)) {
@@ -113,42 +113,61 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> {
}
}
- createGetterForField(level, fieldNode, fieldNode, pos, false, onMethod);
+ createGetterForField(level, fieldNode, fieldNode, pos, false, onMethod, lazy);
}
public boolean handle(AnnotationValues<Getter> annotation, Annotation ast, EclipseNode annotationNode) {
EclipseNode node = annotationNode.up();
- AccessLevel level = annotation.getInstance().value();
- if (level == AccessLevel.NONE) return true;
+ Getter annotationInstance = annotation.getInstance();
+ AccessLevel level = annotationInstance.value();
+ boolean lazy = annotationInstance.lazy();
+ if (level == AccessLevel.NONE) {
+ if (lazy) {
+ annotationNode.addWarning("'lazy' requires AccessLevel.PRIVATE or higher.");
+ }
+ 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, onMethod);
+ return createGetterForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, annotationNode.get(), true, onMethod, lazy);
}
if (node.getKind() == Kind.TYPE) {
if (onMethod != null && onMethod.length != 0) annotationNode.addError("'onMethod' is not supported for @Getter on a type.");
+ if (lazy) annotationNode.addError("'lazy' 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, Annotation[] onMethod) {
+ private boolean createGetterForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod, boolean lazy) {
for (EclipseNode fieldNode : fieldNodes) {
- createGetterForField(level, fieldNode, errorNode, source, whineIfExists, onMethod);
+ createGetterForField(level, fieldNode, errorNode, source, whineIfExists, onMethod, lazy);
}
return true;
}
private boolean createGetterForField(AccessLevel level,
- EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod) {
+ EclipseNode fieldNode, EclipseNode errorNode, ASTNode source, boolean whineIfExists, Annotation[] onMethod, boolean lazy) {
if (fieldNode.getKind() != Kind.FIELD) {
errorNode.addError("@Getter is only supported on a class or a field.");
return true;
}
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
+ if (lazy) {
+ if ((field.modifiers & (ClassFileConstants.AccPrivate | ClassFileConstants.AccFinal)) != 0) {
+ errorNode.addError("'lazy' requires the field to be private and final.");
+ return true;
+ }
+ if (field.initialization == null) {
+ errorNode.addError("'lazy' requires field initialization.");
+ return true;
+ }
+ }
+
TypeReference fieldType = copyType(field.type, source);
String fieldName = new String(field.name);
boolean isBoolean = nameEquals(fieldType.getTypeName(), "boolean") && fieldType.dimensions() == 0;
@@ -198,7 +217,7 @@ public class HandleGetter implements EclipseAnnotationHandler<Getter> {
method.thrownExceptions = null;
method.typeParameters = null;
method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- Expression fieldRef = createFieldAccessor(fieldNode, true, source);
+ Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source);
Statement returnStatement = new ReturnStatement(fieldRef, field.sourceStart, field.sourceEnd);
Eclipse.setGeneratedBy(returnStatement, source);
method.bodyStart = method.declarationSourceStart = method.sourceStart = source.sourceStart;
diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java
index 48e688fd..2c3ca6ed 100644
--- a/src/core/lombok/eclipse/handlers/HandleSetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleSetter.java
@@ -35,6 +35,7 @@ import lombok.core.handlers.TransformationsUtil;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
+import lombok.eclipse.handlers.EclipseHandlerUtil.FieldAccess;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
@@ -206,7 +207,7 @@ public class HandleSetter implements EclipseAnnotationHandler<Setter> {
method.thrownExceptions = null;
method.typeParameters = null;
method.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
- Expression fieldRef = createFieldAccessor(fieldNode, true, source);
+ Expression fieldRef = createFieldAccessor(fieldNode, FieldAccess.ALWAYS_FIELD, source);
NameReference fieldNameRef = new SingleNameReference(field.name, p);
Eclipse.setGeneratedBy(fieldNameRef, source);
Assignment assignment = new Assignment(fieldRef, fieldNameRef, (int)p);
diff --git a/src/core/lombok/eclipse/handlers/HandleToString.java b/src/core/lombok/eclipse/handlers/HandleToString.java
index b3f4abaa..f39cb129 100644
--- a/src/core/lombok/eclipse/handlers/HandleToString.java
+++ b/src/core/lombok/eclipse/handlers/HandleToString.java
@@ -38,6 +38,7 @@ import lombok.core.AST.Kind;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
+import lombok.eclipse.handlers.EclipseHandlerUtil.FieldAccess;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
@@ -94,7 +95,7 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> {
try {
includeFieldNames = ((Boolean)ToString.class.getMethod("includeFieldNames").getDefaultValue()).booleanValue();
} catch (Exception ignore) {}
- generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, false);
+ generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, FieldAccess.GETTER);
}
public boolean handle(AnnotationValues<ToString> annotation, Annotation ast, EclipseNode annotationNode) {
@@ -115,11 +116,13 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> {
checkForBogusFieldNames(typeNode, annotation);
- return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, ann.doNotUseGetters());
+ FieldAccess fieldAccess = ann.doNotUseGetters() ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER;
+
+ return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, fieldAccess);
}
public boolean generateToString(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes,
- boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) {
+ boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess) {
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
@@ -161,7 +164,7 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> {
switch (methodExists("toString", typeNode)) {
case NOT_EXISTS:
- MethodDeclaration toString = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get(), useFieldsDirectly);
+ MethodDeclaration toString = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get(), fieldAccess);
injectMethod(typeNode, toString);
return true;
case EXISTS_BY_LOMBOK:
@@ -176,7 +179,7 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> {
}
private MethodDeclaration createToString(EclipseNode type, Collection<EclipseNode> fields,
- boolean includeFieldNames, boolean callSuper, ASTNode source, boolean useFieldsDirectly) {
+ boolean includeFieldNames, boolean callSuper, ASTNode source, FieldAccess fieldAccess) {
String typeName = getTypeName(type);
char[] suffix = ")".toCharArray();
String infixS = ", ";
@@ -214,8 +217,8 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> {
}
for (EclipseNode field : fields) {
- TypeReference fType = getFieldType(field, useFieldsDirectly);
- Expression fieldAccessor = createFieldAccessor(field, useFieldsDirectly, source);
+ TypeReference fType = getFieldType(field, fieldAccess);
+ Expression fieldAccessor = createFieldAccessor(field, fieldAccess, source);
Expression ex;
if (fType.dimensions() > 0) {