aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/eclipse
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/lombok/eclipse')
-rw-r--r--src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java58
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java17
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleBuilder.java110
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleConstructor.java17
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java18
-rw-r--r--src/core/lombok/eclipse/handlers/HandleGetter.java13
-rw-r--r--src/core/lombok/eclipse/handlers/HandleSetter.java9
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/HandleSuperBuilder.java106
-rw-r--r--src/core/lombok/eclipse/handlers/HandleToString.java10
-rw-r--r--src/core/lombok/eclipse/handlers/HandleWith.java (renamed from src/core/lombok/eclipse/handlers/HandleWither.java)85
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java21
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java23
-rwxr-xr-xsrc/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java23
13 files changed, 345 insertions, 165 deletions
diff --git a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
index 11a2b9bd..0955dba6 100644
--- a/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
+++ b/src/core/lombok/eclipse/handlers/EclipseHandlerUtil.java
@@ -111,6 +111,7 @@ import lombok.core.AnnotationValues;
import lombok.core.AnnotationValues.AnnotationValue;
import lombok.core.LombokImmutableList;
import lombok.core.TypeResolver;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.configuration.NullCheckExceptionType;
import lombok.core.configuration.TypeName;
import lombok.core.debug.ProblemReporter;
@@ -184,6 +185,23 @@ public class EclipseHandlerUtil {
return ma;
}
+ public static MarkerAnnotation generateNamedAnnotation(ASTNode source, String typeName) {
+ char[][] cc = fromQualifiedName(typeName);
+ QualifiedTypeReference qtr = new QualifiedTypeReference(cc, poss(source, cc.length));
+ setGeneratedBy(qtr, source);
+ MarkerAnnotation ma = new MarkerAnnotation(qtr, source.sourceStart);
+ // No matter what value you input for sourceEnd, the AST->DOM converter of eclipse will reparse to find the end, and will fail as
+ // it can't find code that isn't really there. This results in the end position being set to 2 or 0 or some weird magic value, and thus,
+ // length, as calculated by end-start, is all screwed up, resulting in IllegalArgumentException during a setSourceRange call MUCH later in the process.
+ // We solve it by going with a voodoo magic source start value such that the calculated length so happens to exactly be 0. 0 lengths are accepted
+ // by eclipse. For some reason.
+ // TL;DR: Don't change 1. 1 is sacred. Trust the 1.
+ // issue: #408.
+ ma.sourceStart = 1;
+ setGeneratedBy(ma, source);
+ return ma;
+ }
+
public static boolean isFieldDeprecated(EclipseNode fieldNode) {
if (!(fieldNode.get() instanceof FieldDeclaration)) return false;
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
@@ -199,6 +217,11 @@ public class EclipseHandlerUtil {
return false;
}
+ public static CheckerFrameworkVersion getCheckerFrameworkVersion(EclipseNode node) {
+ CheckerFrameworkVersion cfv = node.getAst().readConfiguration(ConfigurationKeys.CHECKER_FRAMEWORK);
+ return cfv != null ? cfv : CheckerFrameworkVersion.NONE;
+ }
+
/**
* Checks if the given TypeReference node is likely to be a reference to the provided class.
*
@@ -652,15 +675,6 @@ public class EclipseHandlerUtil {
return result == null ? null : result.toArray(new Annotation[0]);
}
- public static Annotation[] mergeAnnotations(Annotation[] a, Annotation[] b) {
- if (a == null || a.length == 0) return (b == null || b.length == 0) ? null : b;
- if (b == null || b.length == 0) return a.length == 0 ? null : a;
- Annotation[] c = new Annotation[a.length + b.length];
- System.arraycopy(a, 0, c, 0, a.length);
- System.arraycopy(b, 0, c, a.length, b.length);
- return c;
- }
-
public static boolean hasAnnotation(Class<? extends java.lang.annotation.Annotation> type, EclipseNode node) {
if (node == null) return false;
if (type == null) return false;
@@ -1403,20 +1417,20 @@ public class EclipseHandlerUtil {
}
/**
- * Translates the given field into all possible wither names.
- * Convenient wrapper around {@link TransformationsUtil#toAllWitherNames(lombok.core.AnnotationValues, CharSequence, boolean)}.
+ * Translates the given field into all possible with names.
+ * Convenient wrapper around {@link TransformationsUtil#toAllWithNames(lombok.core.AnnotationValues, CharSequence, boolean)}.
*/
- public static java.util.List<String> toAllWitherNames(EclipseNode field, boolean isBoolean) {
- return HandlerUtil.toAllWitherNames(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean);
+ public static java.util.List<String> toAllWithNames(EclipseNode field, boolean isBoolean) {
+ return HandlerUtil.toAllWithNames(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean);
}
/**
- * @return the likely wither name for the stated field. (e.g. private boolean foo; to withFoo).
+ * @return the likely with name for the stated field. (e.g. private boolean foo; to withFoo).
*
- * Convenient wrapper around {@link TransformationsUtil#toWitherName(lombok.core.AnnotationValues, CharSequence, boolean)}.
+ * Convenient wrapper around {@link TransformationsUtil#toWithName(lombok.core.AnnotationValues, CharSequence, boolean)}.
*/
- public static String toWitherName(EclipseNode field, boolean isBoolean) {
- return HandlerUtil.toWitherName(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean);
+ public static String toWithName(EclipseNode field, boolean isBoolean) {
+ return HandlerUtil.toWithName(field.getAst(), getAccessorsForField(field), field.getName(), isBoolean);
}
/**
@@ -1908,11 +1922,13 @@ public class EclipseHandlerUtil {
* Create an annotation of the given name, and is marked as being generated by the given source.
*/
public static MarkerAnnotation makeMarkerAnnotation(char[][] name, ASTNode source) {
- long pos = (long)source.sourceStart << 32 | source.sourceEnd;
- TypeReference typeRef = new QualifiedTypeReference(name, new long[] {pos, pos, pos});
+ long pos = (long) source.sourceStart << 32 | source.sourceEnd;
+ long[] poss = new long[name.length];
+ Arrays.fill(poss, pos);
+ TypeReference typeRef = new QualifiedTypeReference(name, poss);
setGeneratedBy(typeRef, source);
- MarkerAnnotation ann = new MarkerAnnotation(typeRef, (int)(pos >> 32));
- ann.declarationSourceEnd = ann.sourceEnd = ann.statementEnd = (int)pos;
+ MarkerAnnotation ann = new MarkerAnnotation(typeRef, (int) (pos >> 32));
+ ann.declarationSourceEnd = ann.sourceEnd = ann.statementEnd = (int) pos;
setGeneratedBy(ann, source);
return ann;
}
diff --git a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
index a8a780d6..da0bf471 100755
--- a/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
+++ b/src/core/lombok/eclipse/handlers/EclipseSingularsRecipes.java
@@ -33,6 +33,7 @@ import java.util.Map;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
+import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.Expression;
@@ -62,6 +63,7 @@ import lombok.AccessLevel;
import lombok.core.LombokImmutableList;
import lombok.core.SpiLoadUtil;
import lombok.core.TypeLibrary;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.eclipse.EclipseNode;
public class EclipseSingularsRecipes {
@@ -235,7 +237,7 @@ public class EclipseSingularsRecipes {
* If you need more control over the return type and value, use
* {@link #generateMethods(SingularData, boolean, EclipseNode, boolean, TypeReferenceMaker, StatementMaker)}.
*/
- public void generateMethods(SingularData data, boolean deprecate, final EclipseNode builderType, boolean fluent, final boolean chain, AccessLevel access) {
+ public void generateMethods(CheckerFrameworkVersion cfv, SingularData data, boolean deprecate, final EclipseNode builderType, boolean fluent, final boolean chain, AccessLevel access) {
TypeReferenceMaker returnTypeMaker = new TypeReferenceMaker() {
@Override public TypeReference make() {
return chain ? cloneSelfType(builderType) : TypeReference.baseTypeReference(TypeIds.T_void, 0);
@@ -248,14 +250,14 @@ public class EclipseSingularsRecipes {
}
};
- generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
+ generateMethods(cfv, data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
}
/**
* Generates the singular, plural, and clear methods for the given {@link SingularData}.
* Uses the given {@code returnTypeMaker} and {@code returnStatementMaker} for the generated methods.
*/
- public abstract void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access);
+ public abstract void generateMethods(CheckerFrameworkVersion cfv, SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access);
public abstract void appendBuildCode(SingularData data, EclipseNode builderType, List<Statement> statements, char[] targetVariableName, String builderVariable);
@@ -272,6 +274,15 @@ public class EclipseSingularsRecipes {
// -- Utility methods --
+ protected Annotation[] generateSelfReturnAnnotations(boolean deprecate, CheckerFrameworkVersion cfv, ASTNode source) {
+ Annotation deprecated = deprecate ? generateDeprecatedAnnotation(source) : null;
+ Annotation returnsReceiver = cfv.generateReturnsReceiver() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) : null;
+ if (deprecated == null && returnsReceiver == null) return null;
+ if (deprecated == null) return new Annotation[] {returnsReceiver};
+ if (returnsReceiver == null) return new Annotation[] {deprecated};
+ return new Annotation[] {deprecated, returnsReceiver};
+ }
+
/**
* Adds the requested number of type arguments to the provided type, copying each argument in {@code typeArgs}. If typeArgs is too long, the extra elements are ignored.
* If {@code typeArgs} is null or too short, {@code java.lang.Object} will be substituted for each missing type argument.
diff --git a/src/core/lombok/eclipse/handlers/HandleBuilder.java b/src/core/lombok/eclipse/handlers/HandleBuilder.java
index 5a4d5bff..375bd164 100755
--- a/src/core/lombok/eclipse/handlers/HandleBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleBuilder.java
@@ -38,6 +38,7 @@ import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.Argument;
+import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
@@ -58,9 +59,11 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -85,6 +88,7 @@ import lombok.core.handlers.HandlerUtil;
import lombok.core.handlers.InclusionExclusionUtils.Included;
import lombok.core.AnnotationValues;
import lombok.core.HandlerPriority;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
@@ -156,6 +160,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
@Override public void handle(AnnotationValues<Builder> annotation, Annotation ast, EclipseNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.BUILDER_FLAG_USAGE, "@Builder");
+ CheckerFrameworkVersion cfv = getCheckerFrameworkVersion(annotationNode);
long p = (long) ast.sourceStart << 32 | ast.sourceEnd;
@@ -488,14 +493,14 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
for (BuilderFieldData bfd : builderFields) {
- makePrefixedSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain, accessForInners, bfd.originalFieldNode, builderInstance.setterPrefix());
+ makePrefixedSetterMethodsForBuilder(cfv, builderType, bfd, annotationNode, fluent, chain, accessForInners, bfd.originalFieldNode, builderInstance.setterPrefix());
}
{
MemberExistsResult methodExists = methodExists(buildMethodName, builderType, -1);
if (methodExists == MemberExistsResult.EXISTS_BY_LOMBOK) methodExists = methodExists(buildMethodName, builderType, 0);
if (methodExists == MemberExistsResult.NOT_EXISTS) {
- MethodDeclaration md = generateBuildMethod(tdParent, isStatic, buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast, accessForInners);
+ MethodDeclaration md = generateBuildMethod(cfv, tdParent, isStatic, buildMethodName, nameOfStaticBuilderMethod, returnType, builderFields, builderType, thrownExceptions, addCleaning, ast, accessForInners);
if (md != null) injectMethod(builderType, md);
}
}
@@ -518,7 +523,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
if (generateBuilderMethod) {
- MethodDeclaration md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, tdParent, typeParams, ast, accessForOuters);
+ MethodDeclaration md = generateBuilderMethod(cfv, isStatic, builderMethodName, builderClassName, tdParent, typeParams, ast, accessForOuters);
if (md != null) injectMethod(tdParent, md);
}
@@ -535,7 +540,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
tps[i].name = typeArgsForToBuilder.get(i);
}
}
- MethodDeclaration md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters);
+ MethodDeclaration md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters);
if (md != null) injectMethod(tdParent, md);
}
@@ -548,7 +553,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
private static final char[] BUILDER_TEMP_VAR = {'b', 'u', 'i', 'l', 'd', 'e', 'r'};
- private MethodDeclaration generateToBuilderMethod(String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source, AccessLevel access) {
+ private MethodDeclaration generateToBuilderMethod(CheckerFrameworkVersion cfv, String methodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, List<BuilderFieldData> builderFields, boolean fluent, ASTNode source, AccessLevel access) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
@@ -624,6 +629,10 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
out.statements = new Statement[] {new ReturnStatement(receiver, pS, pE)};
}
+ if (cfv.generateUnique()) {
+ out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
+ }
+
out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
return out;
@@ -651,7 +660,35 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return decl;
}
- public MethodDeclaration generateBuildMethod(EclipseNode tdParent, boolean isStatic, String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source, AccessLevel access) {
+ static Argument[] generateBuildArgs(CheckerFrameworkVersion cfv, EclipseNode type, List<BuilderFieldData> builderFields, ASTNode source) {
+ if (!cfv.generateCalledMethods()) return null;
+
+ List<char[]> mandatories = new ArrayList<char[]>();
+ for (BuilderFieldData bfd : builderFields) {
+ if (bfd.singularData == null && bfd.nameOfSetFlag == null) mandatories.add(bfd.name);
+ }
+
+ if (mandatories.size() == 0) return null;
+ char[][] nameCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__CALLED);
+ SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameCalled, poss(source, nameCalled.length)), source.sourceStart);
+ if (mandatories.size() == 1) {
+ ann.memberValue = new StringLiteral(mandatories.get(0), 0, 0, 0);
+ } else {
+ ArrayInitializer arr = new ArrayInitializer();
+ arr.sourceStart = source.sourceStart;
+ arr.sourceEnd = source.sourceEnd;
+ arr.expressions = new Expression[mandatories.size()];
+ for (int i = 0; i < arr.expressions.length; i++) {
+ arr.expressions[i] = new StringLiteral(mandatories.get(i), source.sourceStart, source.sourceEnd, 0);
+ }
+ ann.memberValue = arr;
+ }
+ Argument arg = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, new SingleTypeReference(type.getName().toCharArray(), source.sourceStart), Modifier.FINAL);
+ arg.annotations = new Annotation[] {ann};
+ return new Argument[] {arg};
+ }
+
+ public MethodDeclaration generateBuildMethod(CheckerFrameworkVersion cfv, EclipseNode tdParent, boolean isStatic, String name, char[] staticName, TypeReference returnType, List<BuilderFieldData> builderFields, EclipseNode type, TypeReference[] thrownExceptions, boolean addCleaning, ASTNode source, AccessLevel access) {
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
List<Statement> statements = new ArrayList<Statement>();
@@ -724,6 +761,10 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
}
}
out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
+ if (cfv.generateSideEffectFree()) {
+ out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE)};
+ }
+ out.arguments = generateBuildArgs(cfv, type, builderFields, source);
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return out;
}
@@ -755,7 +796,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
return out;
}
- public MethodDeclaration generateBuilderMethod(boolean isStatic, String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source, AccessLevel access) {
+ public MethodDeclaration generateBuilderMethod(CheckerFrameworkVersion cfv, boolean isStatic, String builderMethodName, String builderClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source, AccessLevel access) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
@@ -769,7 +810,15 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
AllocationExpression invoke = new AllocationExpression();
invoke.type = namePlusTypeParamsToTypeReference(builderClassName.toCharArray(), typeParams, p);
out.statements = new Statement[] {new ReturnStatement(invoke, pS, pE)};
-
+ Annotation uniqueAnn = cfv.generateUnique() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE) : null;
+ Annotation sefAnn = cfv.generateSideEffectFree() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) : null;
+ if (uniqueAnn != null && sefAnn != null) {
+ out.annotations = new Annotation[] {uniqueAnn, sefAnn};
+ } else if (uniqueAnn != null) {
+ out.annotations = new Annotation[] {uniqueAnn};
+ } else if (sefAnn != null) {
+ out.annotations = new Annotation[] {sefAnn};
+ }
out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
return out;
}
@@ -814,18 +863,19 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
private static final AbstractMethodDeclaration[] EMPTY = {};
- public void makeSetterMethodsForBuilder(EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, boolean fluent, boolean chain, AccessLevel access, EclipseNode originalFieldNode) {
+ public void makeSetterMethodsForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, boolean fluent, boolean chain, AccessLevel access, EclipseNode originalFieldNode) {
boolean deprecate = isFieldDeprecated(bfd.originalFieldNode);
if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) {
- makeSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, sourceNode, fluent, chain, bfd.annotations, access, originalFieldNode);
+ makeSimpleSetterMethodForBuilder(cfv, builderType, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, sourceNode, fluent, chain, bfd.annotations, access, originalFieldNode);
} else {
- bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, fluent, chain, access);
+ bfd.singularData.getSingularizer().generateMethods(cfv, bfd.singularData, deprecate, builderType, fluent, chain, access);
}
}
- private void makeSimpleSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, EclipseNode sourceNode, boolean fluent, boolean chain, Annotation[] annotations, AccessLevel access, EclipseNode originalFieldNode) {
+ private void makeSimpleSetterMethodForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, EclipseNode sourceNode, boolean fluent, boolean chain, Annotation[] annotations, AccessLevel access, EclipseNode originalFieldNode) {
TypeDeclaration td = (TypeDeclaration) builderType.get();
AbstractMethodDeclaration[] existing = td.methods;
+ ASTNode source = sourceNode.get();
if (existing == null) existing = EMPTY;
int len = existing.length;
FieldDeclaration fd = (FieldDeclaration) fieldNode.get();
@@ -839,24 +889,35 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
String setterName = fluent ? new String(paramName) : HandlerUtil.buildAccessorName("set", new String(paramName));
- List<Annotation> methodAnnsList = Collections.<Annotation>emptyList();
+ List<Annotation> methodAnnsList = Arrays.asList(EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode));
Annotation[] methodAnns = EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode);
if (methodAnns != null && methodAnns.length > 0) methodAnnsList = Arrays.asList(methodAnns);
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, chain, toEclipseModifier(access),
sourceNode, methodAnnsList, annotations != null ? Arrays.asList(copyAnnotations(sourceNode.get(), annotations)) : Collections.<Annotation>emptyList());
+ if (cfv.generateCalledMethods()) {
+ Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments;
+ Argument[] newArr = new Argument[arr.length + 1];
+ System.arraycopy(arr, 0, newArr, 1, arr.length);
+ newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, new SingleTypeReference(builderType.getName().toCharArray(), 0), Modifier.FINAL);
+ char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
+ SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart);
+ ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
+ newArr[0].annotations = new Annotation[] {ann};
+ setter.arguments = newArr;
+ }
injectMethod(builderType, setter);
}
- public void makePrefixedSetterMethodsForBuilder(EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, boolean fluent, boolean chain, AccessLevel access, EclipseNode originalFieldNode, String prefix) {
+ public void makePrefixedSetterMethodsForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, boolean fluent, boolean chain, AccessLevel access, EclipseNode originalFieldNode, String prefix) {
boolean deprecate = isFieldDeprecated(bfd.originalFieldNode);
if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) {
- makePrefixedSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, sourceNode, fluent, chain, bfd.annotations, access, originalFieldNode, prefix);
+ makePrefixedSetterMethodForBuilder(cfv, builderType, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, sourceNode, fluent, chain, bfd.annotations, access, originalFieldNode, prefix);
} else {
- bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, fluent, chain, access);
+ bfd.singularData.getSingularizer().generateMethods(cfv, bfd.singularData, deprecate, builderType, fluent, chain, access);
}
}
- private void makePrefixedSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, EclipseNode sourceNode, boolean fluent, boolean chain, Annotation[] annotations, AccessLevel access, EclipseNode originalFieldNode, String prefix) {
+ private void makePrefixedSetterMethodForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, EclipseNode sourceNode, boolean fluent, boolean chain, Annotation[] annotations, AccessLevel access, EclipseNode originalFieldNode, String prefix) {
TypeDeclaration td = (TypeDeclaration) builderType.get();
AbstractMethodDeclaration[] existing = td.methods;
if (existing == null) existing = EMPTY;
@@ -881,8 +942,21 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
List<Annotation> methodAnnsList = Collections.<Annotation>emptyList();
Annotation[] methodAnns = EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode);
if (methodAnns != null && methodAnns.length > 0) methodAnnsList = Arrays.asList(methodAnns);
+ ASTNode source = sourceNode.get();
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, chain, toEclipseModifier(access),
- sourceNode, methodAnnsList, annotations != null ? Arrays.asList(copyAnnotations(sourceNode.get(), annotations)) : Collections.<Annotation>emptyList());
+ sourceNode, methodAnnsList, annotations != null ? Arrays.asList(copyAnnotations(source, annotations)) : Collections.<Annotation>emptyList());
+ if (cfv.generateCalledMethods()) {
+ Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments;
+ Argument[] newArr = new Argument[arr.length + 1];
+ System.arraycopy(arr, 0, newArr, 1, arr.length);
+ newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, new SingleTypeReference(builderType.getName().toCharArray(), 0), Modifier.FINAL);
+ char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
+ SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(
+ source, nameNotCalled.length)), source.sourceStart);
+ ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
+ newArr[0].annotations = new Annotation[] {ann};
+ setter.arguments = newArr;
+ }
injectMethod(builderType, setter);
}
diff --git a/src/core/lombok/eclipse/handlers/HandleConstructor.java b/src/core/lombok/eclipse/handlers/HandleConstructor.java
index c6b51042..8f981c1a 100755
--- a/src/core/lombok/eclipse/handlers/HandleConstructor.java
+++ b/src/core/lombok/eclipse/handlers/HandleConstructor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2018 The Project Lombok Authors.
+ * Copyright (C) 2010-2019 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
@@ -39,6 +39,7 @@ import lombok.ConfigurationKeys;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.core.AST.Kind;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.AnnotationValues;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
@@ -456,14 +457,14 @@ public class HandleConstructor {
constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[0]);
/* Generate annotations that must be put on the generated method, and attach them. */ {
- Annotation[] constructorProperties = null;
- if (addConstructorProperties && !isLocalType(type)) {
- constructorProperties = createConstructorProperties(source, fieldsToParam);
- }
+ Annotation[] constructorProperties = null, checkerFramework = null;
+ if (addConstructorProperties && !isLocalType(type)) constructorProperties = createConstructorProperties(source, fieldsToParam);
+ if (getCheckerFrameworkVersion(type).generateUnique()) checkerFramework = new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE) };
constructor.annotations = copyAnnotations(source,
onConstructor.toArray(new Annotation[0]),
- constructorProperties);
+ constructorProperties,
+ checkerFramework);
}
constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
@@ -551,7 +552,9 @@ public class HandleConstructor {
assigns.add(nameRef);
Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL);
- parameter.annotations = copyAnnotations(source, findCopyableAnnotations(fieldNode));
+ Annotation[] checkerFramework = null;
+ if (getCheckerFrameworkVersion(fieldNode).generateUnique()) checkerFramework = new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE) };
+ parameter.annotations = copyAnnotations(source, findCopyableAnnotations(fieldNode), checkerFramework);
params.add(parameter);
}
diff --git a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
index 046b197f..1bca4767 100755
--- a/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/eclipse/handlers/HandleEqualsAndHashCode.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2018 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -42,6 +42,7 @@ import lombok.core.handlers.InclusionExclusionUtils;
import lombok.core.handlers.InclusionExclusionUtils.Included;
import lombok.core.AnnotationValues;
import lombok.core.configuration.CallSuperType;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.eclipse.Eclipse;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
@@ -235,7 +236,12 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
method.modifiers = toEclipseModifier(AccessLevel.PUBLIC);
method.returnType = TypeReference.baseTypeReference(TypeIds.T_int, 0);
setGeneratedBy(method.returnType, source);
- method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)};
+ Annotation overrideAnnotation = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source);
+ if (getCheckerFrameworkVersion(type).generateSideEffectFree()) {
+ method.annotations = new Annotation[] { overrideAnnotation, generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
+ } else {
+ method.annotations = new Annotation[] { overrideAnnotation };
+ }
method.selector = "hashCode".toCharArray();
method.thrownExceptions = null;
method.typeParameters = null;
@@ -508,7 +514,12 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
method.returnType = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
method.returnType.sourceStart = pS; method.returnType.sourceEnd = pE;
setGeneratedBy(method.returnType, source);
- method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)};
+ Annotation overrideAnnotation = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source);
+ if (getCheckerFrameworkVersion(type).generateSideEffectFree()) {
+ method.annotations = new Annotation[] { overrideAnnotation, generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
+ } else {
+ method.annotations = new Annotation[] { overrideAnnotation };
+ }
method.selector = "equals".toCharArray();
method.thrownExceptions = null;
method.typeParameters = null;
@@ -785,6 +796,7 @@ public class HandleEqualsAndHashCode extends EclipseAnnotationHandler<EqualsAndH
setGeneratedBy(returnStatement, source);
method.statements = new Statement[] {returnStatement};
+ if (getCheckerFrameworkVersion(type).generateSideEffectFree()) method.annotations = new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
return method;
}
diff --git a/src/core/lombok/eclipse/handlers/HandleGetter.java b/src/core/lombok/eclipse/handlers/HandleGetter.java
index 7d3fe62f..7ba84cdc 100644
--- a/src/core/lombok/eclipse/handlers/HandleGetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleGetter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2016 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -38,6 +38,7 @@ import lombok.experimental.Delegate;
import lombok.Getter;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.agent.PatchDelegate;
@@ -262,16 +263,16 @@ public class HandleGetter extends EclipseAnnotationHandler<Getter> {
EclipseHandlerUtil.registerCreatedLazyGetter((FieldDeclaration) fieldNode.get(), method.selector, returnType);
- /* Generate annotations that must be put on the generated method, and attach them. */ {
- Annotation[] deprecated = null;
- if (isFieldDeprecated(fieldNode)) {
- deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
- }
+ /* Generate annotations that must be put on the generated method, and attach them. */ {
+ Annotation[] deprecated = null, checkerFramework = null;
+ if (isFieldDeprecated(fieldNode)) deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
+ if (getCheckerFrameworkVersion(fieldNode).generateSideEffectFree()) checkerFramework = new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
method.annotations = copyAnnotations(source,
onMethod.toArray(new Annotation[0]),
findCopyableAnnotations(fieldNode),
findDelegatesAndMarkAsHandled(fieldNode),
+ checkerFramework,
deprecated);
}
diff --git a/src/core/lombok/eclipse/handlers/HandleSetter.java b/src/core/lombok/eclipse/handlers/HandleSetter.java
index bb704ead..8180c3fa 100644
--- a/src/core/lombok/eclipse/handlers/HandleSetter.java
+++ b/src/core/lombok/eclipse/handlers/HandleSetter.java
@@ -36,6 +36,7 @@ import lombok.AccessLevel;
import lombok.ConfigurationKeys;
import lombok.Setter;
import lombok.core.AST.Kind;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.AnnotationValues;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
@@ -200,7 +201,11 @@ public class HandleSetter extends EclipseAnnotationHandler<Setter> {
returnThis = new ReturnStatement(thisRef, pS, pE);
}
- return createSetter(parent, deprecate, fieldNode, name, paramName, booleanFieldToSet, returnType, returnThis, modifier, sourceNode, onMethod, onParam);
+ MethodDeclaration d = createSetter(parent, deprecate, fieldNode, name, paramName, booleanFieldToSet, returnType, returnThis, modifier, sourceNode, onMethod, onParam);
+ if (shouldReturnThis && getCheckerFrameworkVersion(sourceNode).generateReturnsReceiver()) {
+ d.annotations = copyAnnotations(source, d.annotations, new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) });
+ }
+ return d;
}
static MethodDeclaration createSetter(TypeDeclaration parent, boolean deprecate, EclipseNode fieldNode, String name, char[] paramName, char[] booleanFieldToSet, TypeReference returnType, Statement returnStatement, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam) {
@@ -221,7 +226,7 @@ public class HandleSetter extends EclipseAnnotationHandler<Setter> {
if (isFieldDeprecated(fieldNode) || deprecate) {
deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
}
- method.annotations = mergeAnnotations(copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated), findCopyableToSetterAnnotations(fieldNode));
+ method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated, findCopyableToSetterAnnotations(fieldNode));
Argument param = new Argument(paramName, p, copyType(field.type, source), Modifier.FINAL);
param.sourceStart = pS; param.sourceEnd = pE;
method.arguments = new Argument[] { param };
diff --git a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
index 88479911..8f0ef338 100755
--- a/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/eclipse/handlers/HandleSuperBuilder.java
@@ -57,9 +57,11 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
+import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
+import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
@@ -81,6 +83,7 @@ import lombok.ConfigurationKeys;
import lombok.Singular;
import lombok.ToString;
import lombok.core.AST.Kind;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.handlers.HandlerUtil;
import lombok.core.handlers.InclusionExclusionUtils.Included;
import lombok.core.AnnotationValues;
@@ -119,6 +122,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
@Override
public void handle(AnnotationValues<SuperBuilder> annotation, Annotation ast, EclipseNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.SUPERBUILDER_FLAG_USAGE, "@SuperBuilder");
+ CheckerFrameworkVersion cfv = getCheckerFrameworkVersion(annotationNode);
long p = (long) ast.sourceStart << 32 | ast.sourceEnd;
@@ -269,7 +273,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
// If there is no superclass, superclassBuilderClassExpression is still == null at this point.
// You can use it to check whether to inherit or not.
- generateBuilderBasedConstructor(tdParent, typeParams, builderFields, annotationNode, builderClassName,
+ generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName,
superclassBuilderClass != null);
// Create the abstract builder class, or reuse an existing one.
@@ -334,12 +338,12 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
// Generate abstract self() and build() methods in the abstract builder.
- injectMethod(builderType, generateAbstractSelfMethod(tdParent, superclassBuilderClass != null, builderGenericName));
- injectMethod(builderType, generateAbstractBuildMethod(tdParent, buildMethodName, superclassBuilderClass != null, classGenericName, ast));
+ injectMethod(builderType, generateAbstractSelfMethod(cfv, tdParent, superclassBuilderClass != null, builderGenericName));
+ injectMethod(builderType, generateAbstractBuildMethod(cfv, builderType, buildMethodName, builderFields, superclassBuilderClass != null, classGenericName, ast));
// Create the setter methods in the abstract builder.
for (BuilderFieldData bfd : builderFields) {
- generateSetterMethodsForBuilder(builderType, bfd, annotationNode, builderGenericName);
+ generateSetterMethodsForBuilder(cfv, builderType, bfd, annotationNode, builderGenericName);
}
// Create the toString() method for the abstract builder.
@@ -386,22 +390,22 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
annotationNode.addWarning("Not generating toBuilder() as it already exists.");
break;
case NOT_EXISTS:
- injectMethod(tdParent, generateToBuilderMethod(builderClassName, builderImplClassName, tdParent, typeParams, ast));
+ injectMethod(tdParent, generateToBuilderMethod(cfv, builderClassName, builderImplClassName, tdParent, typeParams, ast));
default:
// Should not happen.
}
}
// Create the self() and build() methods in the BuilderImpl.
- injectMethod(builderImplType, generateSelfMethod(builderImplType, typeParams, p));
+ injectMethod(builderImplType, generateSelfMethod(cfv, builderImplType, typeParams, p));
if (methodExists(buildMethodName, builderImplType, -1) == MemberExistsResult.NOT_EXISTS) {
- injectMethod(builderImplType, generateBuildMethod(tdParent, buildMethodName, returnType, ast));
+ injectMethod(builderImplType, generateBuildMethod(cfv, builderImplType, buildMethodName, returnType, builderFields, ast));
}
// Add the builder() method to the annotated class.
if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
if (generateBuilderMethod) {
- MethodDeclaration md = generateBuilderMethod(builderMethodName, builderClassName, builderImplClassName, tdParent, typeParams, ast);
+ MethodDeclaration md = generateBuilderMethod(cfv, builderMethodName, builderClassName, builderImplClassName, tdParent, typeParams, ast);
if (md != null) injectMethod(tdParent, md);
}
@@ -483,6 +487,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
* the type (with the {@code @Builder} annotation) for which a
* constructor should be generated.
* @param typeParams
+ * @param cfv Settings for generating checker framework annotations
* @param builderFields a list of fields in the builder which should be assigned to new instances.
* @param source the annotation (used for setting source code locations for the generated code).
* @param callBuilderBasedSuperConstructor
@@ -490,7 +495,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
* constructor with the builder as argument. Requires
* {@code builderClassAsParameter != null}.
*/
- private void generateBuilderBasedConstructor(EclipseNode typeNode, TypeParameter[] typeParams, List<BuilderFieldData> builderFields,
+ private void generateBuilderBasedConstructor(CheckerFrameworkVersion cfv, EclipseNode typeNode, TypeParameter[] typeParams, List<BuilderFieldData> builderFields,
EclipseNode sourceNode, String builderClassName, boolean callBuilderBasedSuperConstructor) {
ASTNode source = sourceNode.get();
@@ -501,6 +506,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
ConstructorDeclaration constructor = new ConstructorDeclaration(((CompilationUnitDeclaration) typeNode.top().get()).compilationResult);
constructor.modifiers = toEclipseModifier(AccessLevel.PROTECTED);
+ if (cfv.generateUnique()) constructor.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
constructor.selector = typeDeclaration.name;
if (callBuilderBasedSuperConstructor) {
constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.Super);
@@ -572,7 +578,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
injectMethod(typeNode, constructor);
}
- private MethodDeclaration generateBuilderMethod(String builderMethodName, String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
+ private MethodDeclaration generateBuilderMethod(CheckerFrameworkVersion cfv, String builderMethodName, String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
@@ -591,6 +597,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
invoke.type = namePlusTypeParamsToTypeReference(builderImplClassName.toCharArray(), typeParams, p);
out.statements = new Statement[] {new ReturnStatement(invoke, pS, pE)};
+ if (cfv.generateUnique()) out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
+
out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
return out;
}
@@ -603,7 +611,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
* }
* </pre>
*/
- private MethodDeclaration generateToBuilderMethod(String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
+ private MethodDeclaration generateToBuilderMethod(CheckerFrameworkVersion cfv, String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
int pS = source.sourceStart, pE = source.sourceEnd;
long p = (long) pS << 32 | pE;
@@ -623,6 +631,8 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
invokeFillMethod.arguments = new Expression[] {new ThisReference(0, 0)};
out.statements = new Statement[] {new ReturnStatement(invokeFillMethod, pS, pE)};
+ if (cfv.generateUnique()) out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
+
out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
return out;
}
@@ -755,44 +765,64 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
return ms;
}
- private MethodDeclaration generateAbstractSelfMethod(EclipseNode tdParent, boolean override, String builderGenericName) {
+ private MethodDeclaration generateAbstractSelfMethod(CheckerFrameworkVersion cfv, EclipseNode tdParent, boolean override, String builderGenericName) {
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) tdParent.top().get()).compilationResult);
out.selector = SELF_METHOD_NAME;
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.modifiers = ClassFileConstants.AccAbstract | ClassFileConstants.AccProtected | ExtraCompilerModifiers.AccSemicolonBody;
- if (override) out.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, tdParent.get())};
+ Annotation overrideAnn = override ? makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, tdParent.get()) : null;
+ Annotation rrAnn = cfv.generateReturnsReceiver() ? generateNamedAnnotation(tdParent.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER): null;
+ Annotation sefAnn = cfv.generateSideEffectFree() ? generateNamedAnnotation(tdParent.get(), CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE): null;
+ if (overrideAnn != null && rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn, sefAnn};
+ else if (overrideAnn != null && rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn};
+ else if (overrideAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
+ else if (overrideAnn != null) out.annotations = new Annotation[] {overrideAnn};
+ else if (rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {rrAnn, sefAnn};
+ else if (rrAnn != null) out.annotations = new Annotation[] {rrAnn};
+ else if (sefAnn != null) out.annotations = new Annotation[] {sefAnn};
out.returnType = new SingleTypeReference(builderGenericName.toCharArray(), 0);
return out;
}
- private MethodDeclaration generateSelfMethod(EclipseNode builderImplType, TypeParameter[] typeParams, long p) {
+ private MethodDeclaration generateSelfMethod(CheckerFrameworkVersion cfv, EclipseNode builderImplType, TypeParameter[] typeParams, long p) {
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) builderImplType.top().get()).compilationResult);
out.selector = SELF_METHOD_NAME;
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.modifiers = ClassFileConstants.AccProtected;
- out.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, builderImplType.get())};
+ Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, builderImplType.get());
+ Annotation rrAnn = cfv.generateReturnsReceiver() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER): null;
+ Annotation sefAnn = cfv.generateSideEffectFree() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE): null;
+ if (rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn, sefAnn};
+ else if (rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn};
+ else if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
+ else out.annotations = new Annotation[] {overrideAnn};
out.returnType = namePlusTypeParamsToTypeReference(builderImplType.getName().toCharArray(), typeParams, p);
out.statements = new Statement[] {new ReturnStatement(new ThisReference(0, 0), 0, 0)};
return out;
}
- private MethodDeclaration generateAbstractBuildMethod(EclipseNode tdParent, String methodName, boolean override,
+ private MethodDeclaration generateAbstractBuildMethod(CheckerFrameworkVersion cfv, EclipseNode builderType, String methodName, List<BuilderFieldData> builderFields, boolean override,
String classGenericName, ASTNode source) {
- MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) tdParent.top().get()).compilationResult);
+ MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract | ExtraCompilerModifiers.AccSemicolonBody;
out.selector = methodName.toCharArray();
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.returnType = new SingleTypeReference(classGenericName.toCharArray(), 0);
- if (override) out.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)};
+ Annotation overrideAnn = override ? makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source) : null;
+ Annotation sefAnn = cfv.generateSideEffectFree() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE): null;
+ if (overrideAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
+ else if (overrideAnn != null) out.annotations = new Annotation[] {overrideAnn};
+ else if (sefAnn != null) out.annotations = new Annotation[] {sefAnn};
+ out.arguments = HandleBuilder.generateBuildArgs(cfv, builderType, builderFields, source);
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
return out;
}
- private MethodDeclaration generateBuildMethod(EclipseNode tdParent, String name, TypeReference returnType, ASTNode source) {
- MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) tdParent.top().get()).compilationResult);
+ private MethodDeclaration generateBuildMethod(CheckerFrameworkVersion cfv, EclipseNode builderType, String name, TypeReference returnType, List<BuilderFieldData> builderFields, ASTNode source) {
+ MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
List<Statement> statements = new ArrayList<Statement>();
@@ -800,7 +830,10 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
out.selector = name.toCharArray();
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
out.returnType = returnType;
- out.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)};
+ Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source);
+ Annotation sefAnn = cfv.generateSideEffectFree() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE): null;
+ if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
+ else out.annotations = new Annotation[] {overrideAnn};
AllocationExpression allocationStatement = new AllocationExpression();
allocationStatement.type = copyType(out.returnType);
@@ -809,6 +842,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
statements.add(new ReturnStatement(allocationStatement, 0, 0));
out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
+ out.arguments = HandleBuilder.generateBuildArgs(cfv, builderType, builderFields, source);
return out;
}
@@ -872,7 +906,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
}
}
- private void generateSetterMethodsForBuilder(EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, final String builderGenericName) {
+ private void generateSetterMethodsForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, final String builderGenericName) {
boolean deprecate = isFieldDeprecated(bfd.originalFieldNode);
TypeReferenceMaker returnTypeMaker = new TypeReferenceMaker() {
@@ -891,14 +925,15 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
};
if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) {
- generateSimpleSetterMethodForBuilder(builderType, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, true, returnTypeMaker.make(), returnStatementMaker.make(), sourceNode, bfd.annotations, bfd.originalFieldNode);
+ generateSimpleSetterMethodForBuilder(cfv, builderType, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, true, returnTypeMaker.make(), returnStatementMaker.make(), sourceNode, bfd.annotations, bfd.originalFieldNode);
} else {
- bfd.singularData.getSingularizer().generateMethods(bfd.singularData, deprecate, builderType, true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
+ bfd.singularData.getSingularizer().generateMethods(cfv, bfd.singularData, deprecate, builderType, true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
}
}
- private void generateSimpleSetterMethodForBuilder(EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, boolean fluent, TypeReference returnType, Statement returnStatement, EclipseNode sourceNode, Annotation[] annosOnParam, EclipseNode originalFieldNode) {
+ private void generateSimpleSetterMethodForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, boolean fluent, TypeReference returnType, Statement returnStatement, EclipseNode sourceNode, Annotation[] annosOnParam, EclipseNode originalFieldNode) {
TypeDeclaration td = (TypeDeclaration) builderType.get();
+ ASTNode source = sourceNode.get();
AbstractMethodDeclaration[] existing = td.methods;
if (existing == null) existing = EMPTY_METHODS;
int len = existing.length;
@@ -913,11 +948,24 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
String setterName = fluent ? new String(paramName) : HandlerUtil.buildAccessorName("set", new String(paramName));
- List<Annotation> methodAnnsList = Collections.<Annotation>emptyList();
- Annotation[] methodAnns = EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode);
- if (methodAnns != null && methodAnns.length > 0) methodAnnsList = Arrays.asList(methodAnns);
+ List<Annotation> methodAnnsList = Arrays.asList(EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode));
+ if (cfv.generateReturnsReceiver()) {
+ methodAnnsList = new ArrayList<Annotation>(methodAnnsList);
+ methodAnnsList.add(generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER));
+ }
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, returnType, returnStatement, ClassFileConstants.AccPublic,
- sourceNode, methodAnnsList, annosOnParam != null ? Arrays.asList(copyAnnotations(sourceNode.get(), annosOnParam)) : Collections.<Annotation>emptyList());
+ sourceNode, methodAnnsList, annosOnParam != null ? Arrays.asList(copyAnnotations(source, annosOnParam)) : Collections.<Annotation>emptyList());
+ if (cfv.generateCalledMethods()) {
+ Argument[] arr = setter.arguments == null ? new Argument[0] : setter.arguments;
+ Argument[] newArr = new Argument[arr.length + 1];
+ System.arraycopy(arr, 0, newArr, 1, arr.length);
+ newArr[0] = new Argument(new char[] { 't', 'h', 'i', 's' }, 0, new SingleTypeReference(builderType.getName().toCharArray(), 0), Modifier.FINAL);
+ char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
+ SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart);
+ ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
+ newArr[0].annotations = new Annotation[] {ann};
+ setter.arguments = newArr;
+ }
injectMethod(builderType, setter);
}
diff --git a/src/core/lombok/eclipse/handlers/HandleToString.java b/src/core/lombok/eclipse/handlers/HandleToString.java
index bb52feb5..39fd5937 100644
--- a/src/core/lombok/eclipse/handlers/HandleToString.java
+++ b/src/core/lombok/eclipse/handlers/HandleToString.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2018 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -60,6 +60,7 @@ import lombok.ToString;
import lombok.core.AST.Kind;
import lombok.core.AnnotationValues;
import lombok.core.configuration.CallSuperType;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.handlers.HandlerUtil.FieldAccess;
import lombok.core.handlers.InclusionExclusionUtils;
import lombok.core.handlers.InclusionExclusionUtils.Included;
@@ -300,7 +301,12 @@ public class HandleToString extends EclipseAnnotationHandler<ToString> {
method.modifiers = toEclipseModifier(AccessLevel.PUBLIC);
method.returnType = new QualifiedTypeReference(TypeConstants.JAVA_LANG_STRING, new long[] {p, p, p});
setGeneratedBy(method.returnType, source);
- method.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source)};
+ Annotation overrideAnnotation = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source);
+ if (getCheckerFrameworkVersion(type).generateSideEffectFree()) {
+ method.annotations = new Annotation[] { overrideAnnotation, generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
+ } else {
+ method.annotations = new Annotation[] { overrideAnnotation };
+ }
method.arguments = null;
method.selector = "toString".toCharArray();
method.thrownExceptions = null;
diff --git a/src/core/lombok/eclipse/handlers/HandleWither.java b/src/core/lombok/eclipse/handlers/HandleWith.java
index a99789a6..8c8c3712 100644
--- a/src/core/lombok/eclipse/handlers/HandleWither.java
+++ b/src/core/lombok/eclipse/handlers/HandleWith.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012-2014 The Project Lombok Authors.
+ * Copyright (C) 2012-2019 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
@@ -32,11 +32,12 @@ import java.util.List;
import lombok.AccessLevel;
import lombok.ConfigurationKeys;
+import lombok.With;
import lombok.core.AST.Kind;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.AnnotationValues;
import lombok.eclipse.EclipseAnnotationHandler;
import lombok.eclipse.EclipseNode;
-import lombok.experimental.Wither;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
@@ -59,10 +60,10 @@ import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers;
import org.mangosdk.spi.ProviderFor;
@ProviderFor(EclipseAnnotationHandler.class)
-public class HandleWither extends EclipseAnnotationHandler<Wither> {
- public boolean generateWitherForType(EclipseNode typeNode, EclipseNode pos, AccessLevel level, boolean checkForTypeLevelWither) {
- if (checkForTypeLevelWither) {
- if (hasAnnotation(Wither.class, typeNode)) {
+public class HandleWith extends EclipseAnnotationHandler<With> {
+ public boolean generateWithForType(EclipseNode typeNode, EclipseNode pos, AccessLevel level, boolean checkForTypeLevelWith) {
+ if (checkForTypeLevelWith) {
+ if (hasAnnotation(With.class, typeNode)) {
//The annotation will make it happen, so we can skip it.
return true;
}
@@ -75,7 +76,7 @@ public class HandleWither extends EclipseAnnotationHandler<Wither> {
(ClassFileConstants.AccInterface | ClassFileConstants.AccAnnotation | ClassFileConstants.AccEnum)) != 0;
if (typeDecl == null || notAClass) {
- pos.addError("@Wither is only supported on a class or a field.");
+ pos.addError("@With is only supported on a class or a field.");
return false;
}
@@ -87,28 +88,28 @@ public class HandleWither extends EclipseAnnotationHandler<Wither> {
//Skip final fields.
if ((fieldDecl.modifiers & ClassFileConstants.AccFinal) != 0 && fieldDecl.initialization != null) continue;
- generateWitherForField(field, pos, level);
+ generateWithForField(field, pos, level);
}
return true;
}
/**
- * Generates a wither on the stated field.
+ * Generates a with on the stated field.
*
* Used by {@link HandleValue}.
*
* The difference between this call and the handle method is as follows:
*
- * If there is a {@code lombok.experimental.Wither} annotation on the field, it is used and the
+ * If there is a {@code lombok.With} annotation on the field, it is used and the
* same rules apply (e.g. warning if the method already exists, stated access level applies).
- * If not, the wither is still generated if it isn't already there, though there will not
+ * If not, the with method is still generated if it isn't already there, though there will not
* be a warning if its already there. The default access level is used.
*/
- public void generateWitherForField(EclipseNode fieldNode, EclipseNode sourceNode, AccessLevel level) {
+ public void generateWithForField(EclipseNode fieldNode, EclipseNode sourceNode, AccessLevel level) {
for (EclipseNode child : fieldNode.down()) {
if (child.getKind() == Kind.ANNOTATION) {
- if (annotationTypeMatches(Wither.class, child)) {
+ if (annotationTypeMatches(With.class, child)) {
//The annotation will make it happen, so we can skip it.
return;
}
@@ -116,49 +117,49 @@ public class HandleWither extends EclipseAnnotationHandler<Wither> {
}
List<Annotation> empty = Collections.emptyList();
- createWitherForField(level, fieldNode, sourceNode, false, empty, empty);
+ createWithForField(level, fieldNode, sourceNode, false, empty, empty);
}
- @Override public void handle(AnnotationValues<Wither> annotation, Annotation ast, EclipseNode annotationNode) {
- handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.WITHER_FLAG_USAGE, "@Wither");
+ @Override public void handle(AnnotationValues<With> annotation, Annotation ast, EclipseNode annotationNode) {
+ handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.WITH_FLAG_USAGE, "@With");
EclipseNode node = annotationNode.up();
AccessLevel level = annotation.getInstance().value();
if (level == AccessLevel.NONE || node == null) return;
- List<Annotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@Wither(onMethod", annotationNode);
- List<Annotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@Wither(onParam", annotationNode);
+ List<Annotation> onMethod = unboxAndRemoveAnnotationParameter(ast, "onMethod", "@With(onMethod", annotationNode);
+ List<Annotation> onParam = unboxAndRemoveAnnotationParameter(ast, "onParam", "@With(onParam", annotationNode);
switch (node.getKind()) {
case FIELD:
- createWitherForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, true, onMethod, onParam);
+ createWithForFields(level, annotationNode.upFromAnnotationToFields(), annotationNode, true, onMethod, onParam);
break;
case TYPE:
if (!onMethod.isEmpty()) {
- annotationNode.addError("'onMethod' is not supported for @Wither on a type.");
+ annotationNode.addError("'onMethod' is not supported for @With on a type.");
}
if (!onParam.isEmpty()) {
- annotationNode.addError("'onParam' is not supported for @Wither on a type.");
+ annotationNode.addError("'onParam' is not supported for @With on a type.");
}
- generateWitherForType(node, annotationNode, level, false);
+ generateWithForType(node, annotationNode, level, false);
break;
}
}
- public void createWitherForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode sourceNode, boolean whineIfExists, List<Annotation> onMethod, List<Annotation> onParam) {
+ public void createWithForFields(AccessLevel level, Collection<EclipseNode> fieldNodes, EclipseNode sourceNode, boolean whineIfExists, List<Annotation> onMethod, List<Annotation> onParam) {
for (EclipseNode fieldNode : fieldNodes) {
- createWitherForField(level, fieldNode, sourceNode, whineIfExists, onMethod, onParam);
+ createWithForField(level, fieldNode, sourceNode, whineIfExists, onMethod, onParam);
}
}
- public void createWitherForField(
+ public void createWithForField(
AccessLevel level, EclipseNode fieldNode, EclipseNode sourceNode,
boolean whineIfExists, List<Annotation> onMethod,
List<Annotation> onParam) {
ASTNode source = sourceNode.get();
if (fieldNode.getKind() != Kind.FIELD) {
- sourceNode.addError("@Wither is only supported on a class or a field.");
+ sourceNode.addError("@With is only supported on a class or a field.");
return;
}
@@ -168,38 +169,38 @@ public class HandleWither extends EclipseAnnotationHandler<Wither> {
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
TypeReference fieldType = copyType(field.type, source);
boolean isBoolean = isBoolean(fieldType);
- String witherName = toWitherName(fieldNode, isBoolean);
+ String withName = toWithName(fieldNode, isBoolean);
- if (witherName == null) {
- fieldNode.addWarning("Not generating wither for this field: It does not fit your @Accessors prefix list.");
+ if (withName == null) {
+ fieldNode.addWarning("Not generating a with method for this field: It does not fit your @Accessors prefix list.");
return;
}
if ((field.modifiers & ClassFileConstants.AccStatic) != 0) {
- fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for static fields.");
+ fieldNode.addWarning("Not generating " + withName + " for this field: With methods cannot be generated for static fields.");
return;
}
if ((field.modifiers & ClassFileConstants.AccFinal) != 0 && field.initialization != null) {
- fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for final, initialized fields.");
+ fieldNode.addWarning("Not generating " + withName + " for this field: With methods cannot be generated for final, initialized fields.");
return;
}
if (field.name != null && field.name.length > 0 && field.name[0] == '$') {
- fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for fields starting with $.");
+ fieldNode.addWarning("Not generating " + withName + " for this field: With methods cannot be generated for fields starting with $.");
return;
}
- for (String altName : toAllWitherNames(fieldNode, isBoolean)) {
+ for (String altName : toAllWithNames(fieldNode, isBoolean)) {
switch (methodExists(altName, fieldNode, false, 1)) {
case EXISTS_BY_LOMBOK:
return;
case EXISTS_BY_USER:
if (whineIfExists) {
String altNameExpl = "";
- if (!altName.equals(witherName)) altNameExpl = String.format(" (%s)", altName);
+ if (!altName.equals(withName)) altNameExpl = String.format(" (%s)", altName);
fieldNode.addWarning(
- String.format("Not generating %s(): A method with that name already exists%s", witherName, altNameExpl));
+ String.format("Not generating %s(): A method with that name already exists%s", withName, altNameExpl));
}
return;
default:
@@ -210,11 +211,11 @@ public class HandleWither extends EclipseAnnotationHandler<Wither> {
int modifier = toEclipseModifier(level);
- MethodDeclaration method = createWither((TypeDeclaration) fieldNode.up().get(), fieldNode, witherName, modifier, sourceNode, onMethod, onParam, makeAbstract);
+ MethodDeclaration method = createWith((TypeDeclaration) fieldNode.up().get(), fieldNode, withName, modifier, sourceNode, onMethod, onParam, makeAbstract);
injectMethod(fieldNode.up(), method);
}
- public MethodDeclaration createWither(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam, boolean makeAbstract ) {
+ public MethodDeclaration createWith(TypeDeclaration parent, EclipseNode fieldNode, String name, int modifier, EclipseNode sourceNode, List<Annotation> onMethod, List<Annotation> onParam, boolean makeAbstract ) {
ASTNode source = sourceNode.get();
if (name == null) return null;
FieldDeclaration field = (FieldDeclaration) fieldNode.get();
@@ -226,11 +227,11 @@ public class HandleWither extends EclipseAnnotationHandler<Wither> {
method.returnType = cloneSelfType(fieldNode, source);
if (method.returnType == null) return null;
- Annotation[] deprecated = null;
- if (isFieldDeprecated(fieldNode)) {
- deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
- }
- method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), deprecated);
+ Annotation[] deprecated = null, checkerFramework = null;
+ if (isFieldDeprecated(fieldNode)) deprecated = new Annotation[] { generateDeprecatedAnnotation(source) };
+ if (getCheckerFrameworkVersion(fieldNode).generateSideEffectFree()) checkerFramework = new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE) };
+
+ method.annotations = copyAnnotations(source, onMethod.toArray(new Annotation[0]), checkerFramework, deprecated);
Argument param = new Argument(field.name, p, copyType(field.type, source), ClassFileConstants.AccFinal);
param.sourceStart = pS; param.sourceEnd = pE;
method.arguments = new Argument[] { param };
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
index 642ba9b7..338f5eab 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseGuavaSingularizer.java
@@ -31,6 +31,7 @@ import java.util.List;
import lombok.AccessLevel;
import lombok.core.GuavaTypeMap;
import lombok.core.LombokImmutableList;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.HandleNonNull;
@@ -111,13 +112,13 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
}
- @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
- generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
- generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
- generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
+ @Override public void generateMethods(CheckerFrameworkVersion cfv, SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
+ generateSingularMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generatePluralMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generateClearMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
}
- void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
+ void generateClearMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = toEclipseModifier(access);
@@ -128,13 +129,13 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
md.selector = HandlerUtil.buildAccessorName("clear", new String(data.getPluralName())).toCharArray();
md.statements = returnStatement != null ? new Statement[] {a, returnStatement} : new Statement[] {a};
md.returnType = returnType;
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
- void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
+ void generateSingularMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
LombokImmutableList<String> suffixes = getArgumentSuffixes();
char[][] names = new char[suffixes.size()][];
for (int i = 0; i < suffixes.size(); i++) {
@@ -172,13 +173,13 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
}
md.returnType = returnType;
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(getAddMethodName(), new String(data.getSingularName())).toCharArray();
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
HandleNonNull.INSTANCE.fix(injectMethod(builderType, md));
}
- void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
+ void generatePluralMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = toEclipseModifier(access);
@@ -204,7 +205,7 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
md.arguments = new Argument[] {param};
md.returnType = returnType;
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName(getAddMethodName() + "All", new String(data.getPluralName())).toCharArray();
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
index 73d6fe9b..53ea15a6 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSetSingularizer.java
@@ -29,6 +29,7 @@ import java.util.Collections;
import java.util.List;
import lombok.AccessLevel;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.HandleNonNull;
@@ -91,18 +92,18 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
return Collections.singletonList(injectFieldAndMarkGenerated(builderType, buildField));
}
- @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
+ @Override public void generateMethods(CheckerFrameworkVersion cfv, SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
if (useGuavaInstead(builderType)) {
- guavaListSetSingularizer.generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
+ guavaListSetSingularizer.generateMethods(cfv, data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
return;
}
- generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
- generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
- generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
+ generateSingularMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generatePluralMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generateClearMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
}
- private void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
+ private void generateClearMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = toEclipseModifier(access);
@@ -118,13 +119,13 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsg, 0, 0);
md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement};
md.returnType = returnType;
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
- void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
+ void generateSingularMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = toEclipseModifier(access);
@@ -150,13 +151,13 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
md.arguments = new Argument[] {param};
md.returnType = returnType;
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
HandleNonNull.INSTANCE.fix(injectMethod(builderType, md));
}
- void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
+ void generatePluralMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = toEclipseModifier(access);
@@ -181,7 +182,7 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
md.arguments = new Argument[] {param};
md.returnType = returnType;
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
index b642522f..8684987f 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilMapSingularizer.java
@@ -54,6 +54,7 @@ import org.mangosdk.spi.ProviderFor;
import lombok.AccessLevel;
import lombok.core.LombokImmutableList;
+import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.handlers.HandlerUtil;
import lombok.eclipse.EclipseNode;
import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
@@ -150,18 +151,18 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
return Arrays.asList(keyFieldNode, valueFieldNode);
}
- @Override public void generateMethods(SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
+ @Override public void generateMethods(CheckerFrameworkVersion cfv, SingularData data, boolean deprecate, EclipseNode builderType, boolean fluent, TypeReferenceMaker returnTypeMaker, StatementMaker returnStatementMaker, AccessLevel access) {
if (useGuavaInstead(builderType)) {
- guavaMapSingularizer.generateMethods(data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
+ guavaMapSingularizer.generateMethods(cfv, data, deprecate, builderType, fluent, returnTypeMaker, returnStatementMaker, access);
return;
}
- generateSingularMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
- generatePluralMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
- generateClearMethod(deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
+ generateSingularMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generatePluralMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, fluent, access);
+ generateClearMethod(cfv, deprecate, returnTypeMaker.make(), returnStatementMaker.make(), data, builderType, access);
}
- private void generateClearMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
+ private void generateClearMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = toEclipseModifier(access);
@@ -188,13 +189,13 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
Statement clearStatement = new IfStatement(new EqualExpression(thisDotField, new NullLiteral(0, 0), OperatorIds.NOT_EQUAL), clearMsgs, 0, 0);
md.statements = returnStatement != null ? new Statement[] {clearStatement, returnStatement} : new Statement[] {clearStatement};
md.returnType = returnType;
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);
}
- private void generateSingularMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
+ private void generateSingularMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = toEclipseModifier(access);
@@ -245,13 +246,13 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
md.arguments = new Argument[] {keyParam, valueParam};
md.returnType = returnType;
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("put", new String(data.getSingularName())).toCharArray();
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
HandleNonNull.INSTANCE.fix(injectMethod(builderType, md));
}
- private void generatePluralMethod(boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
+ private void generatePluralMethod(CheckerFrameworkVersion cfv, boolean deprecate, TypeReference returnType, Statement returnStatement, SingularData data, EclipseNode builderType, boolean fluent, AccessLevel access) {
MethodDeclaration md = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
md.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
md.modifiers = toEclipseModifier(access);
@@ -309,7 +310,7 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
md.arguments = new Argument[] {param};
md.returnType = returnType;
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("putAll", new String(data.getPluralName())).toCharArray();
- md.annotations = deprecate ? new Annotation[] { generateDeprecatedAnnotation(data.getSource()) } : null;
+ md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
data.setGeneratedByRecursive(md);
injectMethod(builderType, md);