diff options
author | Andre Brait <andrebrait@gmail.com> | 2020-08-19 17:59:19 +0200 |
---|---|---|
committer | Roel Spilker <r.spilker@gmail.com> | 2020-09-24 22:25:15 +0200 |
commit | 8d004c0638e4b865c38527a500c493288328eac8 (patch) | |
tree | 33c9db820c79f980ab596d6501a802ceb7b0237a | |
parent | 0808d4271a495e1b6ea4f9a636e63a1c62567133 (diff) | |
download | lombok-8d004c0638e4b865c38527a500c493288328eac8.tar.gz lombok-8d004c0638e4b865c38527a500c493288328eac8.tar.bz2 lombok-8d004c0638e4b865c38527a500c493288328eac8.zip |
Allow non-final types, use Integer.MIN_VALUE
Allow caching hash code for non-final classes (but will warn)
Use Integer.MIN_VALUE to differentiate uncached and 0 cached
6 files changed, 53 insertions, 24 deletions
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index 37379bb9..d5fa5618 100755 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -231,16 +231,16 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH } if (cacheHashCode){ - if (!isFinal) { - String msg = "Not caching the result of hashCode: Annotated type is not final."; - errorNode.addWarning(msg); - cacheHashCode = false; - } else if (fieldExists(HASH_CODE_CACHE_NAME, typeNode) != MemberExistsResult.NOT_EXISTS) { + if (fieldExists(HASH_CODE_CACHE_NAME, typeNode) != MemberExistsResult.NOT_EXISTS) { String msg = String.format("Not caching the result of hashCode: A field named %s already exists.", HASH_CODE_CACHE_NAME); errorNode.addWarning(msg); cacheHashCode = false; } else { createHashCodeCacheField(typeNode, errorNode.get()); + if (!isFinal) { + String msg = "Caching the result of hashCode for non-final type."; + errorNode.addWarning(msg); + } } } @@ -444,7 +444,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH } } - /* this.$hashCodeCache = result; */ { + /* this.$hashCodeCache = result != 0 ? result : Integer.MIN_VALUE; */ { if (cacheHashCode) { FieldReference hashCodeCacheRef = new FieldReference(HASH_CODE_CACHE_NAME_ARR, p); hashCodeCacheRef.receiver = new ThisReference(pS, pE); @@ -452,7 +452,16 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH setGeneratedBy(hashCodeCacheRef.receiver, source); SingleNameReference resultRef = new SingleNameReference(RESULT, p); setGeneratedBy(resultRef, source); - Assignment cacheResult = new Assignment(hashCodeCacheRef, resultRef, pE); + EqualExpression resultNotZero = new EqualExpression(resultRef, makeIntLiteral("0".toCharArray(), source), OperatorIds.NOT_EQUAL); + setGeneratedBy(resultNotZero, source); + FieldReference integerMinValue = new FieldReference("MIN_VALUE".toCharArray(), p); + integerMinValue.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_INTEGER); + setGeneratedBy(integerMinValue, source); + resultRef = new SingleNameReference(RESULT, p); + setGeneratedBy(resultRef, source); + ConditionalExpression notZeroOrIntegerMin = new ConditionalExpression(resultNotZero, resultRef, integerMinValue); + setGeneratedBy(notZeroOrIntegerMin, source); + Assignment cacheResult = new Assignment(hashCodeCacheRef, notZeroOrIntegerMin, pE); cacheResult.sourceStart = pS; cacheResult.statementEnd = cacheResult.sourceEnd = pE; setGeneratedBy(cacheResult, source); statements.add(cacheResult); diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index 58078038..d90fdada 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -40,6 +40,7 @@ import com.sun.tools.javac.tree.JCTree.JCArrayTypeTree; import com.sun.tools.javac.tree.JCTree.JCBinary; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCClassDecl; +import com.sun.tools.javac.tree.JCTree.JCConditional; import com.sun.tools.javac.tree.JCTree.JCExpression; import com.sun.tools.javac.tree.JCTree.JCExpressionStatement; import com.sun.tools.javac.tree.JCTree.JCFieldAccess; @@ -204,16 +205,16 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } if (cacheHashCode){ - if (!isFinal) { - String msg = "Not caching the result of hashCode: Annotated type is not final."; - source.addWarning(msg); - cacheHashCode = false; - } else if (fieldExists(HASH_CODE_CACHE_NAME, typeNode) != MemberExistsResult.NOT_EXISTS) { + if (fieldExists(HASH_CODE_CACHE_NAME, typeNode) != MemberExistsResult.NOT_EXISTS) { String msg = String.format("Not caching the result of hashCode: A field named %s already exists.", HASH_CODE_CACHE_NAME); source.addWarning(msg); cacheHashCode = false; } else { createHashCodeCacheField(typeNode, source.get()); + if (!isFinal) { + String msg = "Caching the result of hashCode for non-final type."; + source.addWarning(msg); + } } } @@ -348,11 +349,14 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas } } - /* this.$hashCodeCache = result; */ { + /* this.$hashCodeCache = result != 0 ? result : Integer.MIN_VALUE; */ { if (cacheHashCode) { JCIdent receiver = maker.Ident(typeNode.toName("this")); JCFieldAccess cacheHashCodeFieldAccess = maker.Select(receiver, typeNode.toName(HASH_CODE_CACHE_NAME)); - statements.append(maker.Exec(maker.Assign(cacheHashCodeFieldAccess, maker.Ident(resultName)))); + JCExpression resultNotZero = maker.Binary(CTC_NOT_EQUAL, maker.Ident(resultName), maker.Literal(CTC_INT, 0)); + JCExpression integerMinValue = genJavaLangTypeRef(typeNode, "Integer", "MIN_VALUE"); + JCConditional notZeroOrIntegerMin = maker.Conditional(resultNotZero, maker.Ident(resultName), integerMinValue); + statements.append(maker.Exec(maker.Assign(cacheHashCodeFieldAccess, notZeroOrIntegerMin))); } } diff --git a/test/transform/resource/after-delombok/EqualsAndHashCodeCache.java b/test/transform/resource/after-delombok/EqualsAndHashCodeCache.java index a028cca7..e76f74d5 100644 --- a/test/transform/resource/after-delombok/EqualsAndHashCodeCache.java +++ b/test/transform/resource/after-delombok/EqualsAndHashCodeCache.java @@ -1,4 +1,6 @@ class EqualsAndHashCode { + @java.lang.SuppressWarnings("all") + private transient int $hashCodeCache = 0; int x; boolean[] y; Object[] z; @@ -29,6 +31,7 @@ class EqualsAndHashCode { @java.lang.Override @java.lang.SuppressWarnings("all") public int hashCode() { + if (this.$hashCodeCache != 0) return this.$hashCodeCache; final int PRIME = 59; int result = 1; result = result * PRIME + this.x; @@ -38,6 +41,7 @@ class EqualsAndHashCode { result = result * PRIME + ($a == null ? 43 : $a.hashCode()); final java.lang.Object $b = this.b; result = result * PRIME + ($b == null ? 43 : $b.hashCode()); + this.$hashCodeCache = result != 0 ? result : java.lang.Integer.MIN_VALUE; return result; } } @@ -75,7 +79,7 @@ final class EqualsAndHashCode2 { final long $d = java.lang.Double.doubleToLongBits(this.d); result = result * PRIME + (int) ($d >>> 32 ^ $d); result = result * PRIME + (this.b ? 79 : 97); - this.$hashCodeCache = result; + this.$hashCodeCache = result != 0 ? result : java.lang.Integer.MIN_VALUE; return result; } } @@ -100,11 +104,13 @@ final class EqualsAndHashCode3 extends EqualsAndHashCode { public int hashCode() { if (this.$hashCodeCache != 0) return this.$hashCodeCache; final int result = 1; - this.$hashCodeCache = result; + this.$hashCodeCache = result != 0 ? result : java.lang.Integer.MIN_VALUE; return result; } } class EqualsAndHashCode4 extends EqualsAndHashCode { + @java.lang.SuppressWarnings("all") + private transient int $hashCodeCache = 0; @java.lang.Override @java.lang.SuppressWarnings("all") public boolean equals(final java.lang.Object o) { @@ -122,7 +128,9 @@ class EqualsAndHashCode4 extends EqualsAndHashCode { @java.lang.Override @java.lang.SuppressWarnings("all") public int hashCode() { + if (this.$hashCodeCache != 0) return this.$hashCodeCache; final int result = super.hashCode(); + this.$hashCodeCache = result != 0 ? result : java.lang.Integer.MIN_VALUE; return result; } } @@ -148,7 +156,7 @@ final class EqualsAndHashCode5 extends EqualsAndHashCode { public int hashCode() { if (this.$hashCodeCache != 0) return this.$hashCodeCache; final int result = super.hashCode(); - this.$hashCodeCache = result; + this.$hashCodeCache = result != 0 ? result : java.lang.Integer.MIN_VALUE; return result; } } diff --git a/test/transform/resource/after-ecj/EqualsAndHashCodeCache.java b/test/transform/resource/after-ecj/EqualsAndHashCodeCache.java index 3c4d0daa..b29fd6b3 100644 --- a/test/transform/resource/after-ecj/EqualsAndHashCodeCache.java +++ b/test/transform/resource/after-ecj/EqualsAndHashCodeCache.java @@ -1,4 +1,5 @@ @lombok.EqualsAndHashCode(cacheStrategy = lombok.EqualsAndHashCode.CacheStrategy.LAZY) class EqualsAndHashCode { + private transient @java.lang.SuppressWarnings("all") int $hashCodeCache = 0; int x; boolean[] y; Object[] z; @@ -35,6 +36,8 @@ return (other instanceof EqualsAndHashCode); } public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() { + if ((this.$hashCodeCache != 0)) + return this.$hashCodeCache; final int PRIME = 59; int result = 1; result = ((result * PRIME) + this.x); @@ -44,6 +47,7 @@ result = ((result * PRIME) + (($a == null) ? 43 : $a.hashCode())); final java.lang.Object $b = this.b; result = ((result * PRIME) + (($b == null) ? 43 : $b.hashCode())); + this.$hashCodeCache = ((result != 0) ? result : java.lang.Integer.MIN_VALUE); return result; } } @@ -87,7 +91,7 @@ final @lombok.EqualsAndHashCode(cacheStrategy = lombok.EqualsAndHashCode.CacheSt final long $d = java.lang.Double.doubleToLongBits(this.d); result = ((result * PRIME) + (int) ($d ^ ($d >>> 32))); result = ((result * PRIME) + (this.b ? 79 : 97)); - this.$hashCodeCache = result; + this.$hashCodeCache = ((result != 0) ? result : java.lang.Integer.MIN_VALUE); return result; } } @@ -113,11 +117,12 @@ final @lombok.EqualsAndHashCode(callSuper = false,cacheStrategy = lombok.EqualsA if ((this.$hashCodeCache != 0)) return this.$hashCodeCache; final int result = 1; - this.$hashCodeCache = result; + this.$hashCodeCache = ((result != 0) ? result : java.lang.Integer.MIN_VALUE); return result; } } @lombok.EqualsAndHashCode(callSuper = true,cacheStrategy = lombok.EqualsAndHashCode.CacheStrategy.LAZY) class EqualsAndHashCode4 extends EqualsAndHashCode { + private transient @java.lang.SuppressWarnings("all") int $hashCodeCache = 0; EqualsAndHashCode4() { super(); } @@ -137,7 +142,10 @@ final @lombok.EqualsAndHashCode(callSuper = false,cacheStrategy = lombok.EqualsA return (other instanceof EqualsAndHashCode4); } public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() { + if ((this.$hashCodeCache != 0)) + return this.$hashCodeCache; final int result = super.hashCode(); + this.$hashCodeCache = ((result != 0) ? result : java.lang.Integer.MIN_VALUE); return result; } } @@ -165,7 +173,7 @@ final @lombok.EqualsAndHashCode(callSuper = true,cacheStrategy = lombok.EqualsAn if ((this.$hashCodeCache != 0)) return this.$hashCodeCache; final int result = super.hashCode(); - this.$hashCodeCache = result; + this.$hashCodeCache = ((result != 0) ? result : java.lang.Integer.MIN_VALUE); return result; } } diff --git a/test/transform/resource/messages-delombok/EqualsAndHashCodeCache.java.messages b/test/transform/resource/messages-delombok/EqualsAndHashCodeCache.java.messages index 24d202bd..f1686a6e 100644 --- a/test/transform/resource/messages-delombok/EqualsAndHashCodeCache.java.messages +++ b/test/transform/resource/messages-delombok/EqualsAndHashCodeCache.java.messages @@ -1,2 +1,2 @@ -1 Not caching the result of hashCode: Annotated type is not final. -23 Not caching the result of hashCode: Annotated type is not final.
\ No newline at end of file +1 Caching the result of hashCode for non-final type. +23 Caching the result of hashCode for non-final type.
\ No newline at end of file diff --git a/test/transform/resource/messages-ecj/EqualsAndHashCodeCache.java.messages b/test/transform/resource/messages-ecj/EqualsAndHashCodeCache.java.messages index 24d202bd..f1686a6e 100644 --- a/test/transform/resource/messages-ecj/EqualsAndHashCodeCache.java.messages +++ b/test/transform/resource/messages-ecj/EqualsAndHashCodeCache.java.messages @@ -1,2 +1,2 @@ -1 Not caching the result of hashCode: Annotated type is not final. -23 Not caching the result of hashCode: Annotated type is not final.
\ No newline at end of file +1 Caching the result of hashCode for non-final type. +23 Caching the result of hashCode for non-final type.
\ No newline at end of file |