Cache hashCode:

- Fix bug where 0 would be returned once
- Fix Eclipse position error
- Don't initialize field with default value 0
This commit is contained in:
Roel Spilker committed 2020-09-25 00:13:50 +02:00
1 parent ee6c0ca7f2
commit 2ba65d105d
4 files changed
+85 -50

No files matched your search

@@ -246,12 +246,11 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
}
private void createHashCodeCacheField(EclipseNode typeNode, ASTNode source) {
FieldDeclaration hashCodeCacheDecl = new FieldDeclaration(HASH_CODE_CACHE_NAME_ARR, 0, -1);
FieldDeclaration hashCodeCacheDecl = new FieldDeclaration(HASH_CODE_CACHE_NAME_ARR, 0, 0);
hashCodeCacheDecl.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccTransient;
hashCodeCacheDecl.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
hashCodeCacheDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
hashCodeCacheDecl.declarationSourceEnd = -1;
hashCodeCacheDecl.initialization = makeIntLiteral("0".toCharArray(), source);
injectFieldAndMarkGenerated(typeNode, hashCodeCacheDecl);
setGeneratedBy(hashCodeCacheDecl, source);
setGeneratedBy(hashCodeCacheDecl.type, source);
@@ -345,7 +344,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
resultDecl.initialization = init;
resultDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
resultDecl.type.sourceStart = pS; resultDecl.type.sourceEnd = pE;
if (isEmpty) resultDecl.modifiers |= Modifier.FINAL;
if (isEmpty && !cacheHashCode) resultDecl.modifiers |= Modifier.FINAL;
setGeneratedBy(resultDecl.type, source);
statements.add(resultDecl);
}
@@ -440,24 +439,43 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
}
}
/* this.$hashCodeCache = result != 0 ? result : Integer.MIN_VALUE; */ {
/*
* if (result == 0) result = Integer.MIN_VALUE;
* this.$hashCodeCache = result;
*
*/ {
if (cacheHashCode) {
SingleNameReference resultRef = new SingleNameReference(RESULT, p);
setGeneratedBy(resultRef, source);
EqualExpression resultIsZero = new EqualExpression(resultRef, makeIntLiteral("0".toCharArray(), source), OperatorIds.EQUAL_EQUAL);
setGeneratedBy(resultIsZero, source);
resultRef = new SingleNameReference(RESULT, p);
setGeneratedBy(resultRef, source);
FieldReference integerMinValue = new FieldReference("MIN_VALUE".toCharArray(), p);
integerMinValue.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_INTEGER);
setGeneratedBy(integerMinValue, source);
Assignment newResult = new Assignment(resultRef, integerMinValue, pE);
newResult.sourceStart = pS; newResult.statementEnd = newResult.sourceEnd = pE;
setGeneratedBy(newResult, source);
IfStatement ifStatement = new IfStatement(resultIsZero, newResult, pS, pE);
setGeneratedBy(ifStatement, source);
statements.add(ifStatement);
FieldReference hashCodeCacheRef = new FieldReference(HASH_CODE_CACHE_NAME_ARR, p);
hashCodeCacheRef.receiver = new ThisReference(pS, pE);
setGeneratedBy(hashCodeCacheRef, source);
setGeneratedBy(hashCodeCacheRef.receiver, source);
SingleNameReference resultRef = new SingleNameReference(RESULT, p);
setGeneratedBy(resultRef, source);
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);
Assignment cacheResult = new Assignment(hashCodeCacheRef, resultRef, pE);
cacheResult.sourceStart = pS; cacheResult.statementEnd = cacheResult.sourceEnd = pE;
setGeneratedBy(cacheResult, source);
statements.add(cacheResult);
@@ -40,7 +40,6 @@ 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;
@@ -221,7 +220,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
private void createHashCodeCacheField(JavacNode typeNode, JCTree source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.PRIVATE | Flags.TRANSIENT);
JCVariableDecl hashCodeCacheField = maker.VarDef(mods, typeNode.toName(HASH_CODE_CACHE_NAME), maker.TypeIdent(CTC_INT), maker.Literal(CTC_INT, 0));
JCVariableDecl hashCodeCacheField = maker.VarDef(mods, typeNode.toName(HASH_CODE_CACHE_NAME), maker.TypeIdent(CTC_INT), null);
injectFieldAndMarkGenerated(typeNode, hashCodeCacheField);
recursiveSetGeneratedBy(hashCodeCacheField, source, typeNode.getContext());
}
@@ -273,7 +272,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
/* ... 1; */
init = maker.Literal(1);
}
statements.append(maker.VarDef(maker.Modifiers(isEmpty ? finalFlag : 0), resultName, maker.TypeIdent(CTC_INT), init));
statements.append(maker.VarDef(maker.Modifiers(isEmpty && !cacheHashCode ? finalFlag : 0), resultName, maker.TypeIdent(CTC_INT), init));
}
for (Included<JavacNode, EqualsAndHashCode.Include> member : members) {
@@ -345,14 +344,17 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
}
}
/* this.$hashCodeCache = result != 0 ? result : Integer.MIN_VALUE; */ {
/*
* if (result == 0) result = Integer.MIN_VALUE;
* this.$hashCodeCache = result;
*
*/ {
if (cacheHashCode) {
JCIdent receiver = maker.Ident(typeNode.toName("this"));
JCFieldAccess cacheHashCodeFieldAccess = maker.Select(receiver, typeNode.toName(HASH_CODE_CACHE_NAME));
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)));
statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(resultName), maker.Literal(CTC_INT, 0)),
maker.Exec(maker.Assign(maker.Ident(resultName), genJavaLangTypeRef(typeNode, "Integer", "MIN_VALUE"))), null));
JCFieldAccess cacheHashCodeFieldAccess = maker.Select(maker.Ident(typeNode.toName("this")), typeNode.toName(HASH_CODE_CACHE_NAME));
statements.append(maker.Exec(maker.Assign(cacheHashCodeFieldAccess, maker.Ident(resultName))));
}
}
@@ -1,6 +1,6 @@
class EqualsAndHashCode {
@java.lang.SuppressWarnings("all")
private transient int $hashCodeCache = 0;
private transient int $hashCodeCache;
int x;
boolean[] y;
Object[] z;
@@ -41,13 +41,14 @@ 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;
if (result == 0) result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
final class EqualsAndHashCode2 {
@java.lang.SuppressWarnings("all")
private transient int $hashCodeCache = 0;
private transient int $hashCodeCache;
int x;
long y;
float f;
@@ -79,13 +80,14 @@ 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 != 0 ? result : java.lang.Integer.MIN_VALUE;
if (result == 0) result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
final class EqualsAndHashCode3 extends EqualsAndHashCode {
@java.lang.SuppressWarnings("all")
private transient int $hashCodeCache = 0;
private transient int $hashCodeCache;
@java.lang.Override
@java.lang.SuppressWarnings("all")
public boolean equals(final java.lang.Object o) {
@@ -103,14 +105,15 @@ final class EqualsAndHashCode3 extends EqualsAndHashCode {
@java.lang.SuppressWarnings("all")
public int hashCode() {
if (this.$hashCodeCache != 0) return this.$hashCodeCache;
final int result = 1;
this.$hashCodeCache = result != 0 ? result : java.lang.Integer.MIN_VALUE;
int result = 1;
if (result == 0) result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
class EqualsAndHashCode4 extends EqualsAndHashCode {
@java.lang.SuppressWarnings("all")
private transient int $hashCodeCache = 0;
private transient int $hashCodeCache;
@java.lang.Override
@java.lang.SuppressWarnings("all")
public boolean equals(final java.lang.Object o) {
@@ -129,14 +132,15 @@ class EqualsAndHashCode4 extends EqualsAndHashCode {
@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;
int result = super.hashCode();
if (result == 0) result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
final class EqualsAndHashCode5 extends EqualsAndHashCode {
@java.lang.SuppressWarnings("all")
private transient int $hashCodeCache = 0;
private transient int $hashCodeCache;
@java.lang.Override
@java.lang.SuppressWarnings("all")
public boolean equals(final java.lang.Object o) {
@@ -155,8 +159,9 @@ final class EqualsAndHashCode5 extends EqualsAndHashCode {
@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;
int result = super.hashCode();
if (result == 0) result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
@@ -1,5 +1,5 @@
@lombok.EqualsAndHashCode(cacheStrategy = lombok.EqualsAndHashCode.CacheStrategy.LAZY) class EqualsAndHashCode {
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache = 0;
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache;
int x;
boolean[] y;
Object[] z;
@@ -47,12 +47,14 @@
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);
if ((result == 0))
result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
final @lombok.EqualsAndHashCode(cacheStrategy = lombok.EqualsAndHashCode.CacheStrategy.LAZY) class EqualsAndHashCode2 {
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache = 0;
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache;
int x;
long y;
float f;
@@ -91,12 +93,14 @@ 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 != 0) ? result : java.lang.Integer.MIN_VALUE);
if ((result == 0))
result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
final @lombok.EqualsAndHashCode(callSuper = false,cacheStrategy = lombok.EqualsAndHashCode.CacheStrategy.LAZY) class EqualsAndHashCode3 extends EqualsAndHashCode {
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache = 0;
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache;
EqualsAndHashCode3() {
super();
}
@@ -116,13 +120,15 @@ final @lombok.EqualsAndHashCode(callSuper = false,cacheStrategy = lombok.EqualsA
public @java.lang.Override @java.lang.SuppressWarnings("all") int hashCode() {
if ((this.$hashCodeCache != 0))
return this.$hashCodeCache;
final int result = 1;
this.$hashCodeCache = ((result != 0) ? result : java.lang.Integer.MIN_VALUE);
int result = 1;
if ((result == 0))
result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
@lombok.EqualsAndHashCode(callSuper = true,cacheStrategy = lombok.EqualsAndHashCode.CacheStrategy.LAZY) class EqualsAndHashCode4 extends EqualsAndHashCode {
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache = 0;
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache;
EqualsAndHashCode4() {
super();
}
@@ -144,13 +150,15 @@ final @lombok.EqualsAndHashCode(callSuper = false,cacheStrategy = lombok.EqualsA
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);
int result = super.hashCode();
if ((result == 0))
result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}
final @lombok.EqualsAndHashCode(callSuper = true,cacheStrategy = lombok.EqualsAndHashCode.CacheStrategy.LAZY) class EqualsAndHashCode5 extends EqualsAndHashCode {
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache = 0;
private transient @java.lang.SuppressWarnings("all") int $hashCodeCache;
EqualsAndHashCode5() {
super();
}
@@ -172,8 +180,10 @@ final @lombok.EqualsAndHashCode(callSuper = true,cacheStrategy = lombok.EqualsAn
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);
int result = super.hashCode();
if ((result == 0))
result = java.lang.Integer.MIN_VALUE;
this.$hashCodeCache = result;
return result;
}
}