aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java82
-rw-r--r--src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java2
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java57
4 files changed, 117 insertions, 26 deletions
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 337ae3a8..29e44781 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -46,6 +46,7 @@ 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.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NameReference;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
@@ -98,34 +99,87 @@ public class EclipseHandlerUtil {
}
}
+ private static AbstractMethodDeclaration findGetter(EclipseNode field) {
+ TypeReference fieldType = ((FieldDeclaration)field.get()).type;
+ boolean isBoolean = nameEquals(fieldType.getTypeName(), "boolean") && fieldType.dimensions() == 0;
+ EclipseNode typeNode = field.up();
+ for (String potentialGetterName : TransformationsUtil.toAllGetterNames(field.getName(), isBoolean)) {
+ switch (methodExists(potentialGetterName, typeNode, false)) {
+ case EXISTS_BY_LOMBOK:
+ case EXISTS_BY_USER:
+ for (EclipseNode potentialGetter : typeNode.down()) {
+ if (potentialGetter.getKind() != Kind.METHOD) continue;
+ AbstractMethodDeclaration method = (AbstractMethodDeclaration) potentialGetter.get();
+ /** static getX() methods don't count. */
+ if ((method.modifiers & ClassFileConstants.AccStatic) != 0) continue;
+ /** Nor do getters with a non-empty parameter list. */
+ if (method.arguments != null && method.arguments.length > 0) continue;
+ return method;
+ }
+ }
+ }
+
+ return null;
+ }
+
static TypeReference getFieldType(EclipseNode field, boolean useFieldsDirectly) {
- return ((FieldDeclaration)field.get()).type;
+ AbstractMethodDeclaration getter = useFieldsDirectly ? null : findGetter(field);
+ if (!(getter instanceof MethodDeclaration)) {
+ return ((FieldDeclaration)field.get()).type;
+ }
+
+ return ((MethodDeclaration)getter).returnType;
}
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;
+
+ AbstractMethodDeclaration getter = useFieldsDirectly ? null : findGetter(field);
+
+ if (getter == null) {
+ 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;
+ }
+
+ MessageSend call = new MessageSend();
+ Eclipse.setGeneratedBy(call, source);
+ call.sourceStart = pS; call.sourceEnd = pE;
+ call.receiver = new ThisReference(pS, pE);
+ Eclipse.setGeneratedBy(call.receiver, source);
+ call.selector = getter.selector;
+ return call;
}
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;
+ AbstractMethodDeclaration getter = useFieldsDirectly ? null : findGetter(field);
- char[][] tokens = new char[2][];
- tokens[0] = receiver;
- tokens[1] = field.getName().toCharArray();
- long[] poss = {p, p};
+ if (getter == null) {
+ 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;
+ }
- ref = new QualifiedNameReference(tokens, poss, pS, pE);
- Eclipse.setGeneratedBy(ref, source);
- return ref;
+ MessageSend call = new MessageSend();
+ Eclipse.setGeneratedBy(call, source);
+ call.sourceStart = pS; call.sourceEnd = pE;
+ call.receiver = new SingleNameReference(receiver, p);
+ Eclipse.setGeneratedBy(call.receiver, source);
+ call.selector = getter.selector;
+ return call;
}
/**
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index b7c6cda6..2142618f 100644
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -353,7 +353,7 @@ public class HandleEqualsAndHashCode implements EclipseAnnotationHandler<EqualsA
MessageSend hashCodeCall = new MessageSend();
hashCodeCall.sourceStart = pS; hashCodeCall.sourceEnd = pE;
Eclipse.setGeneratedBy(hashCodeCall, source);
- hashCodeCall.receiver = fieldAccessor;
+ hashCodeCall.receiver = createFieldAccessor(field, useFieldsDirectly, source);
hashCodeCall.selector = "hashCode".toCharArray();
NullLiteral nullLiteral = new NullLiteral(pS, pE);
Eclipse.setGeneratedBy(nullLiteral, source);
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index 66d2308a..20ede725 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -281,7 +281,7 @@ public class HandleEqualsAndHashCode implements JavacAnnotationHandler<EqualsAnd
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(fieldAccessor, typeNode.toName("hashCode")),
+ JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(createFieldAccessor(maker, fieldNode, useFieldsDirectly), typeNode.toName("hashCode")),
List.<JCExpression>nil());
JCExpression thisEqualsNull = maker.Binary(JCTree.EQ, fieldAccessor, maker.Literal(TypeTags.BOT, null));
intoResult = intoResult.append(
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 84388c30..cb2697f1 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -41,6 +41,7 @@ import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
import com.sun.tools.javac.tree.JCTree.JCExpression;
import com.sun.tools.javac.tree.JCTree.JCImport;
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
+import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
import com.sun.tools.javac.util.List;
@@ -269,15 +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);
+ private static JCMethodDecl findGetter(JavacNode field) {
+ JCVariableDecl decl = (JCVariableDecl)field.get();
+ JavacNode typeNode = field.up();
+ for (String potentialGetterName : toAllGetterNames(decl)) {
+ switch (methodExists(potentialGetterName, typeNode, false)) {
+ case EXISTS_BY_LOMBOK:
+ case EXISTS_BY_USER:
+ for (JavacNode potentialGetter : typeNode.down()) {
+ if (potentialGetter.getKind() != Kind.METHOD) continue;
+ JCMethodDecl method = (JCMethodDecl) potentialGetter.get();
+ /** 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 null;
}
/**
@@ -286,7 +298,32 @@ public class JavacHandlerUtil {
* @see #createFieldAccessor(TreeMaker, JavacNode)
*/
static JCExpression getFieldType(JavacNode field, boolean useFieldsDirectly) {
- return ((JCVariableDecl)field.get()).vartype;
+ JCMethodDecl getter = useFieldsDirectly ? null : findGetter(field);
+
+ if (getter == null) {
+ return ((JCVariableDecl)field.get()).vartype;
+ }
+
+ return getter.restype;
+ }
+
+ /**
+ * 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) {
+ JCMethodDecl getter = useFieldsDirectly ? null : findGetter(field);
+
+ if (getter == null) {
+ return maker.Select(receiver, ((JCVariableDecl)field.get()).name);
+ }
+
+ JCMethodInvocation call = maker.Apply(List.<JCExpression>nil(),
+ maker.Select(receiver, getter.name), List.<JCExpression>nil());
+ return call;
}
/**