diff options
author | Roel Spilker <r.spilker@gmail.com> | 2020-09-25 00:13:50 +0200 |
---|---|---|
committer | Roel Spilker <r.spilker@gmail.com> | 2020-09-25 00:13:50 +0200 |
commit | 2ba65d105ddfce54690a64f93cbc5c55480ef364 (patch) | |
tree | c79158768703c8cc77ba9b031f30bc2d7d40db7f | |
parent | ee6c0ca7f2274b24571afdc8586eff9052f5eda1 (diff) | |
download | lombok-2ba65d105ddfce54690a64f93cbc5c55480ef364.tar.gz lombok-2ba65d105ddfce54690a64f93cbc5c55480ef364.tar.bz2 lombok-2ba65d105ddfce54690a64f93cbc5c55480ef364.zip |
Cache hashCode:
- Fix bug where 0 would be returned once
- Fix Eclipse position error
- Don't initialize field with default value 0
4 files changed, 84 insertions, 49 deletions
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java index 2f0ce227..deb19c00 100755 --- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java @@ -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) { - 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); + + 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); + 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); diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java index ea1820f8..9c5b8762 100644 --- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java +++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java @@ -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)))); } } diff --git a/test/transform/resource/after-delombok/EqualsAndHashCodeCache.java b/test/transform/resource/after-delombok/EqualsAndHashCodeCache.java index e76f74d5..4f3574b6 100644 --- a/test/transform/resource/after-delombok/EqualsAndHashCodeCache.java +++ b/test/transform/resource/after-delombok/EqualsAndHashCodeCache.java @@ -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; } } diff --git a/test/transform/resource/after-ecj/EqualsAndHashCodeCache.java b/test/transform/resource/after-ecj/EqualsAndHashCodeCache.java index b29fd6b3..7094b636 100644 --- a/test/transform/resource/after-ecj/EqualsAndHashCodeCache.java +++ b/test/transform/resource/after-ecj/EqualsAndHashCodeCache.java @@ -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; } } |