aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/EqualsAndHashCode.java8
-rw-r--r--src/core/lombok/ToString.java8
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java36
-rw-r--r--src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java95
-rw-r--r--src/core/lombok/eclipse/handlers/HandleToString.java12
-rw-r--r--src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java62
-rw-r--r--src/core/lombok/javac/handlers/HandleToString.java22
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java22
8 files changed, 156 insertions, 109 deletions
diff --git a/src/core/lombok/EqualsAndHashCode.java b/src/core/lombok/EqualsAndHashCode.java
index 88d72051..92fa42b5 100644
--- a/src/core/lombok/EqualsAndHashCode.java
+++ b/src/core/lombok/EqualsAndHashCode.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
@@ -77,4 +77,10 @@ public @interface EqualsAndHashCode {
* <strong>default: false</strong>
*/
boolean callSuper() default false;
+
+ /**
+ * Normally, if getters are available, those are called. To suppress this and let the generated code use the fields directly, set this to {@code true}.
+ * <strong>default: false</strong>
+ */
+ boolean doNotUseGetters() default false;
}
diff --git a/src/core/lombok/ToString.java b/src/core/lombok/ToString.java
index 7b89d481..1247b7bb 100644
--- a/src/core/lombok/ToString.java
+++ b/src/core/lombok/ToString.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
@@ -78,4 +78,10 @@ public @interface ToString {
* <strong>default: false</strong>
*/
boolean callSuper() default false;
+
+ /**
+ * Normally, if getters are available, those are called. To suppress this and let the generated code use the fields directly, set this to {@code true}.
+ * <strong>default: false</strong>
+ */
+ boolean doNotUseGetters() default false;
}
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index fc76ddc0..337ae3a8 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.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
@@ -43,16 +43,20 @@ import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
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.MethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.NameReference;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
+import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
+import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
@@ -94,6 +98,36 @@ public class EclipseHandlerUtil {
}
}
+ static TypeReference getFieldType(EclipseNode field, boolean useFieldsDirectly) {
+ return ((FieldDeclaration)field.get()).type;
+ }
+
+ static Expression createFieldAccessor(EclipseNode field, boolean useFieldsDirectly, ASTNode source) {
+ int pS = source.sourceStart, pE = source.sourceEnd;
+ long p = (long)pS << 32 | pE;
+ FieldReference thisX = new FieldReference(field.getName().toCharArray(), p);
+ Eclipse.setGeneratedBy(thisX, source);
+ thisX.receiver = new ThisReference(pS, pE);
+ Eclipse.setGeneratedBy(thisX.receiver, source);
+ return thisX;
+ }
+
+ static Expression createFieldAccessor(EclipseNode field, boolean useFieldsDirectly, ASTNode source, char[] receiver) {
+ int pS = source.sourceStart, pE = source.sourceEnd;
+ long p = (long)pS << 32 | pE;
+
+ NameReference ref;
+
+ char[][] tokens = new char[2][];
+ tokens[0] = receiver;
+ tokens[1] = field.getName().toCharArray();
+ long[] poss = {p, p};
+
+ ref = new QualifiedNameReference(tokens, poss, pS, pE);
+ Eclipse.setGeneratedBy(ref, source);
+ return ref;
+ }
+
/**
* Checks if an eclipse-style array-of-array-of-characters to represent a fully qualified name ('foo.bar.baz'), matches a plain
* string containing the same fully qualified name with dots in the string.
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index ef0bc9be..b7c6cda6 100644
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.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,7 +46,6 @@ import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
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.IntLiteral;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
@@ -58,7 +57,6 @@ import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
-import org.eclipse.jdt.internal.compiler.ast.Reference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
@@ -114,7 +112,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
}
}
- generateMethods(typeNode, errorNode, null, null, null, false);
+ generateMethods(typeNode, errorNode, null, null, null, false, false);
}
@Override public boolean handle(AnnotationValues<EqualsAndHashCode> annotation,
@@ -136,11 +134,11 @@ 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);
+ return generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, ann.doNotUseGetters());
}
public boolean generateMethods(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes,
- Boolean callSuper, boolean whineIfExists) {
+ Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) {
assert excludes == null || includes == null;
TypeDeclaration typeDecl = null;
@@ -206,7 +204,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
switch (methodExists("equals", typeNode)) {
case NOT_EXISTS:
- MethodDeclaration equals = createEquals(typeNode, nodesForEquality, callSuper, errorNode.get());
+ MethodDeclaration equals = createEquals(typeNode, nodesForEquality, callSuper, errorNode.get(), useFieldsDirectly);
injectMethod(typeNode, equals);
break;
case EXISTS_BY_LOMBOK:
@@ -221,7 +219,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
switch (methodExists("hashCode", typeNode)) {
case NOT_EXISTS:
- MethodDeclaration hashCode = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get());
+ MethodDeclaration hashCode = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get(), useFieldsDirectly);
injectMethod(typeNode, hashCode);
break;
case EXISTS_BY_LOMBOK:
@@ -237,7 +235,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
return true;
}
- private MethodDeclaration createHashCode(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source) {
+ private MethodDeclaration createHashCode(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, boolean useFieldsDirectly) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
@@ -302,9 +300,10 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
int tempCounter = 0;
for (EclipseNode field : fields) {
- FieldDeclaration f = (FieldDeclaration) field.get();
- char[] token = f.type.getLastToken();
- if (f.type.dimensions() == 0 && token != null) {
+ TypeReference fType = getFieldType(field, useFieldsDirectly);
+ char[] token = fType.getLastToken();
+ Expression fieldAccessor = createFieldAccessor(field, useFieldsDirectly, source);
+ if (fType.dimensions() == 0 && token != null) {
if (Arrays.equals(TypeConstants.FLOAT, token)) {
/* Float.floatToIntBits(fieldName) */
MessageSend floatToIntBits = new MessageSend();
@@ -312,7 +311,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
Eclipse.setGeneratedBy(floatToIntBits, source);
floatToIntBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_FLOAT);
floatToIntBits.selector = "floatToIntBits".toCharArray();
- floatToIntBits.arguments = new Expression[] { generateFieldReference(f.name, source) };
+ floatToIntBits.arguments = new Expression[] { fieldAccessor };
intoResult.add(floatToIntBits);
} else if (Arrays.equals(TypeConstants.DOUBLE, token)) {
/* longToIntForHashCode(Double.doubleToLongBits(fieldName)) */
@@ -321,7 +320,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
Eclipse.setGeneratedBy(doubleToLongBits, source);
doubleToLongBits.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_DOUBLE);
doubleToLongBits.selector = "doubleToLongBits".toCharArray();
- doubleToLongBits.arguments = new Expression[] { generateFieldReference(f.name, source) };
+ doubleToLongBits.arguments = new Expression[] { fieldAccessor };
final char[] tempName = ("temp" + ++tempCounter).toCharArray();
LocalDeclaration tempVar = new LocalDeclaration(tempName, pS, pE);
Eclipse.setGeneratedBy(tempVar, source);
@@ -342,25 +341,23 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
Eclipse.setGeneratedBy(int1231, source);
IntLiteral int1237 = new IntLiteral("1237".toCharArray(), pS, pE);
Eclipse.setGeneratedBy(int1237, source);
- ConditionalExpression int1231or1237 = new ConditionalExpression(
- generateFieldReference(f.name, source), int1231, int1237);
+ ConditionalExpression int1231or1237 = new ConditionalExpression(fieldAccessor, int1231, int1237);
Eclipse.setGeneratedBy(int1231or1237, source);
intoResult.add(int1231or1237);
} else if (Arrays.equals(TypeConstants.LONG, token)) {
- intoResult.add(longToIntForHashCode(generateFieldReference(f.name, source), generateFieldReference(f.name, source), source));
+ intoResult.add(longToIntForHashCode(fieldAccessor, createFieldAccessor(field, useFieldsDirectly, source), source));
} else if (BUILT_IN_TYPES.contains(new String(token))) {
- intoResult.add(generateFieldReference(f.name, source));
+ intoResult.add(fieldAccessor);
} else /* objects */ {
/* this.fieldName == null ? 0 : this.fieldName.hashCode() */
MessageSend hashCodeCall = new MessageSend();
hashCodeCall.sourceStart = pS; hashCodeCall.sourceEnd = pE;
Eclipse.setGeneratedBy(hashCodeCall, source);
- hashCodeCall.receiver = generateFieldReference(f.name, source);
+ hashCodeCall.receiver = fieldAccessor;
hashCodeCall.selector = "hashCode".toCharArray();
NullLiteral nullLiteral = new NullLiteral(pS, pE);
Eclipse.setGeneratedBy(nullLiteral, source);
- EqualExpression objIsNull = new EqualExpression(
- generateFieldReference(f.name, source), nullLiteral, OperatorIds.EQUAL_EQUAL);
+ EqualExpression objIsNull = new EqualExpression(fieldAccessor, nullLiteral, OperatorIds.EQUAL_EQUAL);
Eclipse.setGeneratedBy(objIsNull, source);
IntLiteral int0 = new IntLiteral("0".toCharArray(), pS, pE);
Eclipse.setGeneratedBy(int0, source);
@@ -369,18 +366,18 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
Eclipse.setGeneratedBy(nullOrHashCode, source);
intoResult.add(nullOrHashCode);
}
- } else if (f.type.dimensions() > 0 && token != null) {
+ } else if (fType.dimensions() > 0 && token != null) {
/* Arrays.deepHashCode(array) //just hashCode for simple arrays */
MessageSend arraysHashCodeCall = new MessageSend();
arraysHashCodeCall.sourceStart = pS; arraysHashCodeCall.sourceEnd = pE;
Eclipse.setGeneratedBy(arraysHashCodeCall, source);
arraysHashCodeCall.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray());
- if (f.type.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) {
+ if (fType.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) {
arraysHashCodeCall.selector = "deepHashCode".toCharArray();
} else {
arraysHashCodeCall.selector = "hashCode".toCharArray();
}
- arraysHashCodeCall.arguments = new Expression[] { generateFieldReference(f.name, source) };
+ arraysHashCodeCall.arguments = new Expression[] { fieldAccessor };
intoResult.add(arraysHashCodeCall);
}
}
@@ -418,7 +415,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
return method;
}
- private MethodDeclaration createEquals(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source) {
+ private MethodDeclaration createEquals(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, boolean useFieldsDirectly) {
int pS = source.sourceStart; int pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
@@ -559,17 +556,18 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
}
for (EclipseNode field : fields) {
- FieldDeclaration f = (FieldDeclaration) field.get();
- char[] token = f.type.getLastToken();
+ TypeReference fType = getFieldType(field, useFieldsDirectly);
+ char[] token = fType.getLastToken();
+ Expression thisFieldAccessor = createFieldAccessor(field, useFieldsDirectly, source);
+ Expression otherFieldAccessor = createFieldAccessor(field, useFieldsDirectly, source, otherN);
- if (f.type.dimensions() == 0 && token != null) {
+ if (fType.dimensions() == 0 && token != null) {
if (Arrays.equals(TypeConstants.FLOAT, token)) {
- statements.add(generateCompareFloatOrDouble(otherN, "Float".toCharArray(), f.name, source));
+ statements.add(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, "Float".toCharArray(), source));
} else if (Arrays.equals(TypeConstants.DOUBLE, token)) {
- statements.add(generateCompareFloatOrDouble(otherN, "Double".toCharArray(), f.name, source));
+ statements.add(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, "Double".toCharArray(), source));
} else if (BUILT_IN_TYPES.contains(new String(token))) {
- EqualExpression fieldsNotEqual = new EqualExpression(generateFieldReference(f.name, source),
- generateQualifiedNameRef(source, otherN, f.name), OperatorIds.NOT_EQUAL);
+ EqualExpression fieldsNotEqual = new EqualExpression(thisFieldAccessor, otherFieldAccessor, OperatorIds.NOT_EQUAL);
Eclipse.setGeneratedBy(fieldsNotEqual, source);
FalseLiteral falseLiteral = new FalseLiteral(pS, pE);
Eclipse.setGeneratedBy(falseLiteral, source);
@@ -581,18 +579,16 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
} else /* objects */ {
NullLiteral nullLiteral = new NullLiteral(pS, pE);
Eclipse.setGeneratedBy(nullLiteral, source);
- EqualExpression fieldIsNull = new EqualExpression(generateFieldReference(f.name, source), nullLiteral, OperatorIds.EQUAL_EQUAL);
+ EqualExpression fieldIsNull = new EqualExpression(thisFieldAccessor, nullLiteral, OperatorIds.EQUAL_EQUAL);
nullLiteral = new NullLiteral(pS, pE);
Eclipse.setGeneratedBy(nullLiteral, source);
- EqualExpression otherFieldIsntNull = new EqualExpression(
- generateQualifiedNameRef(source, otherN, f.name),
- nullLiteral, OperatorIds.NOT_EQUAL);
+ EqualExpression otherFieldIsntNull = new EqualExpression(otherFieldAccessor, nullLiteral, OperatorIds.NOT_EQUAL);
MessageSend equalsCall = new MessageSend();
equalsCall.sourceStart = pS; equalsCall.sourceEnd = pE;
Eclipse.setGeneratedBy(equalsCall, source);
- equalsCall.receiver = generateFieldReference(f.name, source);
+ equalsCall.receiver = createFieldAccessor(field, useFieldsDirectly, source);
equalsCall.selector = "equals".toCharArray();
- equalsCall.arguments = new Expression[] { generateQualifiedNameRef(source, otherN, f.name) };
+ equalsCall.arguments = new Expression[] { createFieldAccessor(field, useFieldsDirectly, source, otherN) };
UnaryExpression fieldsNotEqual = new UnaryExpression(equalsCall, OperatorIds.NOT);
fieldsNotEqual.sourceStart = pS; fieldsNotEqual.sourceEnd = pE;
Eclipse.setGeneratedBy(fieldsNotEqual, source);
@@ -607,17 +603,17 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
Eclipse.setGeneratedBy(ifStatement, source);
statements.add(ifStatement);
}
- } else if (f.type.dimensions() > 0 && token != null) {
+ } else if (fType.dimensions() > 0 && token != null) {
MessageSend arraysEqualCall = new MessageSend();
arraysEqualCall.sourceStart = pS; arraysEqualCall.sourceEnd = pE;
Eclipse.setGeneratedBy(arraysEqualCall, source);
arraysEqualCall.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.UTIL, "Arrays".toCharArray());
- if (f.type.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) {
+ if (fType.dimensions() > 1 || !BUILT_IN_TYPES.contains(new String(token))) {
arraysEqualCall.selector = "deepEquals".toCharArray();
} else {
arraysEqualCall.selector = "equals".toCharArray();
}
- arraysEqualCall.arguments = new Expression[] { generateFieldReference(f.name, source), generateQualifiedNameRef(source, otherN, f.name) };
+ arraysEqualCall.arguments = new Expression[] { thisFieldAccessor, otherFieldAccessor };
UnaryExpression arraysNotEqual = new UnaryExpression(arraysEqualCall, OperatorIds.NOT);
arraysNotEqual.sourceStart = pS; arraysNotEqual.sourceEnd = pE;
Eclipse.setGeneratedBy(arraysNotEqual, source);
@@ -642,7 +638,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
return method;
}
- private IfStatement generateCompareFloatOrDouble(char[] otherN, char[] floatOrDouble, char[] fieldName, ASTNode source) {
+ private IfStatement generateCompareFloatOrDouble(Expression thisRef, Expression otherRef, char[] floatOrDouble, ASTNode source) {
int pS = source.sourceStart, pE = source.sourceEnd;
/* if (Float.compare(fieldName, other.fieldName) != 0) return false */
MessageSend floatCompare = new MessageSend();
@@ -650,7 +646,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
Eclipse.setGeneratedBy(floatCompare, source);
floatCompare.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA, TypeConstants.LANG, floatOrDouble);
floatCompare.selector = "compare".toCharArray();
- floatCompare.arguments = new Expression[] {generateFieldReference(fieldName, source), generateQualifiedNameRef(source, otherN, fieldName)};
+ floatCompare.arguments = new Expression[] {thisRef, otherRef};
IntLiteral int0 = new IntLiteral(new char[] {'0'}, pS, pE);
Eclipse.setGeneratedBy(int0, source);
EqualExpression ifFloatCompareIsNot0 = new EqualExpression(floatCompare, int0, OperatorIds.NOT_EQUAL);
@@ -666,7 +662,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
}
/** Give 2 clones! */
- private Expression longToIntForHashCode(Reference ref1, Reference ref2, ASTNode source) {
+ private Expression longToIntForHashCode(Expression ref1, Expression ref2, ASTNode source) {
int pS = source.sourceStart, pE = source.sourceEnd;
/* (int)(ref >>> 32 ^ ref) */
IntLiteral int32 = new IntLiteral("32".toCharArray(), pS, pE);
@@ -684,17 +680,6 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
return expr;
}
- private Reference generateFieldReference(char[] fieldName, ASTNode source) {
- int pS = source.sourceStart, pE = source.sourceEnd;
- long p = (long)pS << 32 | pE;
- FieldReference thisX = new FieldReference(fieldName, p);
- Eclipse.setGeneratedBy(thisX, source);
- thisX.receiver = new ThisReference(pS, pE);
- Eclipse.setGeneratedBy(thisX.receiver, source);
- thisX.token = fieldName;
- return thisX;
- }
-
private NameReference generateQualifiedNameRef(ASTNode source, char[]... varNames) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long)pS << 32 | pE;
diff --git a/src/core/lombok/eclipse/handlers/HandleToString.java b/src/core/lombok/eclipse/handlers/HandleToString.java
index 5b87e32b..f409b5c4 100644
--- a/src/core/lombok/eclipse/handlers/HandleToString.java
+++ b/src/core/lombok/eclipse/handlers/HandleToString.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
@@ -95,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);
+ generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, false);
}
public boolean handle(AnnotationValues<ToString> annotation, Annotation ast, EclipseNode annotationNode) {
@@ -116,11 +116,11 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> {
checkForBogusFieldNames(typeNode, annotation);
- return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true);
+ return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, ann.doNotUseGetters());
}
public boolean generateToString(EclipseNode typeNode, EclipseNode errorNode, List<String> excludes, List<String> includes,
- boolean includeFieldNames, Boolean callSuper, boolean whineIfExists) {
+ boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) {
TypeDeclaration typeDecl = null;
if (typeNode.get() instanceof TypeDeclaration) typeDecl = (TypeDeclaration) typeNode.get();
@@ -162,7 +162,7 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> {
switch (methodExists("toString", typeNode)) {
case NOT_EXISTS:
- MethodDeclaration toString = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get());
+ MethodDeclaration toString = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, errorNode.get(), useFieldsDirectly);
injectMethod(typeNode, toString);
return true;
case EXISTS_BY_LOMBOK:
@@ -177,7 +177,7 @@ public class HandleToString implements EclipseAnnotationHandler<ToString> {
}
private MethodDeclaration createToString(EclipseNode type, Collection<EclipseNode> fields,
- boolean includeFieldNames, boolean callSuper, ASTNode source) {
+ boolean includeFieldNames, boolean callSuper, ASTNode source, boolean useFieldsDirectly) {
TypeDeclaration typeDeclaration = (TypeDeclaration)type.get();
char[] rawTypeName = typeDeclaration.name;
String typeName = rawTypeName == null ? "" : new String(rawTypeName);
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index 4ee24391..66d2308a 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.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
@@ -90,7 +90,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored.");
}
- return generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true);
+ return generateMethods(typeNode, annotationNode, excludes, includes, callSuper, true, ann.doNotUseGetters());
}
public void generateEqualsAndHashCodeForType(JavacNode typeNode, JavacNode errorNode) {
@@ -103,11 +103,11 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
}
}
- generateMethods(typeNode, errorNode, null, null, null, false);
+ generateMethods(typeNode, errorNode, null, null, null, false, false);
}
private boolean generateMethods(JavacNode typeNode, JavacNode errorNode, List<String> excludes, List<String> includes,
- Boolean callSuper, boolean whineIfExists) {
+ Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) {
boolean notAClass = true;
if (typeNode.get() instanceof JCClassDecl) {
long flags = ((JCClassDecl)typeNode.get()).mods.flags;
@@ -169,7 +169,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
switch (methodExists("equals", typeNode)) {
case NOT_EXISTS:
- JCMethodDecl method = createEquals(typeNode, nodesForEquality, callSuper);
+ JCMethodDecl method = createEquals(typeNode, nodesForEquality, callSuper, useFieldsDirectly);
injectMethod(typeNode, method);
break;
case EXISTS_BY_LOMBOK:
@@ -184,7 +184,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
switch (methodExists("hashCode", typeNode)) {
case NOT_EXISTS:
- JCMethodDecl method = createHashCode(typeNode, nodesForEquality, callSuper);
+ JCMethodDecl method = createHashCode(typeNode, nodesForEquality, callSuper, useFieldsDirectly);
injectMethod(typeNode, method);
break;
case EXISTS_BY_LOMBOK:
@@ -200,7 +200,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
return true;
}
- private JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper) {
+ private JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, boolean useFieldsDirectly) {
TreeMaker maker = typeNode.getTreeMaker();
JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.<JCExpression>nil());
@@ -232,25 +232,23 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
int tempCounter = 0;
for (JavacNode fieldNode : fields) {
- JCVariableDecl field = (JCVariableDecl) fieldNode.get();
- JCExpression fType = field.vartype;
- JCExpression thisDotField = maker.Select(maker.Ident(typeNode.toName("this")), field.name);
- JCExpression thisDotFieldClone = maker.Select(maker.Ident(typeNode.toName("this")), field.name);
+ JCExpression fType = getFieldType(fieldNode, useFieldsDirectly);
+ JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, useFieldsDirectly);
if (fType instanceof JCPrimitiveTypeTree) {
switch (((JCPrimitiveTypeTree)fType).getPrimitiveTypeKind()) {
case BOOLEAN:
/* this.fieldName ? 1231 : 1237 */
- intoResult = intoResult.append(maker.Conditional(thisDotField, maker.Literal(1231), maker.Literal(1237)));
+ intoResult = intoResult.append(maker.Conditional(fieldAccessor, maker.Literal(1231), maker.Literal(1237)));
break;
case LONG:
- intoResult = intoResult.append(longToIntForHashCode(maker, thisDotField, thisDotFieldClone));
+ intoResult = intoResult.append(longToIntForHashCode(maker, fieldAccessor, createFieldAccessor(maker, fieldNode, useFieldsDirectly)));
break;
case FLOAT:
/* Float.floatToIntBits(this.fieldName) */
intoResult = intoResult.append(maker.Apply(
List.<JCExpression>nil(),
chainDots(maker, typeNode, "java", "lang", "Float", "floatToIntBits"),
- List.of(thisDotField)));
+ List.of(fieldAccessor)));
break;
case DOUBLE:
/* longToIntForHashCode(Double.doubleToLongBits(this.fieldName)) */
@@ -258,7 +256,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
JCExpression init = maker.Apply(
List.<JCExpression>nil(),
chainDots(maker, typeNode, "java", "lang", "Double", "doubleToLongBits"),
- List.of(thisDotField));
+ List.of(fieldAccessor));
statements = statements.append(
maker.VarDef(maker.Modifiers(Flags.FINAL), tempVar, maker.TypeIdent(TypeTags.LONG), init));
intoResult = intoResult.append(longToIntForHashCode(maker, maker.Ident(tempVar), maker.Ident(tempVar)));
@@ -269,7 +267,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
case INT:
case CHAR:
/* just the field */
- intoResult = intoResult.append(thisDotField);
+ intoResult = intoResult.append(fieldAccessor);
break;
}
} else if (fType instanceof JCArrayTypeTree) {
@@ -280,12 +278,12 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
JCExpression hcMethod = chainDots(maker, typeNode, "java", "util", "Arrays", useDeepHC ? "deepHashCode" : "hashCode");
intoResult = intoResult.append(
- maker.Apply(List.<JCExpression>nil(), hcMethod, List.of(thisDotField)));
+ maker.Apply(List.<JCExpression>nil(), hcMethod, List.of(fieldAccessor)));
} else /* objects */ {
/* this.fieldName == null ? 0 : this.fieldName.hashCode() */
- JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(thisDotField, typeNode.toName("hashCode")),
+ JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(fieldAccessor, typeNode.toName("hashCode")),
List.<JCExpression>nil());
- JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, thisDotField, maker.Literal(TypeTags.BOT, null));
+ JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, fieldAccessor, maker.Literal(TypeTags.BOT, null));
intoResult = intoResult.append(
maker.Conditional(thisEqualsNull, maker.Literal(0), hcCall));
}
@@ -316,7 +314,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
return maker.TypeCast(maker.TypeIdent(TypeTags.INT), xorBits);
}
- private JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper) {
+ private JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, boolean useFieldsDirectly) {
TreeMaker maker = typeNode.getTreeMaker();
JCClassDecl type = (JCClassDecl) typeNode.get();
@@ -382,24 +380,23 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
}
for (JavacNode fieldNode : fields) {
- JCVariableDecl field = (JCVariableDecl) fieldNode.get();
- JCExpression fType = field.vartype;
- JCExpression thisDotField = maker.Select(maker.Ident(thisName), field.name);
- JCExpression otherDotField = maker.Select(maker.Ident(otherName), field.name);
+ JCExpression fType = getFieldType(fieldNode, useFieldsDirectly);
+ JCExpression thisFieldAccessor = createFieldAccessor(maker, fieldNode, useFieldsDirectly);
+ JCExpression otherFieldAccessor = createFieldAccessor(maker, fieldNode, useFieldsDirectly, maker.Ident(otherName));
if (fType instanceof JCPrimitiveTypeTree) {
switch (((JCPrimitiveTypeTree)fType).getPrimitiveTypeKind()) {
case FLOAT:
/* if (Float.compare(this.fieldName, other.fieldName) != 0) return false; */
- statements = statements.append(generateCompareFloatOrDouble(thisDotField, otherDotField, maker, typeNode, false));
+ statements = statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, false));
break;
case DOUBLE:
/* if (Double(this.fieldName, other.fieldName) != 0) return false; */
- statements = statements.append(generateCompareFloatOrDouble(thisDotField, otherDotField, maker, typeNode, true));
+ statements = statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, true));
break;
default:
/* if (this.fieldName != other.fieldName) return false; */
statements = statements.append(
- maker.If(maker.Binary(JCTree.NE, thisDotField, otherDotField), returnBool(maker, false), null));
+ maker.If(maker.Binary(JCTree.NE, thisFieldAccessor, otherFieldAccessor), returnBool(maker, false), null));
break;
}
} else if (fType instanceof JCArrayTypeTree) {
@@ -409,15 +406,16 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
boolean useDeepEquals = multiDim || !primitiveArray;
JCExpression eqMethod = chainDots(maker, typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals");
- List<JCExpression> args = List.of(thisDotField, otherDotField);
+ List<JCExpression> args = List.of(thisFieldAccessor, otherFieldAccessor);
statements = statements.append(maker.If(maker.Unary(JCTree.NOT,
maker.Apply(List.<JCExpression>nil(), eqMethod, args)), returnBool(maker, false), null));
} else /* objects */ {
/* if (this.fieldName == null ? other.fieldName != null : !this.fieldName.equals(other.fieldName)) return false; */
- JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, thisDotField, maker.Literal(TypeTags.BOT, null));
- JCExpression otherNotEqualsNull = maker.Binary(JCTree.NE, otherDotField, maker.Literal(TypeTags.BOT, null));
- JCExpression thisEqualsThat = maker.Apply(
- List.<JCExpression>nil(), maker.Select(thisDotField, typeNode.toName("equals")), List.of(otherDotField));
+ JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, thisFieldAccessor, maker.Literal(TypeTags.BOT, null));
+ JCExpression otherNotEqualsNull = maker.Binary(JCTree.NE, thisFieldAccessor, maker.Literal(TypeTags.BOT, null));
+ JCExpression thisEqualsThat = maker.Apply(List.<JCExpression>nil(),
+ maker.Select(createFieldAccessor(maker, fieldNode, useFieldsDirectly), typeNode.toName("equals")),
+ List.of(createFieldAccessor(maker, fieldNode, useFieldsDirectly, maker.Ident(otherName))));
JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(JCTree.NOT, thisEqualsThat));
statements = statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null));
}
diff --git a/src/core/lombok/javac/handlers/HandleToString.java b/src/core/lombok/javac/handlers/HandleToString.java
index cdba7558..7b1b3b81 100644
--- a/src/core/lombok/javac/handlers/HandleToString.java
+++ b/src/core/lombok/javac/handlers/HandleToString.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
@@ -40,7 +40,6 @@ import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree;
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;
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCModifiers;
@@ -89,7 +88,7 @@ public class HandleToString implements JavacAnnotationHandler<ToString> {
annotation.setWarning("exclude", "exclude and of are mutually exclusive; the 'exclude' parameter will be ignored.");
}
- return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true);
+ return generateToString(typeNode, annotationNode, excludes, includes, ann.includeFieldNames(), callSuper, true, ann.doNotUseGetters());
}
public void generateToStringForType(JavacNode typeNode, JavacNode errorNode) {
@@ -106,11 +105,11 @@ public class HandleToString implements JavacAnnotationHandler<ToString> {
try {
includeFieldNames = ((Boolean)ToString.class.getMethod("includeFieldNames").getDefaultValue()).booleanValue();
} catch (Exception ignore) {}
- generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false);
+ generateToString(typeNode, errorNode, null, null, includeFieldNames, null, false, false);
}
private boolean generateToString(JavacNode typeNode, JavacNode errorNode, List<String> excludes, List<String> includes,
- boolean includeFieldNames, Boolean callSuper, boolean whineIfExists) {
+ boolean includeFieldNames, Boolean callSuper, boolean whineIfExists, boolean useFieldsDirectly) {
boolean notAClass = true;
if (typeNode.get() instanceof JCClassDecl) {
long flags = ((JCClassDecl)typeNode.get()).mods.flags;
@@ -151,7 +150,7 @@ public class HandleToString implements JavacAnnotationHandler<ToString> {
switch (methodExists("toString", typeNode)) {
case NOT_EXISTS:
- JCMethodDecl method = createToString(typeNode, nodesForToString, includeFieldNames, callSuper);
+ JCMethodDecl method = createToString(typeNode, nodesForToString, includeFieldNames, callSuper, useFieldsDirectly);
injectMethod(typeNode, method);
return true;
case EXISTS_BY_LOMBOK:
@@ -166,7 +165,7 @@ public class HandleToString implements JavacAnnotationHandler<ToString> {
}
- private JCMethodDecl createToString(JavacNode typeNode, List<JavacNode> fields, boolean includeFieldNames, boolean callSuper) {
+ private JCMethodDecl createToString(JavacNode typeNode, List<JavacNode> fields, boolean includeFieldNames, boolean callSuper, boolean useFieldsDirectly) {
TreeMaker maker = typeNode.getTreeMaker();
JCAnnotation overrideAnnotation = maker.Annotation(chainDots(maker, typeNode, "java", "lang", "Override"), List.<JCExpression>nil());
@@ -203,16 +202,16 @@ public class HandleToString implements JavacAnnotationHandler<ToString> {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
JCExpression expr;
- JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), field.name);
+ JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, useFieldsDirectly);
- if (field.vartype instanceof JCArrayTypeTree) {
+ if (getFieldType(fieldNode, useFieldsDirectly) instanceof JCArrayTypeTree) {
boolean multiDim = ((JCArrayTypeTree)field.vartype).elemtype instanceof JCArrayTypeTree;
boolean primitiveArray = ((JCArrayTypeTree)field.vartype).elemtype instanceof JCPrimitiveTypeTree;
boolean useDeepTS = multiDim || !primitiveArray;
JCExpression hcMethod = chainDots(maker, typeNode, "java", "util", "Arrays", useDeepTS ? "deepToString" : "toString");
- expr = maker.Apply(List.<JCExpression>nil(), hcMethod, List.<JCExpression>of(thisX));
- } else expr = thisX;
+ expr = maker.Apply(List.<JCExpression>nil(), hcMethod, List.<JCExpression>of(fieldAccessor));
+ } else expr = fieldAccessor;
if (first) {
current = maker.Binary(JCTree.PLUS, current, expr);
@@ -238,5 +237,4 @@ public class HandleToString implements JavacAnnotationHandler<ToString> {
return maker.MethodDef(mods, typeNode.toName("toString"), returnType,
List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
-
}
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 9ac84bd1..84388c30 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.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
@@ -270,6 +270,26 @@ public class JavacHandlerUtil {
}
/**
+ * Creates an expression that reads the field. Will either be {@code this.field} or {@code this.getField()} depending on whether or not there's a getter.
+ */
+ static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, boolean useFieldsDirectly) {
+ return createFieldAccessor(maker, field, useFieldsDirectly, maker.Ident(field.toName("this")));
+ }
+
+ static JCExpression createFieldAccessor(TreeMaker maker, JavacNode field, boolean useFieldsDirectly, JCExpression receiver) {
+ return maker.Select(receiver, ((JCVariableDecl)field.get()).name);
+ }
+
+ /**
+ * Returns the type of the field, unless a getter exists for this field, in which case the return type of the getter is returned.
+ *
+ * @see #createFieldAccessor(TreeMaker, JavacNode)
+ */
+ static JCExpression getFieldType(JavacNode field, boolean useFieldsDirectly) {
+ return ((JCVariableDecl)field.get()).vartype;
+ }
+
+ /**
* Adds the given new field declaration to the provided type AST Node.
*
* Also takes care of updating the JavacAST.