Skip to content

Commit 58545ce

Browse files
committed
Merge remote-tracking branch 'origin/master'
# Conflicts: # src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
2 parents 14cce76 + 4f76336 commit 58545ce

File tree

10 files changed

+576
-17
lines changed

10 files changed

+576
-17
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Lombok contributors in alphabetical order:
22

33
Adam Juraszek <[email protected]>
44
Aleksandr Zhelezniak <[email protected]>
5+
Andre Brait <[email protected]>
56
Bulgakov Alexander <[email protected]>
67
Caleb Brinkman <[email protected]>
78
Christian Nüssgens <[email protected]>

src/core/lombok/EqualsAndHashCode.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,14 @@
7171
* @return If {@code true}, always use direct field access instead of calling the getter method.
7272
*/
7373
boolean doNotUseGetters() default false;
74+
75+
/**
76+
* Determines how the result of the {@code hashCode} method will be cached.
77+
* <strong>default: {@link CacheStrategy#NEVER}</strong>
78+
*
79+
* @return The {@code hashCode} cache strategy to be used.
80+
*/
81+
CacheStrategy cacheStrategy() default CacheStrategy.NEVER;
7482

7583
/**
7684
* Any annotations listed here are put on the generated parameter of {@code equals} and {@code canEqual}.
@@ -132,4 +140,19 @@
132140
*/
133141
int rank() default 0;
134142
}
143+
144+
public enum CacheStrategy {
145+
/**
146+
* Never cache. Perform the calculation every time the method is called.
147+
*/
148+
NEVER,
149+
/**
150+
* Cache the result of the first invocation of {@code hashCode} and use it for subsequent invocations.
151+
* This can improve performance if all fields used for calculating the {@code hashCode} are immutable
152+
* and thus every invocation of {@code hashCode} will always return the same value.
153+
* <strong>Do not use this if there's <em>any</em> chance that different invocations of {@code hashCode}
154+
* might return different values.</strong>
155+
*/
156+
LAZY
157+
}
135158
}

src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java

Lines changed: 98 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import lombok.AccessLevel;
3737
import lombok.ConfigurationKeys;
3838
import lombok.EqualsAndHashCode;
39+
import lombok.EqualsAndHashCode.CacheStrategy;
3940
import lombok.core.AST.Kind;
4041
import lombok.core.handlers.HandlerUtil;
4142
import lombok.core.handlers.InclusionExclusionUtils;
@@ -59,6 +60,8 @@
5960
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
6061
import org.eclipse.jdt.internal.compiler.ast.Expression;
6162
import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
63+
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
64+
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
6265
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
6366
import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
6467
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
@@ -94,6 +97,9 @@
9497
@ProviderFor(EclipseAnnotationHandler.class)
9598
public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndHashCode> {
9699

100+
private static final String HASH_CODE_CACHE_NAME = "$hashCodeCache";
101+
102+
private final char[] HASH_CODE_CACHE_NAME_ARR = HASH_CODE_CACHE_NAME.toCharArray();
97103
private final char[] PRIME = "PRIME".toCharArray();
98104
private final char[] RESULT = "result".toCharArray();
99105

@@ -116,7 +122,9 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
116122
boolean doNotUseGetters = annotation.isExplicit("doNotUseGetters") || doNotUseGettersConfiguration == null ? ann.doNotUseGetters() : doNotUseGettersConfiguration;
117123
FieldAccess fieldAccess = doNotUseGetters ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER;
118124

119-
generateMethods(annotationNode.up(), annotationNode, members, callSuper, true, fieldAccess, onParam);
125+
boolean cacheHashCode = ann.cacheStrategy() == CacheStrategy.LAZY;
126+
127+
generateMethods(annotationNode.up(), annotationNode, members, callSuper, true, cacheHashCode, fieldAccess, onParam);
120128
}
121129

