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
This commit is contained in:
Andre Brait authored and Roel Spilker committed 2020-09-24 22:25:15 +02:00
1 parent 0808d4271a
commit 8d004c0638
6 files changed
+53 -24

No files matched your search

@@ -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);
@@ -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)));
}
}
@@ -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;
}
}
@@ -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;
}
}
@@ -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.
1 Caching the result of hashCode for non-final type.
23 Caching the result of hashCode for non-final type.
@@ -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.
1 Caching the result of hashCode for non-final type.
23 Caching the result of hashCode for non-final type.