mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-11 03:13:38 +00:00
[config: lombok.CheckReturnValue]: setting is now a list of possible flavours, do not apply if building for a method, add to getter/hc/equals/toString.
This commit is contained in:
17 files changed
+65
-34
No files matched your search
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2025 The Project Lombok Authors.
|
||||
* Copyright (C) 2025-2026 The Project Lombok Authors.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -92,13 +92,19 @@ public class ConfigurationKeys {
|
||||
public static final ConfigurationKey<Boolean> ADD_LOMBOK_GENERATED_ANNOTATIONS = new ConfigurationKey<Boolean>("lombok.addLombokGeneratedAnnotation", "Generate @lombok.Generated on all generated code (default: true).") {};
|
||||
|
||||
/**
|
||||
* lombok configuration: {@code lombok.checkReturnValueAnnotation} = [{@code none} | {@code lombok}].
|
||||
* lombok configuration: {@code lombok.checkReturnValueAnnotation} += {@code lombok} / {@code androidx}.
|
||||
*
|
||||
* If set to {@code lombok}, lombok generates {@code @lombok.CheckReturnValue} on generated methods where the return value should not be ignored,
|
||||
* such as {@code @With} methods and {@code @Builder}'s {@code build()} method.
|
||||
* If set to {@code none} (the current default), no such annotation is emitted. A future lombok release may flip the default to {@code lombok}.
|
||||
* If set, lombok generates all requested annotation flavors indicating that a caller must use the returned value on all methods where it is sensible, such as {@code @With} methods and {@code @Builder}'s {@code build()} method.
|
||||
* <p>
|
||||
* If value {@code lombok} is added, lombok generates {@code @lombok.CheckReturnValue}.
|
||||
* <p>
|
||||
* If value {@code androidx} is added, lombok generates {@code @androidx.annotation.CheckResult}.
|
||||
* <p>
|
||||
* The current default is no flavors (no annotations are added), but a future lombok release may flip the default {@code lombok}.
|
||||
* <p>
|
||||
* NB: {@code build()} methods only get these annotations if the thing they are building for is a type or constructor. Applying {@code @Builder} to a method will not result in these annotations unless that method is itself so annotated.
|
||||
*/
|
||||
public static final ConfigurationKey<CheckReturnValueFlavor> CHECK_RETURN_VALUE_ANNOTATION = new ConfigurationKey<CheckReturnValueFlavor>("lombok.checkReturnValueAnnotation", "Which @CheckReturnValue annotation flavor to emit on generated methods. Values: none, lombok (default: none).") {};
|
||||
public static final ConfigurationKey<List<CheckReturnValueFlavor>> CHECK_RETURN_VALUE_ANNOTATION = new ConfigurationKey<List<CheckReturnValueFlavor>>("lombok.checkReturnValueAnnotation", "Which @CheckReturnValue annotation flavor(s) to emit on generated methods. Values: lombok, androidx (default: none).") {};
|
||||
|
||||
/**
|
||||
* lombok configuration: {@code lombok.extern.findbugs.addSuppressFBWarnings} = {@code true} | {@code false}.
|
||||
|
||||
@@ -21,7 +21,23 @@
|
||||
*/
|
||||
package lombok.core.configuration;
|
||||
|
||||
/** Used for lombok configuration to select which {@code @CheckReturnValue} annotation flavor to emit on generated methods. */
|
||||
public enum CheckReturnValueFlavor {
|
||||
NONE, LOMBOK;
|
||||
/** Used for lombok configuration to select which {@code @CheckReturnValue} annotation flavor(s) to emit on generated methods. */
|
||||
public enum CheckReturnValueFlavor implements MappedConfigEnum {
|
||||
LOMBOK,
|
||||
ANDROIDX,
|
||||
;
|
||||
|
||||
@Override public boolean matches(String value) {
|
||||
return value.equals(this.name().toLowerCase());
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
return this.name().toLowerCase();
|
||||
}
|
||||
|
||||
public String getMarkerAnnotationFullyQualifiedName() {
|
||||
if (this == LOMBOK) return "lombok.CheckReturnValue";
|
||||
if (this == ANDROIDX) return "androidx.annotation.CheckResult";
|
||||
throw new IllegalStateException("bug");
|
||||
}
|
||||
}
|
||||
@@ -31,11 +31,13 @@ public enum JacksonVersion implements MappedConfigEnum {
|
||||
|
||||
@Override public boolean matches(String value) {
|
||||
if (this == TWO) return "2".equals(value);
|
||||
return "3".equals(value);
|
||||
if (this == THREE) return "3".equals(value);
|
||||
throw new IllegalStateException("bug");
|
||||
}
|
||||
|
||||
@Override public String toString() {
|
||||
if (this == TWO) return "2";
|
||||
return "3";
|
||||
if (this == THREE) return "3";
|
||||
throw new IllegalStateException("bug");
|
||||
}
|
||||
}
|
||||
@@ -2108,7 +2108,7 @@ public class EclipseHandlerUtil {
|
||||
private static final char[][] JAKARTA_ANNOTATION_GENERATED = Eclipse.fromQualifiedName("jakarta.annotation.Generated");
|
||||
private static final char[][] LOMBOK_GENERATED = Eclipse.fromQualifiedName("lombok.Generated");
|
||||
private static final char[][] EDU_UMD_CS_FINDBUGS_ANNOTATIONS_SUPPRESSFBWARNINGS = Eclipse.fromQualifiedName("edu.umd.cs.findbugs.annotations.SuppressFBWarnings");
|
||||
private static final char[][] LOMBOK_CHECK_RETURN_VALUE = Eclipse.fromQualifiedName("lombok.CheckReturnValue");
|
||||
private static final Map<CheckReturnValueFlavor, char[][]> checkReturnValueQualifiedNameCache = new HashMap<CheckReturnValueFlavor, char[][]>();
|
||||
|
||||
public static Annotation[] addSuppressWarningsAll(EclipseNode node, ASTNode source, Annotation[] originalAnnotationArray) {
|
||||
Annotation[] anns = originalAnnotationArray;
|
||||
@@ -2140,15 +2140,15 @@ public class EclipseHandlerUtil {
|
||||
}
|
||||
|
||||
public static Annotation[] addCheckReturnValue(EclipseNode node, ASTNode source, Annotation[] originalAnnotationArray) {
|
||||
CheckReturnValueFlavor flavor = node.getAst().readConfiguration(ConfigurationKeys.CHECK_RETURN_VALUE_ANNOTATION);
|
||||
if (flavor == null) flavor = CheckReturnValueFlavor.NONE;
|
||||
switch (flavor) {
|
||||
case LOMBOK:
|
||||
return addAnnotation(source, originalAnnotationArray, LOMBOK_CHECK_RETURN_VALUE);
|
||||
case NONE:
|
||||
default:
|
||||
return originalAnnotationArray;
|
||||
Annotation[] out = originalAnnotationArray;
|
||||
List<CheckReturnValueFlavor> flavors = node.getAst().readConfiguration(ConfigurationKeys.CHECK_RETURN_VALUE_ANNOTATION);
|
||||
for (CheckReturnValueFlavor flavor : flavors) {
|
||||
char[][] fqn = checkReturnValueQualifiedNameCache.get(flavor);
|
||||
if (fqn == null) checkReturnValueQualifiedNameCache.put(flavor, fqn = Eclipse.fromQualifiedName(flavor.getMarkerAnnotationFullyQualifiedName()));
|
||||
out = addAnnotation(source, out, fqn);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static Annotation[] addAnnotation(ASTNode source, Annotation[] originalAnnotationArray, char[][] annotationTypeFqn) {
|
||||
|
||||
@@ -897,7 +897,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
out.annotations = new Annotation[] {generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE)};
|
||||
}
|
||||
out.receiver = generateBuildReceiver(job);
|
||||
out.annotations = addCheckReturnValue(job.builderType, job.source, out.annotations);
|
||||
if (job.checkReturnValue) out.annotations = addCheckReturnValue(job.builderType, job.source, out.annotations);
|
||||
if (staticName == null) createRelevantNonNullAnnotation(job.builderType, out);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
return out;
|
||||
|
||||
@@ -272,6 +272,8 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
|
||||
} else {
|
||||
method.annotations = new Annotation[] { overrideAnnotation };
|
||||
}
|
||||
|
||||
method.annotations = EclipseHandlerUtil.addCheckReturnValue(type, method, method.annotations);
|
||||
method.selector = "hashCode".toCharArray();
|
||||
method.thrownExceptions = null;
|
||||
method.typeParameters = null;
|
||||
@@ -635,6 +637,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
|
||||
} else {
|
||||
method.annotations = new Annotation[] { overrideAnnotation };
|
||||
}
|
||||
method.annotations = EclipseHandlerUtil.addCheckReturnValue(type, method, method.annotations);
|
||||
method.selector = "equals".toCharArray();
|
||||
method.thrownExceptions = null;
|
||||
method.typeParameters = null;
|
||||
|
||||
@@ -291,6 +291,7 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> {
|
||||
findDelegatesAndMarkAsHandled(fieldNode),
|
||||
checkerFramework,
|
||||
deprecated);
|
||||
method.annotations = EclipseHandlerUtil.addCheckReturnValue(fieldNode, method, method.annotations);
|
||||
}
|
||||
|
||||
if (addSuppressWarningsUnchecked) {
|
||||
|
||||
@@ -27,7 +27,6 @@ import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -868,6 +868,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
else if (overrideAnn != null) out.annotations = new Annotation[] {overrideAnn};
|
||||
else if (sefAnn != null) out.annotations = new Annotation[] {sefAnn};
|
||||
out.receiver = HandleBuilder.generateBuildReceiver(job);
|
||||
out.annotations = addCheckReturnValue(job.builderType, job.source, out.annotations);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -298,6 +298,8 @@ public class HandleToString extends EclipseAnnotationHandler<ToString> {
|
||||
} else {
|
||||
method.annotations = new Annotation[] { overrideAnnotation };
|
||||
}
|
||||
method.annotations = EclipseHandlerUtil.addCheckReturnValue(type, method, method.annotations);
|
||||
|
||||
method.arguments = null;
|
||||
method.selector = "toString".toCharArray();
|
||||
method.thrownExceptions = null;
|
||||
|
||||
@@ -347,7 +347,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
}
|
||||
if (job.builderClassName.indexOf('*') > -1) {
|
||||
String replStr = returnTypeToBuilderClassName(annotationNode, td, buildMethodReturnType, job.typeParams);
|
||||
if (replStr == null) return; // shuold not happen
|
||||
if (replStr == null) return; // should not happen
|
||||
job.builderClassName = job.builderClassName.replace("*", replStr);
|
||||
}
|
||||
if (job.toBuilder) {
|
||||
@@ -810,7 +810,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
} else {
|
||||
methodDef = maker.MethodDef(maker.Modifiers(toJavacModifier(job.accessInners), annsOnMethod), job.toName(job.buildMethodName), returnTypeCopy, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
|
||||
}
|
||||
addCheckReturnValue(methodDef.mods, job.builderType, job.sourceNode);
|
||||
if (job.checkReturnValue) addCheckReturnValue(methodDef.mods, job.builderType, job.sourceNode);
|
||||
if (staticName == null) createRelevantNonNullAnnotation(job.builderType, methodDef);
|
||||
return methodDef;
|
||||
}
|
||||
|
||||
@@ -228,6 +228,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
|
||||
}
|
||||
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, annsOnMethod);
|
||||
addCheckReturnValue(mods, typeNode, source);
|
||||
JCExpression returnType = maker.TypeIdent(CTC_INT);
|
||||
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
|
||||
|
||||
@@ -439,6 +440,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
|
||||
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
|
||||
}
|
||||
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, annsOnMethod);
|
||||
addCheckReturnValue(mods, typeNode, source);
|
||||
JCExpression objectType;
|
||||
if (annsOnParamOnMethod.isEmpty()) {
|
||||
objectType = genJavaLangTypeRef(typeNode, "Object");
|
||||
|
||||
@@ -56,6 +56,7 @@ import com.sun.tools.javac.tree.JCTree.JCExpressionStatement;
|
||||
import com.sun.tools.javac.tree.JCTree.JCIf;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
|
||||
import com.sun.tools.javac.tree.JCTree.JCMethodInvocation;
|
||||
import com.sun.tools.javac.tree.JCTree.JCModifiers;
|
||||
import com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree;
|
||||
import com.sun.tools.javac.tree.JCTree.JCStatement;
|
||||
import com.sun.tools.javac.tree.JCTree.JCSynchronized;
|
||||
@@ -264,9 +265,11 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
|
||||
if (getCheckerFrameworkVersion(field).generateSideEffectFree()) annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genTypeRef(field, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
|
||||
}
|
||||
if (isFieldDeprecated(field)) annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
|
||||
JCModifiers mods = treeMaker.Modifiers(access, annsOnMethod);
|
||||
addCheckReturnValue(mods, field, source);
|
||||
|
||||
if (makeFinal) access |= Flags.FINAL;
|
||||
JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType,
|
||||
JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(mods, methodName, methodType,
|
||||
methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source);
|
||||
|
||||
decl.mods.annotations = decl.mods.annotations.appendList(delegates);
|
||||
|
||||
@@ -841,6 +841,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
|
||||
} else {
|
||||
methodDef = maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
|
||||
}
|
||||
addCheckReturnValue(methodDef.mods, job.builderType, job.sourceNode);
|
||||
return methodDef;
|
||||
}
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ public class HandleToString extends JavacAnnotationHandler<ToString> {
|
||||
List<JCAnnotation> annsOnMethod = List.of(overrideAnnotation);
|
||||
if (getCheckerFrameworkVersion(typeNode).generateSideEffectFree()) annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
|
||||
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, annsOnMethod);
|
||||
addCheckReturnValue(mods, typeNode, source);
|
||||
JCExpression returnType = genJavaLangTypeRef(typeNode, "String");
|
||||
|
||||
boolean first = true;
|
||||
|
||||
@@ -1556,15 +1556,9 @@ public class JavacHandlerUtil {
|
||||
}
|
||||
|
||||
public static void addCheckReturnValue(JCModifiers mods, JavacNode node, JavacNode source) {
|
||||
CheckReturnValueFlavor flavor = node.getAst().readConfiguration(ConfigurationKeys.CHECK_RETURN_VALUE_ANNOTATION);
|
||||
if (flavor == null) flavor = CheckReturnValueFlavor.NONE;
|
||||
switch (flavor) {
|
||||
case LOMBOK:
|
||||
addAnnotation(mods, node, source, "lombok.CheckReturnValue", null);
|
||||
return;
|
||||
case NONE:
|
||||
default:
|
||||
return;
|
||||
java.util.List<CheckReturnValueFlavor> flavors = node.getAst().readConfiguration(ConfigurationKeys.CHECK_RETURN_VALUE_ANNOTATION);
|
||||
for (CheckReturnValueFlavor flavor : flavors) {
|
||||
addAnnotation(mods, node, source, flavor.getMarkerAnnotationFullyQualifiedName(), null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user