122130
public void generateEqualsAndHashCodeForType(EclipseNode typeNode, EclipseNode errorNode) {
@@ -130,11 +138,11 @@ public void generateEqualsAndHashCodeForType(EclipseNode typeNode, EclipseNode e
130138
Boolean doNotUseGettersConfiguration = typeNode.getAst().readConfiguration(ConfigurationKeys.EQUALS_AND_HASH_CODE_DO_NOT_USE_GETTERS);
131139
FieldAccess access = doNotUseGettersConfiguration == null || !doNotUseGettersConfiguration ? FieldAccess.GETTER : FieldAccess.PREFER_FIELD;
132140

133-
generateMethods(typeNode, errorNode, members, null, false, access, new ArrayList<Annotation>());
141+
generateMethods(typeNode, errorNode, members, null, false, false, access, new ArrayList<Annotation>());
134142
}
135143

136144
public void generateMethods(EclipseNode typeNode, EclipseNode errorNode, List<Included<EclipseNode, EqualsAndHashCode.Include>> members,
137-
Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess, List<Annotation> onParam) {
145+
Boolean callSuper, boolean whineIfExists, boolean cacheHashCode, FieldAccess fieldAccess, List<Annotation> onParam) {
138146

139147
TypeDeclaration typeDecl = null;
140148

@@ -222,12 +230,33 @@ public void generateMethods(EclipseNode typeNode, EclipseNode errorNode, List<In
222230
injectMethod(typeNode, canEqualMethod);
223231
}
224232

225-
MethodDeclaration hashCodeMethod = createHashCode(typeNode, members, callSuper, errorNode.get(), fieldAccess);
233+
if (cacheHashCode){
234+
if (fieldExists(HASH_CODE_CACHE_NAME, typeNode) != MemberExistsResult.NOT_EXISTS) {
235+
String msg = String.format("Not caching the result of hashCode: A field named %s already exists.", HASH_CODE_CACHE_NAME);
236+
errorNode.addWarning(msg);
237+
cacheHashCode = false;
238+
} else {
239+
createHashCodeCacheField(typeNode, errorNode.get());
240+
}
241+
}
242+
243+
MethodDeclaration hashCodeMethod = createHashCode(typeNode, members, callSuper, cacheHashCode, errorNode.get(), fieldAccess);
226244
hashCodeMethod.traverse(new SetGeneratedByVisitor(errorNode.get()), ((TypeDeclaration)typeNode.get()).scope);
227245
injectMethod(typeNode, hashCodeMethod);
228246
}
247+
248+
private void createHashCodeCacheField(EclipseNode typeNode, ASTNode source) {
249+
FieldDeclaration hashCodeCacheDecl = new FieldDeclaration(HASH_CODE_CACHE_NAME_ARR, 0, 0);
250+
hashCodeCacheDecl.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccTransient;
251+
hashCodeCacheDecl.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
252+
hashCodeCacheDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
253+
hashCodeCacheDecl.declarationSourceEnd = -1;
254+
injectFieldAndMarkGenerated(typeNode, hashCodeCacheDecl);
255+
setGeneratedBy(hashCodeCacheDecl, source);
256+
setGeneratedBy(hashCodeCacheDecl.type, source);
257+
}
229258

230-
public MethodDeclaration createHashCode(EclipseNode type, Collection<Included<EclipseNode, EqualsAndHashCode.Include>> members, boolean callSuper, ASTNode source, FieldAccess fieldAccess) {
259+
public MethodDeclaration createHashCode(EclipseNode type, Collection<Included<EclipseNode, EqualsAndHashCode.Include>> members, boolean callSuper, boolean cacheHashCode, ASTNode source, FieldAccess fieldAccess) {
231260
int pS = source.sourceStart, pE = source.sourceEnd;
232261
long p = (long) pS << 32 | pE;
233262

@@ -238,7 +267,10 @@ public MethodDeclaration createHashCode(EclipseNode type, Collection<Included<Ec
238267
method.returnType = TypeReference.baseTypeReference(TypeIds.T_int, 0);
239268
setGeneratedBy(method.returnType, source);
240269
Annotation overrideAnnotation = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source);
241-
if (getCheckerFrameworkVersion(type).generateSideEffectFree()) {
270+
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(type);
271+
if (cacheHashCode && checkerFramework.generatePure()) {
272+
method.annotations = new Annotation[] { overrideAnnotation, generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__PURE) };
273+
} else if (checkerFramework.generateSideEffectFree()) {
242274
method.annotations = new Annotation[] { overrideAnnotation, generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
243275
} else {
244276
method.annotations = new Annotation[] { overrideAnnotation };
@@ -262,6 +294,22 @@ public MethodDeclaration createHashCode(EclipseNode type, Collection<Included<Ec
262294
}
263295
}
264296

297+
/* if (this.$hashCodeCache != 0) return this.$hashCodeCache; */ {
298+
if (cacheHashCode) {
299+
FieldReference hashCodeCacheRef = new FieldReference(HASH_CODE_CACHE_NAME_ARR, p);
300+
hashCodeCacheRef.receiver = new ThisReference(pS, pE);
301+
setGeneratedBy(hashCodeCacheRef, source);
302+
setGeneratedBy(hashCodeCacheRef.receiver, source);
303+
EqualExpression cacheNotZero = new EqualExpression(hashCodeCacheRef, makeIntLiteral("0".toCharArray(), source), OperatorIds.NOT_EQUAL);
304+
setGeneratedBy(cacheNotZero, source);
305+
ReturnStatement returnCache = new ReturnStatement(hashCodeCacheRef, pS, pE);
306+
setGeneratedBy(returnCache, source);
307+
IfStatement ifStatement = new IfStatement(cacheNotZero, returnCache, pS, pE);
308+
setGeneratedBy(ifStatement, source);
309+
statements.add(ifStatement);
310+
}
311+
}
312+
265313
/* final int PRIME = X; */ {
266314
/* Without members, PRIME isn't used, as that would trigger a 'local variable not used' warning. */
267315
if (!isEmpty) {
@@ -296,7 +344,7 @@ public MethodDeclaration createHashCode(EclipseNode type, Collection<Included<Ec
296344
resultDecl.initialization = init;
297345
resultDecl.type = TypeReference.baseTypeReference(TypeIds.T_int, 0);
298346
resultDecl.type.sourceStart = pS; resultDecl.type.sourceEnd = pE;
299-
if (isEmpty) resultDecl.modifiers |= Modifier.FINAL;
347+
if (isEmpty && !cacheHashCode) resultDecl.modifiers |= Modifier.FINAL;
300348
setGeneratedBy(resultDecl.type, source);
301349
statements.add(resultDecl);
302350
}
@@ -391,6 +439,49 @@ public MethodDeclaration createHashCode(EclipseNode type, Collection<Included<Ec
391439
}
392440
}
393441

442+
/*
443+
* if (result == 0) result = Integer.MIN_VALUE;
444+
* this.$hashCodeCache = result;
445+
*
446+
*/ {
447+
if (cacheHashCode) {
448+
SingleNameReference resultRef = new SingleNameReference(RESULT, p);
449+
setGeneratedBy(resultRef, source);
450+
451+
EqualExpression resultIsZero = new EqualExpression(resultRef, makeIntLiteral("0".toCharArray(), source), OperatorIds.EQUAL_EQUAL);
452+
setGeneratedBy(resultIsZero, source);
453+
454+
resultRef = new SingleNameReference(RESULT, p);
455+
setGeneratedBy(resultRef, source);
456+
457+
FieldReference integerMinValue = new FieldReference("MIN_VALUE".toCharArray(), p);
458+
integerMinValue.receiver = generateQualifiedNameRef(source, TypeConstants.JAVA_LANG_INTEGER);
459+
setGeneratedBy(integerMinValue, source);
460+
461+
Assignment newResult = new Assignment(resultRef, integerMinValue, pE);
462+
newResult.sourceStart = pS; newResult.statementEnd = newResult.sourceEnd = pE;
463+
setGeneratedBy(newResult, source);
464+
465+
IfStatement ifStatement = new IfStatement(resultIsZero, newResult, pS, pE);
466+
setGeneratedBy(ifStatement, source);
467+
statements.add(ifStatement);
468+
469+
470+
FieldReference hashCodeCacheRef = new FieldReference(HASH_CODE_CACHE_NAME_ARR, p);
471+
hashCodeCacheRef.receiver = new ThisReference(pS, pE);
472+
setGeneratedBy(hashCodeCacheRef, source);
473+
setGeneratedBy(hashCodeCacheRef.receiver, source);
474+
475+
resultRef = new SingleNameReference(RESULT, p);
476+
setGeneratedBy(resultRef, source);
477+
478+
Assignment cacheResult = new Assignment(hashCodeCacheRef, resultRef, pE);
479+
cacheResult.sourceStart = pS; cacheResult.statementEnd = cacheResult.sourceEnd = pE;
480+
setGeneratedBy(cacheResult, source);
481+
statements.add(cacheResult);
482+
}
483+
}
484+
394485
/* return result; */ {
395486
SingleNameReference resultRef = new SingleNameReference(RESULT, p);
396487
setGeneratedBy(resultRef, source);

src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
import com.sun.tools.javac.tree.JCTree.JCClassDecl;
4343
import com.sun.tools.javac.tree.JCTree.JCExpression;
4444
import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
45+
import com.sun.tools.javac.tree.JCTree.JCFieldAccess;
46+
import com.sun.tools.javac.tree.JCTree.JCIdent;
4547
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
4648
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
4749
import com.sun.tools.javac.tree.JCTree.JCModifiers;
@@ -56,6 +58,7 @@
5658

5759
import lombok.ConfigurationKeys;
5860
import lombok.EqualsAndHashCode;
61+
import lombok.EqualsAndHashCode.CacheStrategy;
5962
import lombok.core.AST.Kind;
6063
import lombok.core.AnnotationValues;
6164
import lombok.core.configuration.CallSuperType;
@@ -76,11 +79,13 @@
7679
public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHashCode> {
7780
private static final String RESULT_NAME = "result";
7881
private static final String PRIME_NAME = "PRIME";
82+
private static final String HASH_CODE_CACHE_NAME = "$hashCodeCache";
7983

8084
@Override public void handle(AnnotationValues<EqualsAndHashCode> annotation, JCAnnotation ast, JavacNode annotationNode) {
8185
handleFlagUsage(annotationNode, ConfigurationKeys.EQUALS_AND_HASH_CODE_FLAG_USAGE, "@EqualsAndHashCode");
8286

8387
deleteAnnotationIfNeccessary(annotationNode, EqualsAndHashCode.class);
88+
deleteImportFromCompilationUnit(annotationNode, CacheStrategy.class.getName());
8489
EqualsAndHashCode ann = annotation.getInstance();
8590
java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members = InclusionExclusionUtils.handleEqualsAndHashCodeMarking(annotationNode.up(), annotation, annotationNode);
8691
JavacNode typeNode = annotationNode.up();
@@ -92,8 +97,10 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
9297
Boolean doNotUseGettersConfiguration = annotationNode.getAst().readConfiguration(ConfigurationKeys.EQUALS_AND_HASH_CODE_DO_NOT_USE_GETTERS);
9398
boolean doNotUseGetters = annotation.isExplicit("doNotUseGetters") || doNotUseGettersConfiguration == null ? ann.doNotUseGetters() : doNotUseGettersConfiguration;
9499
FieldAccess fieldAccess = doNotUseGetters ? FieldAccess.PREFER_FIELD : FieldAccess.GETTER;
95-
96-
generateMethods(typeNode, annotationNode, members, callSuper, true, fieldAccess, onParam);
100+
101+
boolean cacheHashCode = ann.cacheStrategy() == CacheStrategy.LAZY;
102+
103+
generateMethods(typeNode, annotationNode, members, callSuper, true, cacheHashCode, fieldAccess, onParam);
97104
}
98105

99106
public void generateEqualsAndHashCodeForType(JavacNode typeNode, JavacNode source) {
@@ -107,11 +114,11 @@ public void generateEqualsAndHashCodeForType(JavacNode typeNode, JavacNode sourc
107114

108115
java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members = InclusionExclusionUtils.handleEqualsAndHashCodeMarking(typeNode, null, null);
109116

110-
generateMethods(typeNode, source, members, null, false, access, List.<JCAnnotation>nil());
117+
generateMethods(typeNode, source, members, null, false, false, access, List.<JCAnnotation>nil());
111118
}
112119

113120
public void generateMethods(JavacNode typeNode, JavacNode source, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members,
114-
Boolean callSuper, boolean whineIfExists, FieldAccess fieldAccess, List<JCAnnotation> onParam) {
121+
Boolean callSuper, boolean whineIfExists, boolean cacheHashCode, FieldAccess fieldAccess, List<JCAnnotation> onParam) {
115122

116123
boolean notAClass = true;
117124
if (typeNode.get() instanceof JCClassDecl) {
@@ -196,17 +203,39 @@ public void generateMethods(JavacNode typeNode, JavacNode source, java.util.List
196203
injectMethod(typeNode, canEqualMethod);
197204
}
198205

199-
JCMethodDecl hashCodeMethod = createHashCode(typeNode, members, callSuper, fieldAccess, source.get());
206+
if (cacheHashCode){
207+
if (fieldExists(HASH_CODE_CACHE_NAME, typeNode) != MemberExistsResult.NOT_EXISTS) {
208+
String msg = String.format("Not caching the result of hashCode: A field named %s already exists.", HASH_CODE_CACHE_NAME);
209+
source.addWarning(msg);
210+
cacheHashCode = false;
211+
} else {
212+
createHashCodeCacheField(typeNode, source.get());
213+
}
214+
}
215+
216+
JCMethodDecl hashCodeMethod = createHashCode(typeNode, members, callSuper, cacheHashCode, fieldAccess, source.get());
200217
injectMethod(typeNode, hashCodeMethod);
201218
}
219+
220+
private void createHashCodeCacheField(JavacNode typeNode, JCTree source) {
221+
JavacTreeMaker maker = typeNode.getTreeMaker();
222+
JCModifiers mods = maker.Modifiers(Flags.PRIVATE | Flags.TRANSIENT);
223+
JCVariableDecl hashCodeCacheField = maker.VarDef(mods, typeNode.toName(HASH_CODE_CACHE_NAME), maker.TypeIdent(CTC_INT), null);
224+
injectFieldAndMarkGenerated(typeNode, hashCodeCacheField);
225+
recursiveSetGeneratedBy(hashCodeCacheField, source, typeNode.getContext());
226+
}
202227

203-
public JCMethodDecl createHashCode(JavacNode typeNode, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members, boolean callSuper, FieldAccess fieldAccess, JCTree source) {
228+
public JCMethodDecl createHashCode(JavacNode typeNode, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members, boolean callSuper, boolean cacheHashCode, FieldAccess fieldAccess, JCTree source) {
204229
JavacTreeMaker maker = typeNode.getTreeMaker();
205230

206231
JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
207232
List<JCAnnotation> annsOnMethod = List.of(overrideAnnotation);
208233
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(typeNode);
209-
if (checkerFramework.generateSideEffectFree()) annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
234+
if (cacheHashCode && checkerFramework.generatePure()) {
235+
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()));
236+
} else if (checkerFramework.generateSideEffectFree()) {
237+
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
238+
}
210239
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, annsOnMethod);
211240
JCExpression returnType = maker.TypeIdent(CTC_INT);
212241
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
@@ -217,6 +246,15 @@ public JCMethodDecl createHashCode(JavacNode typeNode, java.util.List<Included<J
217246

218247
boolean isEmpty = members.isEmpty();
219248

249+
/* if (this.$hashCodeCache != 0) return this.$hashCodeCache; */ {
250+
if (cacheHashCode) {
251+
JCIdent receiver = maker.Ident(typeNode.toName("this"));
252+
JCFieldAccess cacheHashCodeFieldAccess = maker.Select(receiver, typeNode.toName(HASH_CODE_CACHE_NAME));
253+
JCExpression cacheNotZero = maker.Binary(CTC_NOT_EQUAL, cacheHashCodeFieldAccess, maker.Literal(CTC_INT, 0));
254+
statements.append(maker.If(cacheNotZero, maker.Return(cacheHashCodeFieldAccess), null));
255+
}
256+
}
257+
220258
/* final int PRIME = X; */ {
221259
if (!isEmpty) {
222260
statements.append(maker.VarDef(maker.Modifiers(finalFlag), primeName, maker.TypeIdent(CTC_INT), maker.Literal(HandlerUtil.primeForHashcode())));
@@ -234,7 +272,7 @@ public JCMethodDecl createHashCode(JavacNode typeNode, java.util.List<Included<J
234272
/* ... 1; */
235273
init = maker.Literal(1);
236274
}
237-
statements.append(maker.VarDef(maker.Modifiers(isEmpty ? finalFlag : 0L), resultName, maker.TypeIdent(CTC_INT), init));
275+
statements.append(maker.VarDef(maker.Modifiers(isEmpty && !cacheHashCode ? finalFlag : 0L), resultName, maker.TypeIdent(CTC_INT), init));
238276
}
239277

240278
for (Included<JavacNode, EqualsAndHashCode.Include> member : members) {
@@ -306,6 +344,20 @@ public JCMethodDecl createHashCode(JavacNode typeNode, java.util.List<Included<J
306344
}
307345
}
308346

347+
/*
348+
* if (result == 0) result = Integer.MIN_VALUE;
349+
* this.$hashCodeCache = result;
350+
*
351+
*/ {
352+
if (cacheHashCode) {
353+
statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(resultName), maker.Literal(CTC_INT, 0)),
354+
maker.Exec(maker.Assign(maker.Ident(resultName), genJavaLangTypeRef(typeNode, "Integer", "MIN_VALUE"))), null));
355+
356+
JCFieldAccess cacheHashCodeFieldAccess = maker.Select(maker.Ident(typeNode.toName("this")), typeNode.toName(HASH_CODE_CACHE_NAME));
357+
statements.append(maker.Exec(maker.Assign(cacheHashCodeFieldAccess, maker.Ident(resultName))));
358+
}
359+
}
360+
309361
/* return result; */ {
310362
statements.append(maker.Return(maker.Ident(resultName)));
311363
}

src/delombok/lombok/delombok/Delombok.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,8 +701,12 @@ public boolean delombok() throws IOException {
701701

702702
if (!disablePreview && Javac.getJavaCompilerVersion() >= 11) argsList.add("--enable-preview");
703703

704-
String[] argv = argsList.toArray(new String[0]);
705-
args.init("javac", argv);
704+
if (Javac.getJavaCompilerVersion() < 15) {
705+
String[] argv = argsList.toArray(new String[0]);
706+
args.init("javac", argv);
707+
} else {
708+
args.init("javac", argsList);
709+
}
706710
options.put("diags.legacy", "TRUE");
707711
options.put("allowStringFolding", "FALSE");
708712
} else {

0 commit comments

Comments
 (0)