mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-13 08:15:48 +00:00
Merge branch 'floralvikings-feature/builder-setter-prefixes'
This commit is contained in:
83 files changed
+4310
-51
No files matched your search
@@ -153,6 +153,22 @@ public @interface Builder {
|
||||
* @return The builder class will be generated with this access modifier.
|
||||
*/
|
||||
AccessLevel access() default lombok.AccessLevel.PUBLIC;
|
||||
|
||||
/**
|
||||
* Prefix to prepend to 'set' methods in the generated builder class. By default, generated methods do not include a prefix.
|
||||
*
|
||||
* For example, a method normally generated as {@code someField(String someField)} would instead be
|
||||
* generated as {@code withSomeField(String someField)} if using {@code @Builder(setterPrefix = "with")}.
|
||||
*
|
||||
* Note that using "with" to prefix builder setter methods is strongly discouraged as as "with" normally
|
||||
* suggests immutable data structures, and builders by definition are mutable objects.
|
||||
*
|
||||
* For {@code @Singular} fields, the generated methods are called {@code withName}, {@code withNames}, and {@code clearNames}, instead of
|
||||
* the default {@code name}, {@code names}, and {@code clearNames}.
|
||||
*
|
||||
* @return The prefix to prepend to generated method names.
|
||||
*/
|
||||
String setterPrefix() default "";
|
||||
|
||||
/**
|
||||
* Put on a field (in case of {@code @Builder} on a type) or a parameter (for {@code @Builder} on a constructor or static method) to
|
||||
|
||||
@@ -122,12 +122,17 @@ public class EclipseSingularsRecipes {
|
||||
private final EclipseNode annotation;
|
||||
private final char[] singularName;
|
||||
private final char[] pluralName;
|
||||
private final char[] setterPrefix;
|
||||
private final List<TypeReference> typeArgs;
|
||||
private final String targetFqn;
|
||||
private final EclipseSingularizer singularizer;
|
||||
private final ASTNode source;
|
||||
|
||||
public SingularData(EclipseNode annotation, char[] singularName, char[] pluralName, List<TypeReference> typeArgs, String targetFqn, EclipseSingularizer singularizer, ASTNode source) {
|
||||
this(annotation, singularName, pluralName, typeArgs, targetFqn, singularizer, source, new char[0]);
|
||||
}
|
||||
|
||||
public SingularData(EclipseNode annotation, char[] singularName, char[] pluralName, List<TypeReference> typeArgs, String targetFqn, EclipseSingularizer singularizer, ASTNode source, char[] setterPrefix) {
|
||||
this.annotation = annotation;
|
||||
this.singularName = singularName;
|
||||
this.pluralName = pluralName;
|
||||
@@ -135,6 +140,7 @@ public class EclipseSingularsRecipes {
|
||||
this.targetFqn = targetFqn;
|
||||
this.singularizer = singularizer;
|
||||
this.source = source;
|
||||
this.setterPrefix = setterPrefix;
|
||||
}
|
||||
|
||||
public void setGeneratedByRecursive(ASTNode target) {
|
||||
@@ -165,6 +171,10 @@ public class EclipseSingularsRecipes {
|
||||
return pluralName;
|
||||
}
|
||||
|
||||
public char[] getSetterPrefix() {
|
||||
return setterPrefix;
|
||||
}
|
||||
|
||||
public List<TypeReference> getTypeArgs() {
|
||||
return typeArgs;
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
bfd.builderFieldName = bfd.name;
|
||||
bfd.annotations = copyAnnotations(fd, copyableAnnotations);
|
||||
bfd.type = fd.type;
|
||||
bfd.singularData = getSingularData(fieldNode, ast);
|
||||
bfd.singularData = getSingularData(fieldNode, ast, builderInstance.setterPrefix());
|
||||
bfd.originalFieldNode = fieldNode;
|
||||
|
||||
if (bfd.singularData != null && isDefault != null) {
|
||||
@@ -422,7 +422,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
bfd.builderFieldName = bfd.name;
|
||||
bfd.annotations = copyAnnotations(arg, copyableAnnotations);
|
||||
bfd.type = arg.type;
|
||||
bfd.singularData = getSingularData(param, ast);
|
||||
bfd.singularData = getSingularData(param, ast, builderInstance.setterPrefix());
|
||||
bfd.originalFieldNode = param;
|
||||
addObtainVia(bfd, param);
|
||||
builderFields.add(bfd);
|
||||
@@ -492,7 +492,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
makeSetterMethodsForBuilder(cfv, builderType, bfd, annotationNode, fluent, chain, accessForInners, bfd.originalFieldNode);
|
||||
makePrefixedSetterMethodsForBuilder(cfv, builderType, bfd, annotationNode, fluent, chain, accessForInners, bfd.originalFieldNode, builderInstance.setterPrefix());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -539,7 +539,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
tps[i].name = typeArgsForToBuilder.get(i);
|
||||
}
|
||||
}
|
||||
MethodDeclaration md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters);
|
||||
MethodDeclaration md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters, builderInstance.setterPrefix());
|
||||
|
||||
if (md != null) injectMethod(tdParent, md);
|
||||
}
|
||||
@@ -552,7 +552,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
private static final char[] BUILDER_TEMP_VAR = {'b', 'u', 'i', 'l', 'd', 'e', 'r'};
|
||||
private MethodDeclaration generateToBuilderMethod(CheckerFrameworkVersion cfv, 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, String prefix) {
|
||||
int pS = source.sourceStart, pE = source.sourceEnd;
|
||||
long p = (long) pS << 32 | pE;
|
||||
|
||||
@@ -567,7 +567,10 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
Expression receiver = invoke;
|
||||
List<Statement> statements = null;
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
char[] setterName = fluent ? bfd.name : HandlerUtil.buildAccessorName("set", new String(bfd.name)).toCharArray();
|
||||
String setterName = new String(bfd.name);
|
||||
String setterPrefix = !prefix.isEmpty() ? prefix : fluent ? "" : "set";
|
||||
if (!setterPrefix.isEmpty()) setterName = HandlerUtil.buildAccessorName(setterPrefix, setterName);
|
||||
|
||||
MessageSend ms = new MessageSend();
|
||||
Expression[] tgt = new Expression[bfd.singularData == null ? 1 : 2];
|
||||
|
||||
@@ -600,7 +603,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
}
|
||||
|
||||
ms.selector = setterName;
|
||||
ms.selector = setterName.toCharArray();
|
||||
if (bfd.singularData == null) {
|
||||
ms.arguments = tgt;
|
||||
ms.receiver = receiver;
|
||||
@@ -634,7 +637,6 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
|
||||
out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
|
||||
return out;
|
||||
|
||||
}
|
||||
|
||||
private MethodDeclaration generateCleanMethod(List<BuilderFieldData> builderFields, EclipseNode builderType, ASTNode source) {
|
||||
@@ -746,10 +748,11 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
} else {
|
||||
MessageSend invoke = new MessageSend();
|
||||
invoke.selector = staticName;
|
||||
if (isStatic)
|
||||
if (isStatic) {
|
||||
invoke.receiver = new SingleNameReference(type.up().getName().toCharArray(), 0);
|
||||
else
|
||||
} else {
|
||||
invoke.receiver = new QualifiedThisReference(new SingleTypeReference(type.up().getName().toCharArray(), 0) , 0, 0);
|
||||
}
|
||||
|
||||
invoke.typeArguments = typeParameterNames(((TypeDeclaration) type.get()).typeParameters);
|
||||
invoke.arguments = args.isEmpty() ? null : args.toArray(new Expression[0]);
|
||||
@@ -862,33 +865,39 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
|
||||
private static final AbstractMethodDeclaration[] EMPTY = {};
|
||||
|
||||
public void makeSetterMethodsForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, boolean fluent, boolean chain, AccessLevel access, EclipseNode originalFieldNode) {
|
||||
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) {
|
||||
makeSimpleSetterMethodForBuilder(cfv, builderType, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, sourceNode, fluent, chain, bfd.annotations, access, originalFieldNode);
|
||||
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(cfv, bfd.singularData, deprecate, builderType, fluent, chain, access);
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
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;
|
||||
ASTNode source = sourceNode.get();
|
||||
if (existing == null) existing = EMPTY;
|
||||
int len = existing.length;
|
||||
FieldDeclaration fd = (FieldDeclaration) fieldNode.get();
|
||||
char[] name = fd.name;
|
||||
|
||||
String setterPrefix = prefix.isEmpty() ? "set" : prefix;
|
||||
String setterName;
|
||||
if(fluent) {
|
||||
setterName = prefix.isEmpty() ? new String(paramName) : HandlerUtil.buildAccessorName(setterPrefix, new String(paramName));
|
||||
} else {
|
||||
setterName = HandlerUtil.buildAccessorName(setterPrefix, new String(paramName));
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (!(existing[i] instanceof MethodDeclaration)) continue;
|
||||
char[] existingName = existing[i].selector;
|
||||
if (Arrays.equals(name, existingName) && !isTolerate(fieldNode, existing[i])) return;
|
||||
if (Arrays.equals(setterName.toCharArray(), existingName) && !isTolerate(fieldNode, existing[i])) return;
|
||||
}
|
||||
|
||||
String setterName = fluent ? new String(paramName) : HandlerUtil.buildAccessorName("set", new String(paramName));
|
||||
|
||||
List<Annotation> methodAnnsList = Arrays.asList(EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode));
|
||||
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(source, annotations)) : Collections.<Annotation>emptyList());
|
||||
if (cfv.generateCalledMethods()) {
|
||||
@@ -897,7 +906,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
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);
|
||||
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;
|
||||
@@ -932,8 +942,9 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
* or parameter), or null if there's no {@code @Singular} annotation on it.
|
||||
*
|
||||
* @param node The node (field or method param) to inspect for its name and potential {@code @Singular} annotation.
|
||||
* @param setterPrefix Explicitly requested setter prefix.
|
||||
*/
|
||||
private SingularData getSingularData(EclipseNode node, ASTNode source) {
|
||||
private SingularData getSingularData(EclipseNode node, ASTNode source, final String setterPrefix) {
|
||||
for (EclipseNode child : node.down()) {
|
||||
if (!annotationTypeMatches(Singular.class, child)) continue;
|
||||
char[] pluralName = node.getKind() == Kind.FIELD ? removePrefixFromField(node) : ((AbstractVariableDeclaration) node.get()).name;
|
||||
@@ -980,7 +991,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SingularData(child, singularName, pluralName, typeArgs == null ? Collections.<TypeReference>emptyList() : Arrays.asList(typeArgs), targetFqn, singularizer, source);
|
||||
return new SingularData(child, singularName, pluralName, typeArgs == null ? Collections.<TypeReference>emptyList() : Arrays.asList(typeArgs), targetFqn, singularizer, source, setterPrefix.toCharArray());
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -172,7 +172,8 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
|
||||
md.arguments[i].annotations = typeUseAnns;
|
||||
}
|
||||
md.returnType = returnType;
|
||||
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName(getAddMethodName(), new String(data.getSingularName())).toCharArray();
|
||||
char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
|
||||
md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
|
||||
md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
|
||||
|
||||
data.setGeneratedByRecursive(md);
|
||||
@@ -204,7 +205,8 @@ abstract class EclipseGuavaSingularizer extends EclipseSingularizer {
|
||||
Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
|
||||
md.arguments = new Argument[] {param};
|
||||
md.returnType = returnType;
|
||||
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName(getAddMethodName() + "All", new String(data.getPluralName())).toCharArray();
|
||||
char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
|
||||
md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
|
||||
md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
|
||||
|
||||
data.setGeneratedByRecursive(md);
|
||||
|
||||
@@ -150,7 +150,8 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
|
||||
param.annotations = typeUseAnns;
|
||||
md.arguments = new Argument[] {param};
|
||||
md.returnType = returnType;
|
||||
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
|
||||
char[] prefixedSingularName = data.getSetterPrefix().length == 0 ? data.getSingularName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getSingularName())).toCharArray();
|
||||
md.selector = fluent ? prefixedSingularName : HandlerUtil.buildAccessorName("add", new String(data.getSingularName())).toCharArray();
|
||||
md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
|
||||
|
||||
data.setGeneratedByRecursive(md);
|
||||
@@ -181,7 +182,8 @@ abstract class EclipseJavaUtilListSetSingularizer extends EclipseJavaUtilSingula
|
||||
Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
|
||||
md.arguments = new Argument[] {param};
|
||||
md.returnType = returnType;
|
||||
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
|
||||
char[] prefixedSelector = data.getSetterPrefix().length == 0 ? data.getPluralName() : HandlerUtil.buildAccessorName(new String(data.getSetterPrefix()), new String(data.getPluralName())).toCharArray();
|
||||
md.selector = fluent ? prefixedSelector : HandlerUtil.buildAccessorName("addAll", new String(data.getPluralName())).toCharArray();
|
||||
md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
|
||||
|
||||
data.setGeneratedByRecursive(md);
|
||||
|
||||
@@ -245,7 +245,12 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
|
||||
valueParam.annotations = typeUseAnnsValue;
|
||||
md.arguments = new Argument[] {keyParam, valueParam};
|
||||
md.returnType = returnType;
|
||||
md.selector = fluent ? data.getSingularName() : HandlerUtil.buildAccessorName("put", new String(data.getSingularName())).toCharArray();
|
||||
|
||||
String name = new String(data.getSingularName());
|
||||
String setterPrefix = data.getSetterPrefix().length > 0 ? new String(data.getSetterPrefix()) : fluent ? "" : "put";
|
||||
String setterName = HandlerUtil.buildAccessorName(setterPrefix, name);
|
||||
|
||||
md.selector = setterName.toCharArray();
|
||||
md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
|
||||
|
||||
data.setGeneratedByRecursive(md);
|
||||
@@ -309,7 +314,12 @@ public class EclipseJavaUtilMapSingularizer extends EclipseJavaUtilSingularizer
|
||||
Argument param = new Argument(data.getPluralName(), 0, paramType, ClassFileConstants.AccFinal);
|
||||
md.arguments = new Argument[] {param};
|
||||
md.returnType = returnType;
|
||||
md.selector = fluent ? data.getPluralName() : HandlerUtil.buildAccessorName("putAll", new String(data.getPluralName())).toCharArray();
|
||||
|
||||
String name = new String(data.getPluralName());
|
||||
String setterPrefix = data.getSetterPrefix().length > 0 ? new String(data.getSetterPrefix()) : fluent ? "" : "put";
|
||||
String setterName = HandlerUtil.buildAccessorName(setterPrefix, name);
|
||||
|
||||
md.selector = setterName.toCharArray();
|
||||
md.annotations = generateSelfReturnAnnotations(deprecate, cfv, data.getSource());
|
||||
|
||||
data.setGeneratedByRecursive(md);
|
||||
|
||||
@@ -180,7 +180,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
bfd.builderFieldName = bfd.name;
|
||||
bfd.annotations = findCopyableAnnotations(fieldNode);
|
||||
bfd.type = fd.vartype;
|
||||
bfd.singularData = getSingularData(fieldNode);
|
||||
bfd.singularData = getSingularData(fieldNode, builderInstance.setterPrefix());
|
||||
bfd.originalFieldNode = fieldNode;
|
||||
|
||||
if (bfd.singularData != null && isDefault != null) {
|
||||
@@ -369,7 +369,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
bfd.rawName = raw.name;
|
||||
bfd.annotations = findCopyableAnnotations(param);
|
||||
bfd.type = raw.vartype;
|
||||
bfd.singularData = getSingularData(param);
|
||||
bfd.singularData = getSingularData(param, builderInstance.setterPrefix());
|
||||
bfd.originalFieldNode = param;
|
||||
addObtainVia(bfd, param);
|
||||
builderFields.add(bfd);
|
||||
@@ -436,7 +436,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
makeSetterMethodsForBuilder(cfv, builderType, bfd, annotationNode, fluent, chain, accessForInners);
|
||||
makePrefixedSetterMethodsForBuilder(cfv, builderType, bfd, annotationNode, fluent, chain, accessForInners, builderInstance.setterPrefix());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -487,7 +487,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
}
|
||||
tps = lb.toList();
|
||||
}
|
||||
JCMethodDecl md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters);
|
||||
JCMethodDecl md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast, accessForOuters, builderInstance.setterPrefix());
|
||||
if (md != null) {
|
||||
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
|
||||
injectMethod(tdParent, md);
|
||||
@@ -536,7 +536,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
private static final String BUILDER_TEMP_VAR = "builder";
|
||||
private JCMethodDecl generateToBuilderMethod(CheckerFrameworkVersion cfv, String toBuilderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, boolean fluent, JCAnnotation ast, AccessLevel access) {
|
||||
private JCMethodDecl generateToBuilderMethod(CheckerFrameworkVersion cfv, String toBuilderMethodName, String builderClassName, JavacNode type, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, boolean fluent, JCAnnotation ast, AccessLevel access, String prefix) {
|
||||
// return new ThingieBuilder<A, B>().setA(this.a).setB(this.b);
|
||||
JavacTreeMaker maker = type.getTreeMaker();
|
||||
|
||||
@@ -549,7 +549,11 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
JCExpression invoke = call;
|
||||
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
Name setterName = fluent ? bfd.name : type.toName(HandlerUtil.buildAccessorName("set", bfd.name.toString()));
|
||||
String setterPrefix = !prefix.isEmpty() ? prefix : fluent ? "" : "set";
|
||||
String prefixedSetterName = bfd.name.toString();
|
||||
if (!setterPrefix.isEmpty()) prefixedSetterName = HandlerUtil.buildAccessorName(setterPrefix, prefixedSetterName);
|
||||
|
||||
Name setterName = type.toName(prefixedSetterName);
|
||||
JCExpression[] tgt = new JCExpression[bfd.singularData == null ? 1 : 2];
|
||||
if (bfd.obtainVia == null || !bfd.obtainVia.field().isEmpty()) {
|
||||
for (int i = 0; i < tgt.length; i++) {
|
||||
@@ -622,12 +626,12 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
|
||||
static List<JCVariableDecl> generateBuildArgs(CheckerFrameworkVersion cfv, JavacNode type, java.util.List<BuilderFieldData> builderFields) {
|
||||
if (!cfv.generateCalledMethods()) return List.<JCVariableDecl>nil();
|
||||
|
||||
|
||||
ArrayList<String> mandatories = new ArrayList<String>();
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
if (bfd.singularData == null && bfd.nameOfSetFlag == null) mandatories.add(bfd.name.toString());
|
||||
}
|
||||
|
||||
|
||||
JCExpression arg;
|
||||
JavacTreeMaker maker = type.getTreeMaker();
|
||||
if (mandatories.size() == 0) return List.<JCVariableDecl>nil();
|
||||
@@ -642,7 +646,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(recvAnno)), type.toName("this"), maker.Ident(builderTypeNode.name), null);
|
||||
return List.of(recv);
|
||||
}
|
||||
|
||||
|
||||
private JCMethodDecl generateBuildMethod(CheckerFrameworkVersion cfv, JavacNode tdParent, boolean isStatic, String buildName, Name builderName, JCExpression returnType, java.util.List<BuilderFieldData> builderFields, JavacNode type, List<JCExpression> thrownExceptions, JCTree source, boolean addCleaning, AccessLevel access) {
|
||||
JavacTreeMaker maker = type.getTreeMaker();
|
||||
|
||||
@@ -776,27 +780,28 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
for (JCVariableDecl gen : generated) recursiveSetGeneratedBy(gen, source, builderType.getContext());
|
||||
}
|
||||
|
||||
public void makeSetterMethodsForBuilder(CheckerFrameworkVersion cfv, JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, boolean fluent, boolean chain, AccessLevel access) {
|
||||
public void makePrefixedSetterMethodsForBuilder(CheckerFrameworkVersion cfv, JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, boolean fluent, boolean chain, AccessLevel access, String prefix) {
|
||||
boolean deprecate = isFieldDeprecated(fieldNode.originalFieldNode);
|
||||
if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
|
||||
makeSimpleSetterMethodForBuilder(cfv, builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode, access);
|
||||
makePrefixedSetterMethodForBuilder(cfv, builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode, access, prefix);
|
||||
} else {
|
||||
// TODO prefixed version
|
||||
fieldNode.singularData.getSingularizer().generateMethods(cfv, fieldNode.singularData, deprecate, builderType, source.get(), fluent, chain, access);
|
||||
}
|
||||
}
|
||||
|
||||
private void makeSimpleSetterMethodForBuilder(CheckerFrameworkVersion cfv, JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name paramName, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List<JCAnnotation> annosOnParam, JavacNode originalFieldNode, AccessLevel access) {
|
||||
Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
|
||||
private void makePrefixedSetterMethodForBuilder(CheckerFrameworkVersion cfv, JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name paramName, Name nameOfSetFlag, JavacNode source, boolean fluent, boolean chain, List<JCAnnotation> annosOnParam, JavacNode originalFieldNode, AccessLevel access, String prefix) {
|
||||
String setterPrefix = !prefix.isEmpty() ? prefix : fluent ? "" : "set";
|
||||
String setterName = HandlerUtil.buildAccessorName(setterPrefix, paramName.toString());
|
||||
Name setterName_ = builderType.toName(setterName);
|
||||
|
||||
for (JavacNode child : builderType.down()) {
|
||||
if (child.getKind() != Kind.METHOD) continue;
|
||||
JCMethodDecl methodDecl = (JCMethodDecl) child.get();
|
||||
Name existingName = methodDecl.name;
|
||||
if (existingName.equals(fieldName) && !isTolerate(fieldNode, methodDecl)) return;
|
||||
if (existingName.equals(setterName_) && !isTolerate(fieldNode, methodDecl)) return;
|
||||
}
|
||||
|
||||
String setterName = fluent ? paramName.toString() : HandlerUtil.buildAccessorName("set", paramName.toString());
|
||||
|
||||
JavacTreeMaker maker = fieldNode.getTreeMaker();
|
||||
|
||||
List<JCAnnotation> methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode);
|
||||
@@ -838,8 +843,9 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
* or parameter), or null if there's no {@code @Singular} annotation on it.
|
||||
*
|
||||
* @param node The node (field or method param) to inspect for its name and potential {@code @Singular} annotation.
|
||||
* @param setterPrefix Explicitly requested setter prefix.
|
||||
*/
|
||||
private SingularData getSingularData(JavacNode node) {
|
||||
private SingularData getSingularData(JavacNode node, String setterPrefix) {
|
||||
for (JavacNode child : node.down()) {
|
||||
if (!annotationTypeMatches(Singular.class, child)) continue;
|
||||
Name pluralName = node.getKind() == Kind.FIELD ? removePrefixFromField(node) : ((JCVariableDecl) node.get()).name;
|
||||
@@ -881,7 +887,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new SingularData(child, singularName, pluralName, typeArgs, targetFqn, singularizer);
|
||||
return new SingularData(child, singularName, pluralName, typeArgs, targetFqn, singularizer, setterPrefix);
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
@@ -119,14 +119,20 @@ public class JavacSingularsRecipes {
|
||||
private final List<JCExpression> typeArgs;
|
||||
private final String targetFqn;
|
||||
private final JavacSingularizer singularizer;
|
||||
private final String setterPrefix;
|
||||
|
||||
public SingularData(JavacNode annotation, Name singularName, Name pluralName, List<JCExpression> typeArgs, String targetFqn, JavacSingularizer singularizer) {
|
||||
this(annotation, singularName, pluralName, typeArgs, targetFqn, singularizer, "");
|
||||
}
|
||||
|
||||
public SingularData(JavacNode annotation, Name singularName, Name pluralName, List<JCExpression> typeArgs, String targetFqn, JavacSingularizer singularizer, String setterPrefix) {
|
||||
this.annotation = annotation;
|
||||
this.singularName = singularName;
|
||||
this.pluralName = pluralName;
|
||||
this.typeArgs = typeArgs;
|
||||
this.targetFqn = targetFqn;
|
||||
this.singularizer = singularizer;
|
||||
this.setterPrefix = setterPrefix;
|
||||
}
|
||||
|
||||
public JavacNode getAnnotation() {
|
||||
@@ -141,6 +147,10 @@ public class JavacSingularsRecipes {
|
||||
return pluralName;
|
||||
}
|
||||
|
||||
public String getSetterPrefix() {
|
||||
return setterPrefix;
|
||||
}
|
||||
|
||||
public List<JCExpression> getTypeArgs() {
|
||||
return typeArgs;
|
||||
}
|
||||
@@ -281,7 +291,9 @@ public class JavacSingularsRecipes {
|
||||
ListBuffer<JCStatement> statements = generateSingularMethodStatements(maker, data, builderType, source);
|
||||
List<JCVariableDecl> params = generateSingularMethodParameters(maker, data, builderType, source);
|
||||
Name name = data.getSingularName();
|
||||
if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName(getAddMethodName(), name.toString()));
|
||||
String setterPrefix = data.getSetterPrefix();
|
||||
if (setterPrefix.isEmpty() && !fluent) setterPrefix = getAddMethodName();
|
||||
if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(setterPrefix, name.toString()));
|
||||
|
||||
statements.prepend(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
|
||||
finishAndInjectMethod(cfv, maker, returnType, returnStatement, data, builderType, source, deprecate, statements, name, params, access);
|
||||
@@ -309,7 +321,9 @@ public class JavacSingularsRecipes {
|
||||
private void generatePluralMethod(CheckerFrameworkVersion cfv, boolean deprecate, JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent, AccessLevel access) {
|
||||
ListBuffer<JCStatement> statements = generatePluralMethodStatements(maker, data, builderType, source);
|
||||
Name name = data.getPluralName();
|
||||
if (!fluent) name = builderType.toName(HandlerUtil.buildAccessorName(getAddMethodName() + "All", name.toString()));
|
||||
String setterPrefix = data.getSetterPrefix();
|
||||
if (setterPrefix.isEmpty() && !fluent) setterPrefix = getAddMethodName() + "All";
|
||||
if (!setterPrefix.isEmpty()) name = builderType.toName(HandlerUtil.buildAccessorName(setterPrefix, name.toString()));
|
||||
JCExpression paramType = getPluralMethodParamType(builderType);
|
||||
paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs(), source);
|
||||
long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
|
||||
|
||||
Reference in new issue
Block a user