aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoel Spilker <r.spilker@gmail.com>2011-07-18 20:59:52 +0200
committerRoel Spilker <r.spilker@gmail.com>2011-07-18 21:05:00 +0200
commit83e2fb5e00e1868f0b4f0fe38b1ea1383119f8ee (patch)
tree68f44e863293287e989b120a1d15de88de338a2a
parentaa1a0e7ac87f5e96a39d0bad670aa8c7b7df85d4 (diff)
downloadlombok-83e2fb5e00e1868f0b4f0fe38b1ea1383119f8ee.tar.gz
lombok-83e2fb5e00e1868f0b4f0fe38b1ea1383119f8ee.tar.bz2
lombok-83e2fb5e00e1868f0b4f0fe38b1ea1383119f8ee.zip
Now either all or none of equals/hashCode/canEqual is generated. Fixes issue 240.
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java2
-rw-r--r--src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java58
-rw-r--r--src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java63
-rw-r--r--src/core/lombok/javac/handlers/JavacHandlerUtil.java2
-rw-r--r--test/transform/resource/after-delombok/EqualsAndHashCode.java99
-rw-r--r--test/transform/resource/after-delombok/EqualsAndHashCodeWithExistingMethods.java18
-rw-r--r--test/transform/resource/after-ecj/EqualsAndHashCode.java109
-rw-r--r--test/transform/resource/after-ecj/EqualsAndHashCodeWithExistingMethods.java27
-rw-r--r--test/transform/resource/after-eclipse/EqualsAndHashCode.java109
-rw-r--r--test/transform/resource/after-eclipse/EqualsAndHashCodeWithExistingMethods.java27
-rw-r--r--test/transform/resource/before/EqualsAndHashCode.java20
-rw-r--r--test/transform/resource/before/EqualsAndHashCodeWithExistingMethods.java26
-rw-r--r--test/transform/resource/messages-delombok/EqualsAndHashCodeWithExistingMethods.java.messages3
-rw-r--r--test/transform/resource/messages-ecj/EqualsAndHashCodeWithExistingMethods.java.messages3
-rw-r--r--test/transform/resource/messages-eclipse/EqualsAndHashCodeWithExistingMethods.java.messages3
-rw-r--r--website/features/EqualsAndHashCode.html6
16 files changed, 496 insertions, 79 deletions
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 159a1994..627acecb 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -292,7 +292,7 @@ public class EclipseHandlerUtil {
/** Serves as return value for the methods that check for the existence of fields and methods. */
public enum MemberExistsResult {
- NOT_EXISTS, EXISTS_BY_USER, EXISTS_BY_LOMBOK;
+ NOT_EXISTS, EXISTS_BY_LOMBOK, EXISTS_BY_USER;
}
/**
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index 05fbd0e2..db45c087 100644
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -203,52 +203,36 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
}
}
- boolean needsCanEqual = false;
- switch (methodExists("equals", typeNode)) {
- case NOT_EXISTS:
- boolean isFinal = (typeDecl.modifiers & ClassFileConstants.AccFinal) != 0;
- needsCanEqual = !isDirectDescendantOfObject || !isFinal;
-
- MethodDeclaration equals = createEquals(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess, needsCanEqual);
- injectMethod(typeNode, equals);
- break;
+ boolean isFinal = (typeDecl.modifiers & ClassFileConstants.AccFinal) != 0;
+ boolean needsCanEqual = !isDirectDescendantOfObject || !isFinal;
+ java.util.List<MemberExistsResult> existsResults = new ArrayList<MemberExistsResult>();
+ existsResults.add(methodExists("equals", typeNode));
+ existsResults.add(methodExists("hashCode", typeNode));
+ existsResults.add(methodExists("canEqual", typeNode));
+ switch (Collections.max(existsResults)) {
case EXISTS_BY_LOMBOK:
- break;
- default:
+ return;
case EXISTS_BY_USER:
if (whineIfExists) {
- errorNode.addWarning("Not generating equals(Object other): A method with that name already exists");
+ String msg = String.format("Not generating equals%s: A method with one of those names already exists. (Either all or none of these methods will be generated).", needsCanEqual ? ", hashCode and canEquals" : " and hashCode");
+ errorNode.addWarning(msg);
}
- break;
+ return;
+ case NOT_EXISTS:
+ default:
+ //fallthrough
}
+ MethodDeclaration equalsMethod = createEquals(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess, needsCanEqual);
+ injectMethod(typeNode, equalsMethod);
+
if (needsCanEqual) {
- switch (methodExists("canEqual", typeNode)) {
- case NOT_EXISTS:
- MethodDeclaration equals = createCanEqual(typeNode, errorNode.get());
- injectMethod(typeNode, equals);
- break;
- case EXISTS_BY_LOMBOK:
- case EXISTS_BY_USER:
- default:
- break;
- }
+ MethodDeclaration canEqualMethod = createCanEqual(typeNode, errorNode.get());
+ injectMethod(typeNode, canEqualMethod);
}
- switch (methodExists("hashCode", typeNode)) {
- case NOT_EXISTS:
- MethodDeclaration hashCode = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess);
- injectMethod(typeNode, hashCode);
- break;
- case EXISTS_BY_LOMBOK:
- break;
- default:
- case EXISTS_BY_USER:
- if (whineIfExists) {
- errorNode.addWarning("Not generating hashCode(): A method with that name already exists");
- }
- break;
- }
+ MethodDeclaration hashCodeMethod = createHashCode(typeNode, nodesForEquality, callSuper, errorNode.get(), fieldAccess);
+ injectMethod(typeNode, hashCodeMethod);
}
private MethodDeclaration createHashCode(EclipseNode type, Collection<EclipseNode> fields, boolean callSuper, ASTNode source, FieldAccess fieldAccess) {
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index d77be508..eb733eb4 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -22,6 +22,10 @@
package lombok.javac.handlers;
import static lombok.javac.handlers.JavacHandlerUtil.*;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
import lombok.EqualsAndHashCode;
import lombok.core.AnnotationValues;
import lombok.core.AST.Kind;
@@ -170,51 +174,36 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
}
}
- boolean needsCanEqual = false;
- switch (methodExists("equals", typeNode)) {
- case NOT_EXISTS:
- boolean isFinal = (((JCClassDecl)typeNode.get()).mods.flags & Flags.FINAL) != 0;
- needsCanEqual = !isFinal || !isDirectDescendantOfObject;
-
- JCMethodDecl method = createEquals(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, needsCanEqual, source.get());
- injectMethod(typeNode, method);
- break;
+ boolean isFinal = (((JCClassDecl)typeNode.get()).mods.flags & Flags.FINAL) != 0;
+ boolean needsCanEqual = !isFinal || !isDirectDescendantOfObject;
+ java.util.List<MemberExistsResult> existsResults = new ArrayList<MemberExistsResult>();
+ existsResults.add(methodExists("equals", typeNode));
+ existsResults.add(methodExists("hashCode", typeNode));
+ existsResults.add(methodExists("canEqual", typeNode));
+ switch (Collections.max(existsResults)) {
case EXISTS_BY_LOMBOK:
- break;
- default:
+ return;
case EXISTS_BY_USER:
if (whineIfExists) {
- source.addWarning("Not generating equals(Object other): A method with that name already exists");
+ String msg = String.format("Not generating equals%s: A method with one of those names already exists. (Either all or none of these methods will be generated).", needsCanEqual ? ", hashCode and canEquals" : " and hashCode");
+ source.addWarning(msg);
}
- break;
+ return;
+ case NOT_EXISTS:
+ default:
+ //fallthrough
}
+ JCMethodDecl equalsMethod = createEquals(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, needsCanEqual, source.get());
+ injectMethod(typeNode, equalsMethod);
+
if (needsCanEqual) {
- switch (methodExists("canEqual", typeNode)) {
- case NOT_EXISTS:
- JCMethodDecl method = createCanEqual(typeNode, source.get());
- injectMethod(typeNode, method);
- break;
- case EXISTS_BY_LOMBOK:
- case EXISTS_BY_USER:
- default:
- break;
- }
- }
- switch (methodExists("hashCode", typeNode)) {
- case NOT_EXISTS:
- JCMethodDecl method = createHashCode(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, source.get());
- injectMethod(typeNode, method);
- break;
- case EXISTS_BY_LOMBOK:
- break;
- default:
- case EXISTS_BY_USER:
- if (whineIfExists) {
- source.addWarning("Not generating hashCode(): A method with that name already exists");
- }
- break;
+ JCMethodDecl canEqualMethod = createCanEqual(typeNode, source.get());
+ injectMethod(typeNode, canEqualMethod);
}
+
+ JCMethodDecl hashCodeMethod = createHashCode(typeNode, nodesForEquality.toList(), callSuper, fieldAccess, source.get());
+ injectMethod(typeNode, hashCodeMethod);
}
private JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, JCTree source) {
diff --git a/src/core/lombok/javac/handlers/JavacHandlerUtil.java b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
index 0cbe2c83..03a9142b 100644
--- a/src/core/lombok/javac/handlers/JavacHandlerUtil.java
+++ b/src/core/lombok/javac/handlers/JavacHandlerUtil.java
@@ -185,7 +185,7 @@ public class JavacHandlerUtil {
/** Serves as return value for the methods that check for the existence of fields and methods. */
public enum MemberExistsResult {
- NOT_EXISTS, EXISTS_BY_USER, EXISTS_BY_LOMBOK;
+ NOT_EXISTS, EXISTS_BY_LOMBOK, EXISTS_BY_USER;
}
/**
diff --git a/test/transform/resource/after-delombok/EqualsAndHashCode.java b/test/transform/resource/after-delombok/EqualsAndHashCode.java
new file mode 100644
index 00000000..e7f701e8
--- /dev/null
+++ b/test/transform/resource/after-delombok/EqualsAndHashCode.java
@@ -0,0 +1,99 @@
+class EqualsAndHashCode {
+ int x;
+ boolean[] y;
+ Object[] z;
+ String a;
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public boolean equals(final java.lang.Object o) {
+ if (o == this) return true;
+ if (!(o instanceof EqualsAndHashCode)) return false;
+ final EqualsAndHashCode other = (EqualsAndHashCode)o;
+ if (!other.canEqual((java.lang.Object)this)) return false;
+ if (this.x != other.x) return false;
+ if (!java.util.Arrays.equals(this.y, other.y)) return false;
+ if (!java.util.Arrays.deepEquals(this.z, other.z)) return false;
+ if (this.a == null ? other.a != null : !this.a.equals((java.lang.Object)other.a)) return false;
+ return true;
+ }
+ @java.lang.SuppressWarnings("all")
+ public boolean canEqual(final java.lang.Object other) {
+ return other instanceof EqualsAndHashCode;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = result * PRIME + this.x;
+ result = result * PRIME + java.util.Arrays.hashCode(this.y);
+ result = result * PRIME + java.util.Arrays.deepHashCode(this.z);
+ result = result * PRIME + (this.a == null ? 0 : this.a.hashCode());
+ return result;
+ }
+}
+final class EqualsAndHashCode2 {
+ int x;
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public boolean equals(final java.lang.Object o) {
+ if (o == this) return true;
+ if (!(o instanceof EqualsAndHashCode2)) return false;
+ final EqualsAndHashCode2 other = (EqualsAndHashCode2)o;
+ if (this.x != other.x) return false;
+ return true;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = result * PRIME + this.x;
+ return result;
+ }
+}
+final class EqualsAndHashCode3 extends EqualsAndHashCode {
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public boolean equals(final java.lang.Object o) {
+ if (o == this) return true;
+ if (!(o instanceof EqualsAndHashCode3)) return false;
+ final EqualsAndHashCode3 other = (EqualsAndHashCode3)o;
+ if (!other.canEqual((java.lang.Object)this)) return false;
+ return true;
+ }
+ @java.lang.SuppressWarnings("all")
+ public boolean canEqual(final java.lang.Object other) {
+ return other instanceof EqualsAndHashCode3;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public int hashCode() {
+ int result = 1;
+ return result;
+ }
+}
+class EqualsAndHashCode4 extends EqualsAndHashCode {
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public boolean equals(final java.lang.Object o) {
+ if (o == this) return true;
+ if (!(o instanceof EqualsAndHashCode4)) return false;
+ final EqualsAndHashCode4 other = (EqualsAndHashCode4)o;
+ if (!other.canEqual((java.lang.Object)this)) return false;
+ if (!super.equals(o)) return false;
+ return true;
+ }
+ @java.lang.SuppressWarnings("all")
+ public boolean canEqual(final java.lang.Object other) {
+ return other instanceof EqualsAndHashCode4;
+ }
+ @java.lang.Override
+ @java.lang.SuppressWarnings("all")
+ public int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = result * PRIME + super.hashCode();
+ return result;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/after-delombok/EqualsAndHashCodeWithExistingMethods.java b/test/transform/resource/after-delombok/EqualsAndHashCodeWithExistingMethods.java
new file mode 100644
index 00000000..93b20e25
--- /dev/null
+++ b/test/transform/resource/after-delombok/EqualsAndHashCodeWithExistingMethods.java
@@ -0,0 +1,18 @@
+class EqualsAndHashCodeWithExistingMethods {
+ int x;
+ public int hashCode() {
+ return 42;
+ }
+}
+final class EqualsAndHashCodeWithExistingMethods2 {
+ int x;
+ public boolean equals(Object other) {
+ return false;
+ }
+}
+final class EqualsAndHashCodeWithExistingMethods3 extends EqualsAndHashCodeWithExistingMethods {
+ int x;
+ public boolean canEqual(Object other) {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/after-ecj/EqualsAndHashCode.java b/test/transform/resource/after-ecj/EqualsAndHashCode.java
new file mode 100644
index 00000000..bb757b00
--- /dev/null
+++ b/test/transform/resource/after-ecj/EqualsAndHashCode.java
@@ -0,0 +1,109 @@
+@lombok.EqualsAndHashCode class EqualsAndHashCode {
+ int x;
+ boolean[] y;
+ Object[] z;
+ String a;
+ public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof EqualsAndHashCode)))
+ return false;
+ final EqualsAndHashCode other = (EqualsAndHashCode) o;
+ if ((! other.canEqual((java.lang.Object) this)))
+ return false;
+ if ((this.x != other.x))
+ return false;
+ if ((! java.util.Arrays.equals(this.y, other.y)))
+ return false;
+ if ((! java.util.Arrays.deepEquals(this.z, other.z)))
+ return false;
+ if (((this.a == null) ? (other.a != null) : (! this.a.equals((java.lang.Object) other.a))))
+ return false;
+ return true;
+ }
+ public @java.lang.SuppressWarnings("all") boolean canEqual(final java.lang.Object other) {
+ return (other instanceof EqualsAndHashCode);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = ((result * PRIME) + this.x);
+ result = ((result * PRIME) + java.util.Arrays.hashCode(this.y));
+ result = ((result * PRIME) + java.util.Arrays.deepHashCode(this.z));
+ result = ((result * PRIME) + ((this.a == null) ? 0 : this.a.hashCode()));
+ return result;
+ }
+ EqualsAndHashCode() {
+ super();
+ }
+}
+final @lombok.EqualsAndHashCode class EqualsAndHashCode2 {
+ int x;
+ public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof EqualsAndHashCode2)))
+ return false;
+ final EqualsAndHashCode2 other = (EqualsAndHashCode2) o;
+ if ((this.x != other.x))
+ return false;
+ return true;
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = ((result * PRIME) + this.x);
+ return result;
+ }
+ EqualsAndHashCode2() {
+ super();
+ }
+}
+final @lombok.EqualsAndHashCode(callSuper = false) class EqualsAndHashCode3 extends EqualsAndHashCode {
+ public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof EqualsAndHashCode3)))
+ return false;
+ final EqualsAndHashCode3 other = (EqualsAndHashCode3) o;
+ if ((! other.canEqual((java.lang.Object) this)))
+ return false;
+ return true;
+ }
+ public @java.lang.SuppressWarnings("all") boolean canEqual(final java.lang.Object other) {
+ return (other instanceof EqualsAndHashCode3);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
+ int result = 1;
+ return result;
+ }
+ EqualsAndHashCode3() {
+ super();
+ }
+}
+@lombok.EqualsAndHashCode(callSuper = true) class EqualsAndHashCode4 extends EqualsAndHashCode {
+ public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof EqualsAndHashCode4)))
+ return false;
+ final EqualsAndHashCode4 other = (EqualsAndHashCode4) o;
+ if ((! other.canEqual((java.lang.Object) this)))
+ return false;
+ if ((! super.equals(o)))
+ return false;
+ return true;
+ }
+ public @java.lang.SuppressWarnings("all") boolean canEqual(final java.lang.Object other) {
+ return (other instanceof EqualsAndHashCode4);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = ((result * PRIME) + super.hashCode());
+ return result;
+ }
+ EqualsAndHashCode4() {
+ super();
+ }
+}
diff --git a/test/transform/resource/after-ecj/EqualsAndHashCodeWithExistingMethods.java b/test/transform/resource/after-ecj/EqualsAndHashCodeWithExistingMethods.java
new file mode 100644
index 00000000..50b219f1
--- /dev/null
+++ b/test/transform/resource/after-ecj/EqualsAndHashCodeWithExistingMethods.java
@@ -0,0 +1,27 @@
+@lombok.EqualsAndHashCode class EqualsAndHashCodeWithExistingMethods {
+ int x;
+ EqualsAndHashCodeWithExistingMethods() {
+ super();
+ }
+ public int hashCode() {
+ return 42;
+ }
+}
+final @lombok.EqualsAndHashCode class EqualsAndHashCodeWithExistingMethods2 {
+ int x;
+ EqualsAndHashCodeWithExistingMethods2() {
+ super();
+ }
+ public boolean equals(Object other) {
+ return false;
+ }
+}
+final @lombok.EqualsAndHashCode(callSuper = true) class EqualsAndHashCodeWithExistingMethods3 extends EqualsAndHashCodeWithExistingMethods {
+ int x;
+ EqualsAndHashCodeWithExistingMethods3() {
+ super();
+ }
+ public boolean canEqual(Object other) {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/after-eclipse/EqualsAndHashCode.java b/test/transform/resource/after-eclipse/EqualsAndHashCode.java
new file mode 100644
index 00000000..bb757b00
--- /dev/null
+++ b/test/transform/resource/after-eclipse/EqualsAndHashCode.java
@@ -0,0 +1,109 @@
+@lombok.EqualsAndHashCode class EqualsAndHashCode {
+ int x;
+ boolean[] y;
+ Object[] z;
+ String a;
+ public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof EqualsAndHashCode)))
+ return false;
+ final EqualsAndHashCode other = (EqualsAndHashCode) o;
+ if ((! other.canEqual((java.lang.Object) this)))
+ return false;
+ if ((this.x != other.x))
+ return false;
+ if ((! java.util.Arrays.equals(this.y, other.y)))
+ return false;
+ if ((! java.util.Arrays.deepEquals(this.z, other.z)))
+ return false;
+ if (((this.a == null) ? (other.a != null) : (! this.a.equals((java.lang.Object) other.a))))
+ return false;
+ return true;
+ }
+ public @java.lang.SuppressWarnings("all") boolean canEqual(final java.lang.Object other) {
+ return (other instanceof EqualsAndHashCode);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = ((result * PRIME) + this.x);
+ result = ((result * PRIME) + java.util.Arrays.hashCode(this.y));
+ result = ((result * PRIME) + java.util.Arrays.deepHashCode(this.z));
+ result = ((result * PRIME) + ((this.a == null) ? 0 : this.a.hashCode()));
+ return result;
+ }
+ EqualsAndHashCode() {
+ super();
+ }
+}
+final @lombok.EqualsAndHashCode class EqualsAndHashCode2 {
+ int x;
+ public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof EqualsAndHashCode2)))
+ return false;
+ final EqualsAndHashCode2 other = (EqualsAndHashCode2) o;
+ if ((this.x != other.x))
+ return false;
+ return true;
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = ((result * PRIME) + this.x);
+ return result;
+ }
+ EqualsAndHashCode2() {
+ super();
+ }
+}
+final @lombok.EqualsAndHashCode(callSuper = false) class EqualsAndHashCode3 extends EqualsAndHashCode {
+ public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof EqualsAndHashCode3)))
+ return false;
+ final EqualsAndHashCode3 other = (EqualsAndHashCode3) o;
+ if ((! other.canEqual((java.lang.Object) this)))
+ return false;
+ return true;
+ }
+ public @java.lang.SuppressWarnings("all") boolean canEqual(final java.lang.Object other) {
+ return (other instanceof EqualsAndHashCode3);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
+ int result = 1;
+ return result;
+ }
+ EqualsAndHashCode3() {
+ super();
+ }
+}
+@lombok.EqualsAndHashCode(callSuper = true) class EqualsAndHashCode4 extends EqualsAndHashCode {
+ public @java.lang.Override @java.lang.SuppressWarnings("all") boolean equals(final java.lang.Object o) {
+ if ((o == this))
+ return true;
+ if ((! (o instanceof EqualsAndHashCode4)))
+ return false;
+ final EqualsAndHashCode4 other = (EqualsAndHashCode4) o;
+ if ((! other.canEqual((java.lang.Object) this)))
+ return false;
+ if ((! super.equals(o)))
+ return false;
+ return true;
+ }
+ public @java.lang.SuppressWarnings("all") boolean canEqual(final java.lang.Object other) {
+ return (other instanceof EqualsAndHashCode4);
+ }
+ public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
+ final int PRIME = 31;
+ int result = 1;
+ result = ((result * PRIME) + super.hashCode());
+ return result;
+ }
+ EqualsAndHashCode4() {
+ super();
+ }
+}
diff --git a/test/transform/resource/after-eclipse/EqualsAndHashCodeWithExistingMethods.java b/test/transform/resource/after-eclipse/EqualsAndHashCodeWithExistingMethods.java
new file mode 100644
index 00000000..50b219f1
--- /dev/null
+++ b/test/transform/resource/after-eclipse/EqualsAndHashCodeWithExistingMethods.java
@@ -0,0 +1,27 @@
+@lombok.EqualsAndHashCode class EqualsAndHashCodeWithExistingMethods {
+ int x;
+ EqualsAndHashCodeWithExistingMethods() {
+ super();
+ }
+ public int hashCode() {
+ return 42;
+ }
+}
+final @lombok.EqualsAndHashCode class EqualsAndHashCodeWithExistingMethods2 {
+ int x;
+ EqualsAndHashCodeWithExistingMethods2() {
+ super();
+ }
+ public boolean equals(Object other) {
+ return false;
+ }
+}
+final @lombok.EqualsAndHashCode(callSuper = true) class EqualsAndHashCodeWithExistingMethods3 extends EqualsAndHashCodeWithExistingMethods {
+ int x;
+ EqualsAndHashCodeWithExistingMethods3() {
+ super();
+ }
+ public boolean canEqual(Object other) {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/before/EqualsAndHashCode.java b/test/transform/resource/before/EqualsAndHashCode.java
new file mode 100644
index 00000000..1688c1fc
--- /dev/null
+++ b/test/transform/resource/before/EqualsAndHashCode.java
@@ -0,0 +1,20 @@
+@lombok.EqualsAndHashCode
+class EqualsAndHashCode {
+ int x;
+ boolean[] y;
+ Object[] z;
+ String a;
+}
+
+@lombok.EqualsAndHashCode
+final class EqualsAndHashCode2 {
+ int x;
+}
+
+@lombok.EqualsAndHashCode(callSuper=false)
+final class EqualsAndHashCode3 extends EqualsAndHashCode {
+}
+
+@lombok.EqualsAndHashCode(callSuper=true)
+class EqualsAndHashCode4 extends EqualsAndHashCode {
+} \ No newline at end of file
diff --git a/test/transform/resource/before/EqualsAndHashCodeWithExistingMethods.java b/test/transform/resource/before/EqualsAndHashCodeWithExistingMethods.java
new file mode 100644
index 00000000..be90d871
--- /dev/null
+++ b/test/transform/resource/before/EqualsAndHashCodeWithExistingMethods.java
@@ -0,0 +1,26 @@
+@lombok.EqualsAndHashCode
+class EqualsAndHashCodeWithExistingMethods {
+ int x;
+
+ public int hashCode() {
+ return 42;
+ }
+}
+
+@lombok.EqualsAndHashCode
+final class EqualsAndHashCodeWithExistingMethods2 {
+ int x;
+
+ public boolean equals(Object other) {
+ return false;
+ }
+}
+
+@lombok.EqualsAndHashCode(callSuper=true)
+final class EqualsAndHashCodeWithExistingMethods3 extends EqualsAndHashCodeWithExistingMethods {
+ int x;
+
+ public boolean canEqual(Object other) {
+ return true;
+ }
+} \ No newline at end of file
diff --git a/test/transform/resource/messages-delombok/EqualsAndHashCodeWithExistingMethods.java.messages b/test/transform/resource/messages-delombok/EqualsAndHashCodeWithExistingMethods.java.messages
new file mode 100644
index 00000000..dd78e67f
--- /dev/null
+++ b/test/transform/resource/messages-delombok/EqualsAndHashCodeWithExistingMethods.java.messages
@@ -0,0 +1,3 @@
+1:1 WARNING Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated).
+10:1 WARNING Not generating equals and hashCode: A method with one of those names already exists. (Either all or none of these methods will be generated).
+19:1 WARNING Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated).
diff --git a/test/transform/resource/messages-ecj/EqualsAndHashCodeWithExistingMethods.java.messages b/test/transform/resource/messages-ecj/EqualsAndHashCodeWithExistingMethods.java.messages
new file mode 100644
index 00000000..3ad31311
--- /dev/null
+++ b/test/transform/resource/messages-ecj/EqualsAndHashCodeWithExistingMethods.java.messages
@@ -0,0 +1,3 @@
+1 warning Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated).
+10 warning Not generating equals and hashCode: A method with one of those names already exists. (Either all or none of these methods will be generated).
+19 warning Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated).
diff --git a/test/transform/resource/messages-eclipse/EqualsAndHashCodeWithExistingMethods.java.messages b/test/transform/resource/messages-eclipse/EqualsAndHashCodeWithExistingMethods.java.messages
new file mode 100644
index 00000000..3ad31311
--- /dev/null
+++ b/test/transform/resource/messages-eclipse/EqualsAndHashCodeWithExistingMethods.java.messages
@@ -0,0 +1,3 @@
+1 warning Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated).
+10 warning Not generating equals and hashCode: A method with one of those names already exists. (Either all or none of these methods will be generated).
+19 warning Not generating equals, hashCode and canEquals: A method with one of those names already exists. (Either all or none of these methods will be generated).
diff --git a/website/features/EqualsAndHashCode.html b/website/features/EqualsAndHashCode.html
index e79760df..b683c2b3 100644
--- a/website/features/EqualsAndHashCode.html
+++ b/website/features/EqualsAndHashCode.html
@@ -65,9 +65,9 @@
return false. This is analogous to <code>java.lang.Double</code>'s equals method, and is in fact required to ensure that comparing an object
to an exact copy of itself returns <code>true</code> for equality.
</p><p>
- If there is <em>any</em> method named either <code>hashCode</code> or <code>equals</code>, regardless of parameters or return type,
- that method will not be generated, and a warning is emitted instead. <code>hashCode</code> and <code>equals</code> need to be in sync with
- each other, which lombok cannot guarantee if it is only generating one of the two methods, hence you always get a warning if one <em>or</em> both
+ If there is <em>any</em> method named either <code>hashCode</code>, <code>equals</code> or <code>canEqual</code>, regardless of
+ parameters or return type, no methods will be generated, and a warning is emitted instead. These 3 methods need to be in sync with
+ each other, which lombok cannot guarantee unless it generates all the methods, hence you always get a warning if one <em>or</em> more
of the methods already exist.
</p><p>
Attempting to exclude fields that don't exist or would have been excluded anyway (because they are static or transient) results in warnings on the named fields.