aboutsummaryrefslogtreecommitdiff
path: root/src/core/lombok/javac
diff options
context:
space:
mode:
authorReinier Zwitserloot <r.zwitserloot@projectlombok.org>2020-10-03 23:55:10 +0200
committerReinier Zwitserloot <r.zwitserloot@projectlombok.org>2020-10-03 23:55:10 +0200
commit14cce76805324dce66fcdfde333a63c677694d64 (patch)
tree18001068c7052e08ee85a2df565f4be9902ca448 /src/core/lombok/javac
parent07e921d2b19a660df28e03ee1ed1d0315d5e3458 (diff)
downloadlombok-14cce76805324dce66fcdfde333a63c677694d64.tar.gz
lombok-14cce76805324dce66fcdfde333a63c677694d64.tar.bz2
lombok-14cce76805324dce66fcdfde333a63c677694d64.zip
[builder] big refactor: Fixing CheckerFramework features + all params now in an object
These handlers had methods with humongous argument lists, and they needed to grow even more in order to accommodate some new needs to properly implement checkerframework (where annos can be type-use based, which means they were being put in the wrong place. void foo(com.foo.@X Bar paramName) // correct void foo(@X com.foo.Bar paramName) // wrong For example, the CalledMethod annotation is a type-use annotation. This commit covers both that refactor and fixing checkerframework generation.
Diffstat (limited to 'src/core/lombok/javac')
-rw-r--r--src/core/lombok/javac/handlers/HandleBuilder.java554
-rw-r--r--src/core/lombok/javac/handlers/HandleConstructor.java6
-rw-r--r--src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleGetter.java2
-rw-r--r--src/core/lombok/javac/handlers/HandleSetter.java33
-rw-r--r--src/core/lombok/javac/handlers/HandleSuperBuilder.java610
-rw-r--r--src/core/lombok/javac/handlers/JavacSingularsRecipes.java17
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java2
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java2
-rw-r--r--src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java6
10 files changed, 692 insertions, 542 deletions
diff --git a/src/core/lombok/javac/handlers/HandleBuilder.java b/src/core/lombok/javac/handlers/HandleBuilder.java
index 7e87ce11..1c74ce37 100644
--- a/src/core/lombok/javac/handlers/HandleBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleBuilder.java
@@ -55,6 +55,7 @@ import com.sun.tools.javac.tree.JCTree.JCStatement;
import com.sun.tools.javac.tree.JCTree.JCTypeApply;
import com.sun.tools.javac.tree.JCTree.JCTypeParameter;
import com.sun.tools.javac.tree.JCTree.JCVariableDecl;
+import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.List;
import com.sun.tools.javac.util.ListBuffer;
import com.sun.tools.javac.util.Name;
@@ -88,12 +89,96 @@ import lombok.javac.handlers.JavacSingularsRecipes.SingularData;
public class HandleBuilder extends JavacAnnotationHandler<Builder> {
private HandleConstructor handleConstructor = new HandleConstructor();
+ static final String CLEAN_FIELD_NAME = "$lombokUnclean";
+ static final String CLEAN_METHOD_NAME = "$lombokClean";
+ static final String TO_BUILDER_METHOD_NAME = "toBuilder";
+ static final String DEFAULT_PREFIX = "$default$";
+ static final String SET_PREFIX = "$set";
+ static final String VALUE_PREFIX = "$value";
+ static final String BUILDER_TEMP_VAR = "builder";
+ static final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
+
private static final boolean toBoolean(Object expr, boolean defaultValue) {
if (expr == null) return defaultValue;
if (expr instanceof JCLiteral) return ((Integer) ((JCLiteral) expr).value) != 0;
return ((Boolean) expr).booleanValue();
}
+ static class BuilderJob {
+ CheckerFrameworkVersion checkerFramework;
+ JavacNode parentType;
+ String builderMethodName, buildMethodName;
+ boolean isStatic;
+ List<JCTypeParameter> typeParams;
+ List<JCTypeParameter> builderTypeParams;
+ JCTree source;
+ JavacNode sourceNode;
+ java.util.List<BuilderFieldData> builderFields;
+ AccessLevel accessInners, accessOuters;
+ boolean oldFluent, oldChain, toBuilder;
+
+ JavacNode builderType;
+ String builderClassName;
+
+ void init(AnnotationValues<Builder> annValues, Builder ann, JavacNode node) {
+ accessOuters = ann.access();
+ if (accessOuters == null) accessOuters = AccessLevel.PUBLIC;
+ if (accessOuters == AccessLevel.NONE) {
+ sourceNode.addError("AccessLevel.NONE is not valid here");
+ accessOuters = AccessLevel.PUBLIC;
+ }
+ accessInners = accessOuters == AccessLevel.PROTECTED ? AccessLevel.PUBLIC : accessOuters;
+
+ oldFluent = toBoolean(annValues.getActualExpression("fluent"), true);
+ oldChain = toBoolean(annValues.getActualExpression("chain"), true);
+
+ builderMethodName = ann.builderMethodName();
+ buildMethodName = ann.buildMethodName();
+ builderClassName = fixBuilderClassName(node, ann.builderClassName());
+ toBuilder = ann.toBuilder();
+
+ if (builderMethodName == null) builderMethodName = "builder";
+ if (buildMethodName == null) buildMethodName = "build";
+ if (builderClassName == null) builderClassName = "";
+ }
+
+ static String fixBuilderClassName(JavacNode node, String override) {
+ if (override != null && !override.isEmpty()) return override;
+ override = node.getAst().readConfiguration(ConfigurationKeys.BUILDER_CLASS_NAME);
+ if (override != null && !override.isEmpty()) return override;
+ return "*Builder";
+ }
+
+ String replaceBuilderClassName(Name name) {
+ if (builderClassName.indexOf('*') == -1) return builderClassName;
+ return builderClassName.replace("*", name.toString());
+ }
+
+ JCExpression createBuilderParentTypeReference() {
+ return namePlusTypeParamsToTypeReference(parentType.getTreeMaker(), parentType, typeParams);
+ }
+
+ Name getBuilderClassName() {
+ return parentType.toName(builderClassName);
+ }
+
+ List<JCTypeParameter> copyTypeParams() {
+ return JavacHandlerUtil.copyTypeParams(sourceNode, typeParams);
+ }
+
+ Name toName(String name) {
+ return parentType.toName(name);
+ }
+
+ Context getContext() {
+ return parentType.getContext();
+ }
+
+ JavacTreeMaker getTreeMaker() {
+ return parentType.getTreeMaker();
+ }
+ }
+
static class BuilderFieldData {
List<JCAnnotation> annotations;
JCExpression type;
@@ -112,73 +197,49 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
@Override public void handle(AnnotationValues<Builder> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleFlagUsage(annotationNode, ConfigurationKeys.BUILDER_FLAG_USAGE, "@Builder");
- CheckerFrameworkVersion cfv = getCheckerFrameworkVersion(annotationNode);
-
- Builder builderInstance = annotation.getInstance();
- AccessLevel accessForOuters = builderInstance.access();
- if (accessForOuters == null) accessForOuters = AccessLevel.PUBLIC;
- if (accessForOuters == AccessLevel.NONE) {
- annotationNode.addError("AccessLevel.NONE is not valid here");
- accessForOuters = AccessLevel.PUBLIC;
- }
- AccessLevel accessForInners = accessForOuters == AccessLevel.PROTECTED ? AccessLevel.PUBLIC : accessForOuters;
-
- // These exist just to support the 'old' lombok.experimental.Builder, which had these properties. lombok.Builder no longer has them.
- boolean fluent = toBoolean(annotation.getActualExpression("fluent"), true);
- boolean chain = toBoolean(annotation.getActualExpression("chain"), true);
-
- String builderMethodName = builderInstance.builderMethodName();
- String buildMethodName = builderInstance.buildMethodName();
- String builderClassName = builderInstance.builderClassName();
- String toBuilderMethodName = "toBuilder";
- boolean toBuilder = builderInstance.toBuilder();
+ BuilderJob job = new BuilderJob();
+ job.sourceNode = annotationNode;
+ job.source = ast;
+ job.checkerFramework = getCheckerFrameworkVersion(annotationNode);
+ job.isStatic = true;
+
+ Builder annInstance = annotation.getInstance();
+ job.init(annotation, annInstance, annotationNode);
java.util.List<Name> typeArgsForToBuilder = null;
- if (builderMethodName == null) builderMethodName = "builder";
- if (buildMethodName == null) buildMethodName = "build";
- if (builderClassName == null) builderClassName = "";
-
boolean generateBuilderMethod;
- if (builderMethodName.isEmpty()) {
+ if (job.builderMethodName.isEmpty()) {
generateBuilderMethod = false;
- } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) {
+ } else if (!checkName("builderMethodName", job.builderMethodName, annotationNode)) {
return;
} else {
generateBuilderMethod = true;
}
- if (!checkName("buildMethodName", buildMethodName, annotationNode)) return;
- if (!builderClassName.isEmpty()) {
- if (!checkName("builderClassName", builderClassName, annotationNode)) return;
- }
+ if (!checkName("buildMethodName", job.buildMethodName, annotationNode)) return;
- // Do not delete the Builder annotation here, we need it for @Jacksonized.
+ // Do not delete the Builder annotation yet, we need it for @Jacksonized.
JavacNode parent = annotationNode.up();
- java.util.List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
- JCExpression returnType;
- List<JCTypeParameter> typeParams = List.nil();
- List<JCExpression> thrownExceptions = List.nil();
+ job.builderFields = new ArrayList<BuilderFieldData>();
+ JCExpression buildMethodReturnType;
+ job.typeParams = List.nil();
+ List<JCExpression> buildMethodThrownExceptions;
Name nameOfBuilderMethod;
- JavacNode tdParent;
JavacNode fillParametersFrom = parent.get() instanceof JCMethodDecl ? parent : null;
boolean addCleaning = false;
- boolean isStatic = true;
ArrayList<JavacNode> nonFinalNonDefaultedFields = null;
- if (builderClassName.isEmpty()) builderClassName = annotationNode.getAst().readConfiguration(ConfigurationKeys.BUILDER_CLASS_NAME);
- if (builderClassName == null || builderClassName.isEmpty()) builderClassName = "*Builder";
- boolean replaceNameInBuilderClassName = builderClassName.contains("*");
-
if (parent.get() instanceof JCClassDecl) {
- tdParent = parent;
- JCClassDecl td = (JCClassDecl) tdParent.get();
+ job.parentType = parent;
+ JCClassDecl td = (JCClassDecl) parent.get();
+
ListBuffer<JavacNode> allFields = new ListBuffer<JavacNode>();
boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation("lombok.experimental.Value", parent));
- for (JavacNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) {
+ for (JavacNode fieldNode : HandleConstructor.findAllFields(parent, true)) {
JCVariableDecl fd = (JCVariableDecl) fieldNode.get();
JavacNode isDefault = findAnnotation(Builder.Default.class, fieldNode, false);
boolean isFinal = (fd.mods.flags & Flags.FINAL) != 0 || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode));
@@ -189,7 +250,7 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
bfd.builderFieldName = bfd.name;
bfd.annotations = findCopyableAnnotations(fieldNode);
bfd.type = fd.vartype;
- bfd.singularData = getSingularData(fieldNode, builderInstance.setterPrefix());
+ bfd.singularData = getSingularData(fieldNode, annInstance.setterPrefix());
bfd.originalFieldNode = fieldNode;
if (bfd.singularData != null && isDefault != null) {
@@ -211,26 +272,26 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
if (isDefault != null) {
- bfd.nameOfDefaultProvider = parent.toName("$default$" + bfd.name);
- bfd.nameOfSetFlag = parent.toName(bfd.name + "$set");
- bfd.builderFieldName = parent.toName(bfd.name + "$value");
+ bfd.nameOfDefaultProvider = parent.toName(DEFAULT_PREFIX + bfd.name);
+ bfd.nameOfSetFlag = parent.toName(bfd.name + SET_PREFIX);
+ bfd.builderFieldName = parent.toName(bfd.name + VALUE_PREFIX);
JCMethodDecl md = generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
- if (md != null) injectMethod(tdParent, md);
+ if (md != null) injectMethod(parent, md);
}
addObtainVia(bfd, fieldNode);
- builderFields.add(bfd);
+ job.builderFields.add(bfd);
allFields.append(fieldNode);
}
- handleConstructor.generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode);
+ handleConstructor.generateConstructor(parent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode);
- returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), tdParent, td.typarams);
- typeParams = td.typarams;
- thrownExceptions = List.nil();
+ buildMethodReturnType = namePlusTypeParamsToTypeReference(parent.getTreeMaker(), parent, td.typarams);
+ job.typeParams = job.builderTypeParams = td.typarams;
+ buildMethodThrownExceptions = List.nil();
nameOfBuilderMethod = null;
- if (replaceNameInBuilderClassName) builderClassName = builderClassName.replace("*", td.name.toString());
- replaceNameInBuilderClassName = false;
+ job.builderClassName = job.replaceBuilderClassName(td.name);
+ if (!checkName("builderClassName", job.builderClassName, annotationNode)) return;
} else if (fillParametersFrom != null && fillParametersFrom.getName().toString().equals("<init>")) {
JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
if (!jmd.typarams.isEmpty()) {
@@ -238,38 +299,35 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return;
}
- tdParent = parent.up();
- JCClassDecl td = (JCClassDecl) tdParent.get();
- returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), tdParent, td.typarams);
- typeParams = td.typarams;
- thrownExceptions = jmd.thrown;
+ job.parentType = parent.up();
+ JCClassDecl td = (JCClassDecl) job.parentType.get();
+ job.typeParams = job.builderTypeParams = td.typarams;
+ buildMethodReturnType = job.createBuilderParentTypeReference();
+ buildMethodThrownExceptions = jmd.thrown;
nameOfBuilderMethod = null;
- if (replaceNameInBuilderClassName) builderClassName = builderClassName.replace("*", td.name.toString());
- replaceNameInBuilderClassName = false;
+ job.builderClassName = job.replaceBuilderClassName(td.name);
+ if (!checkName("builderClassName", job.builderClassName, annotationNode)) return;
} else if (fillParametersFrom != null) {
- tdParent = parent.up();
- JCClassDecl td = (JCClassDecl) tdParent.get();
+ job.parentType = parent.up();
+ JCClassDecl td = (JCClassDecl) job.parentType.get();
JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
- isStatic = (jmd.mods.flags & Flags.STATIC) != 0;
+ job.isStatic = (jmd.mods.flags & Flags.STATIC) != 0;
+
JCExpression fullReturnType = jmd.restype;
- returnType = fullReturnType;
- typeParams = jmd.typarams;
- thrownExceptions = jmd.thrown;
+ buildMethodReturnType = fullReturnType;
+ job.typeParams = job.builderTypeParams = jmd.typarams;
+ buildMethodThrownExceptions = jmd.thrown;
nameOfBuilderMethod = jmd.name;
- if (returnType instanceof JCTypeApply) {
- returnType = cloneType(tdParent.getTreeMaker(), returnType, ast, annotationNode.getContext());
+ if (buildMethodReturnType instanceof JCTypeApply) {
+ buildMethodReturnType = cloneType(job.getTreeMaker(), buildMethodReturnType, ast, annotationNode.getContext());
}
- if (replaceNameInBuilderClassName) {
- String replStr = returnTypeToBuilderClassName(annotationNode, td, returnType, typeParams);
- if (replStr == null)
- return;
- builderClassName = builderClassName.replace("*", replStr);
- replaceNameInBuilderClassName = false;
+ if (job.builderClassName.indexOf('*') > -1) {
+ String replStr = returnTypeToBuilderClassName(annotationNode, td, buildMethodReturnType, job.typeParams);
+ if (replStr == null) return; // shuold not happen
+ job.builderClassName = job.builderClassName.replace("*", replStr);
}
- if (replaceNameInBuilderClassName) builderClassName = builderClassName.replace("*", td.name.toString());
- if (toBuilder) {
- final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
- if (returnType instanceof JCArrayTypeTree) {
+ if (job.toBuilder) {
+ if (fullReturnType instanceof JCArrayTypeTree) {
annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
return;
}
@@ -282,8 +340,8 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
tpOnRet = ((JCTypeApply) fullReturnType).arguments;
}
- JCExpression namingType = returnType;
- if (returnType instanceof JCTypeApply) namingType = ((JCTypeApply) returnType).clazz;
+ JCExpression namingType = fullReturnType;
+ if (buildMethodReturnType instanceof JCTypeApply) namingType = ((JCTypeApply) buildMethodReturnType).clazz;
if (namingType instanceof JCIdent) {
simpleName = ((JCIdent) namingType).name;
@@ -307,13 +365,13 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return;
}
- if (!tdParent.getName().contentEquals(simpleName)) {
+ if (!job.parentType.getName().contentEquals(simpleName)) {
annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
return;
}
List<JCTypeParameter> tpOnMethod = jmd.typarams;
- List<JCTypeParameter> tpOnType = ((JCClassDecl) tdParent.get()).typarams;
+ List<JCTypeParameter> tpOnType = ((JCClassDecl) job.builderType.get()).typarams;
typeArgsForToBuilder = new ArrayList<Name>();
for (JCTypeParameter tp : tpOnMethod) {
@@ -349,41 +407,41 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
bfd.rawName = raw.name;
bfd.annotations = findCopyableAnnotations(param);
bfd.type = raw.vartype;
- bfd.singularData = getSingularData(param, builderInstance.setterPrefix());
+ bfd.singularData = getSingularData(param, annInstance.setterPrefix());
bfd.originalFieldNode = param;
addObtainVia(bfd, param);
- builderFields.add(bfd);
+ job.builderFields.add(bfd);
}
}
- JavacNode builderType = findInnerClass(tdParent, builderClassName);
- if (builderType == null) {
- builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast, accessForOuters);
- recursiveSetGeneratedBy(builderType.get(), ast, annotationNode.getContext());
+ job.builderType = findInnerClass(job.parentType, job.builderClassName);
+ if (job.builderType == null) {
+ job.builderType = makeBuilderClass(job);
+ recursiveSetGeneratedBy(job.builderType.get(), ast, annotationNode.getContext());
} else {
- JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get();
- if (isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
+ JCClassDecl builderTypeDeclaration = (JCClassDecl) job.builderType.get();
+ if (job.isStatic && !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
annotationNode.addError("Existing Builder must be a static inner class.");
return;
- } else if (!isStatic && builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
+ } else if (!job.isStatic && builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)) {
annotationNode.addError("Existing Builder must be a non-static inner class.");
return;
}
- sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
+ sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(job.builderType, annotationNode);
/* generate errors for @Singular BFDs that have one already defined node. */ {
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.builderFields) {
SingularData sd = bfd.singularData;
if (sd == null) continue;
JavacSingularizer singularizer = sd.getSingularizer();
if (singularizer == null) continue;
- if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
+ if (singularizer.checkForAlreadyExistingNodesAndGenerateError(job.builderType, sd)) {
bfd.singularData = null;
}
}
}
}
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
if (bfd.singularData.getSingularizer().requiresCleaning()) {
addCleaning = true;
@@ -402,75 +460,75 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
}
- generateBuilderFields(builderType, builderFields, ast);
+ generateBuilderFields(job);
if (addCleaning) {
- JavacTreeMaker maker = builderType.getTreeMaker();
- JCVariableDecl uncleanField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), builderType.toName("$lombokUnclean"), maker.TypeIdent(CTC_BOOLEAN), null);
- injectFieldAndMarkGenerated(builderType, uncleanField);
+ JavacTreeMaker maker = job.getTreeMaker();
+ JCVariableDecl uncleanField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), job.builderType.toName(CLEAN_FIELD_NAME), maker.TypeIdent(CTC_BOOLEAN), null);
+ injectFieldAndMarkGenerated(job.builderType, uncleanField);
recursiveSetGeneratedBy(uncleanField, ast, annotationNode.getContext());
}
- if (constructorExists(builderType) == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.<JCAnnotation>nil(), builderType, List.<JavacNode>nil(), false, annotationNode);
- if (cd != null) injectMethod(builderType, cd);
+ if (constructorExists(job.builderType) == MemberExistsResult.NOT_EXISTS) {
+ JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PACKAGE, List.<JCAnnotation>nil(), job.builderType, List.<JavacNode>nil(), false, annotationNode);
+ if (cd != null) injectMethod(job.builderType, cd);
}
- for (BuilderFieldData bfd : builderFields) {
- makePrefixedSetterMethodsForBuilder(cfv, builderType, bfd, annotationNode, fluent, chain, accessForInners, builderInstance.setterPrefix());
+ for (BuilderFieldData bfd : job.builderFields) {
+ makePrefixedSetterMethodsForBuilder(job, bfd, annInstance.setterPrefix());
}
{
- MemberExistsResult methodExists = methodExists(buildMethodName, builderType, -1);
- if (methodExists == MemberExistsResult.EXISTS_BY_LOMBOK) methodExists = methodExists(buildMethodName, builderType, 0);
+ MemberExistsResult methodExists = methodExists(job.buildMethodName, job.builderType, -1);
+ if (methodExists == MemberExistsResult.EXISTS_BY_LOMBOK) methodExists = methodExists(job.buildMethodName, job.builderType, 0);
if (methodExists == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl md = generateBuildMethod(cfv, tdParent, isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning, accessForInners);
+ JCMethodDecl md = generateBuildMethod(job, nameOfBuilderMethod, buildMethodReturnType, buildMethodThrownExceptions, addCleaning);
if (md != null) {
- injectMethod(builderType, md);
+ injectMethod(job.builderType, md);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
}
}
}
- if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
+ if (methodExists("toString", job.builderType, 0) == MemberExistsResult.NOT_EXISTS) {
java.util.List<Included<JavacNode, ToString.Include>> fieldNodes = new ArrayList<Included<JavacNode, ToString.Include>>();
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.builderFields) {
for (JavacNode f : bfd.createdFields) {
fieldNodes.add(new Included<JavacNode, ToString.Include>(f, null, true, false));
}
}
- JCMethodDecl md = HandleToString.createToString(builderType, fieldNodes, true, false, FieldAccess.ALWAYS_FIELD, ast);
- if (md != null) injectMethod(builderType, md);
+ JCMethodDecl md = HandleToString.createToString(job.builderType, fieldNodes, true, false, FieldAccess.ALWAYS_FIELD, ast);
+ if (md != null) injectMethod(job.builderType, md);
}
- if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
+ if (addCleaning) injectMethod(job.builderType, generateCleanMethod(job));
- if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
+ if (generateBuilderMethod && methodExists(job.builderMethodName, job.parentType, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
if (generateBuilderMethod) {
- JCMethodDecl md = generateBuilderMethod(cfv, isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams, accessForOuters);
+ JCMethodDecl md = generateBuilderMethod(job);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
- if (md != null) injectMethod(tdParent, md);
+ if (md != null) injectMethod(job.parentType, md);
}
- if (toBuilder) {
- switch (methodExists(toBuilderMethodName, tdParent, 0)) {
+ if (job.toBuilder) {
+ switch (methodExists(TO_BUILDER_METHOD_NAME, job.parentType, 0)) {
case EXISTS_BY_USER:
annotationNode.addWarning("Not generating toBuilder() as it already exists.");
return;
case NOT_EXISTS:
- List<JCTypeParameter> tps = typeParams;
+ List<JCTypeParameter> tps = job.typeParams;
if (typeArgsForToBuilder != null) {
ListBuffer<JCTypeParameter> lb = new ListBuffer<JCTypeParameter>();
- JavacTreeMaker maker = tdParent.getTreeMaker();
+ JavacTreeMaker maker = job.getTreeMaker();
for (Name n : typeArgsForToBuilder) {
lb.append(maker.TypeParameter(n, List.<JCExpression>nil()));
}
tps = lb.toList();
}
- JCMethodDecl md = generateToBuilderMethod(cfv, toBuilderMethodName, builderClassName, tdParent, isStatic, tps, builderFields, fluent, ast, accessForOuters, builderInstance.setterPrefix());
+ JCMethodDecl md = generateToBuilderMethod(job, tps, annInstance.setterPrefix());
if (md != null) {
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
- injectMethod(tdParent, md);
+ injectMethod(job.parentType, md);
}
}
}
@@ -551,47 +609,45 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
sb.append("__ERR__");
}
- private static final String BUILDER_TEMP_VAR = "builder";
- private JCMethodDecl generateToBuilderMethod(CheckerFrameworkVersion cfv, String toBuilderMethodName, String builderClassName, JavacNode type, boolean isStatic, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, boolean fluent, JCAnnotation ast, AccessLevel access, String prefix) {
+ private JCMethodDecl generateToBuilderMethod(BuilderJob job, List<JCTypeParameter> typeParameters, String prefix) {
// return new ThingieBuilder<A, B>().setA(this.a).setB(this.b);
- JavacTreeMaker maker = type.getTreeMaker();
-
+ JavacTreeMaker maker = job.getTreeMaker();
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
- for (JCTypeParameter typeParam : typeParams) {
+ for (JCTypeParameter typeParam : typeParameters) {
typeArgs.append(maker.Ident(typeParam.name));
}
- JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), !isStatic, typeParams), List.<JCExpression>nil(), null);
+ JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderClassName), !job.isStatic, job.builderTypeParams), List.<JCExpression>nil(), null);
JCExpression invoke = call;
ListBuffer<JCStatement> preStatements = null;
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
- for (BuilderFieldData bfd : builderFields) {
- String setterPrefix = !prefix.isEmpty() ? prefix : fluent ? "" : "set";
+ for (BuilderFieldData bfd : job.builderFields) {
+ String setterPrefix = !prefix.isEmpty() ? prefix : job.oldFluent ? "" : "set";
String prefixedSetterName = bfd.name.toString();
if (!setterPrefix.isEmpty()) prefixedSetterName = HandlerUtil.buildAccessorName(setterPrefix, prefixedSetterName);
- Name setterName = type.toName(prefixedSetterName);
+ Name setterName = job.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++) {
- tgt[i] = maker.Select(maker.Ident(type.toName("this")), bfd.obtainVia == null ? bfd.rawName : type.toName(bfd.obtainVia.field()));
+ tgt[i] = maker.Select(maker.Ident(job.toName("this")), bfd.obtainVia == null ? bfd.rawName : job.toName(bfd.obtainVia.field()));
}
} else {
String name = bfd.obtainVia.method();
JCMethodInvocation inv;
if (bfd.obtainVia.isStatic()) {
- JCExpression c = maker.Select(maker.Ident(type.toName(type.getName())), type.toName(name));
- inv = maker.Apply(typeParameterNames(maker, typeParams), c, List.<JCExpression>of(maker.Ident(type.toName("this"))));
+ JCExpression c = maker.Select(maker.Ident(job.toName(job.parentType.getName())), job.toName(name));
+ inv = maker.Apply(typeParameterNames(maker, typeParameters), c, List.<JCExpression>of(maker.Ident(job.toName("this"))));
} else {
- JCExpression c = maker.Select(maker.Ident(type.toName("this")), type.toName(name));
+ JCExpression c = maker.Select(maker.Ident(job.toName("this")), job.toName(name));
inv = maker.Apply(List.<JCExpression>nil(), c, List.<JCExpression>nil());
}
for (int i = 0; i < tgt.length; i++) tgt[i] = maker.Ident(bfd.name);
// javac appears to cache the type of JCMethodInvocation expressions based on position, meaning, if you have 2 ObtainVia-based method invokes on different types, you get bizarre type mismatch errors.
// going via a local variable declaration solves the problem.
- JCExpression varType = JavacHandlerUtil.cloneType(maker, bfd.type, ast, type.getContext());
+ JCExpression varType = JavacHandlerUtil.cloneType(maker, bfd.type, job.source, job.getContext());
if (preStatements == null) preStatements = new ListBuffer<JCStatement>();
preStatements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), bfd.name, varType, inv));
}
@@ -602,15 +658,15 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
invoke = maker.Apply(List.<JCExpression>nil(), maker.Select(invoke, setterName), List.of(arg));
} else {
JCExpression isNotNull = maker.Binary(CTC_NOT_EQUAL, tgt[0], maker.Literal(CTC_BOT, null));
- JCExpression invokeBuilder = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(type.toName(BUILDER_TEMP_VAR)), setterName), List.<JCExpression>of(tgt[1]));
+ JCExpression invokeBuilder = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(job.toName(BUILDER_TEMP_VAR)), setterName), List.<JCExpression>of(tgt[1]));
statements.append(maker.If(isNotNull, maker.Exec(invokeBuilder), null));
}
}
if (!statements.isEmpty()) {
- JCExpression tempVarType = namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), !isStatic, typeParams);
- statements.prepend(maker.VarDef(maker.Modifiers(Flags.FINAL), type.toName(BUILDER_TEMP_VAR), tempVarType, invoke));
- statements.append(maker.Return(maker.Ident(type.toName(BUILDER_TEMP_VAR))));
+ JCExpression tempVarType = namePlusTypeParamsToTypeReference(maker, job.parentType, job.getBuilderClassName(), !job.isStatic, typeParameters);
+ statements.prepend(maker.VarDef(maker.Modifiers(Flags.FINAL), job.toName(BUILDER_TEMP_VAR), tempVarType, invoke));
+ statements.append(maker.Return(maker.Ident(job.toName(BUILDER_TEMP_VAR))));
} else {
statements.append(maker.Return(invoke));
}
@@ -620,77 +676,78 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
statements = preStatements;
}
JCBlock body = maker.Block(0, statements.toList());
- List<JCAnnotation> annsOnMethod = cfv.generateUnique() ? List.of(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
- JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(toJavacModifier(access), annsOnMethod), type.toName(toBuilderMethodName), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), !isStatic, typeParams), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
- createRelevantNonNullAnnotation(type, methodDef);
+ List<JCAnnotation> annsOnParamType = List.nil();
+ if (job.checkerFramework.generateUnique()) annsOnParamType = List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil()));
+ JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(toJavacModifier(job.accessOuters)), job.toName(TO_BUILDER_METHOD_NAME), namePlusTypeParamsToTypeReference(maker, job.parentType, job.getBuilderClassName(), !job.isStatic, typeParameters, annsOnParamType), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ createRelevantNonNullAnnotation(job.parentType, methodDef);
return methodDef;
}
- private JCMethodDecl generateCleanMethod(java.util.List<BuilderFieldData> builderFields, JavacNode type, JCTree source) {
- JavacTreeMaker maker = type.getTreeMaker();
+ private JCMethodDecl generateCleanMethod(BuilderJob job) {
+ JavacTreeMaker maker = job.getTreeMaker();
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
- bfd.singularData.getSingularizer().appendCleaningCode(bfd.singularData, type, source, statements);
+ bfd.singularData.getSingularizer().appendCleaningCode(bfd.singularData, job.builderType, job.source, statements);
}
}
- statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")), maker.Literal(CTC_BOOLEAN, 0))));
+ statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(job.toName("this")), job.toName(CLEAN_FIELD_NAME)), maker.Literal(CTC_BOOLEAN, 0))));
JCBlock body = maker.Block(0, statements.toList());
- JCMethodDecl method = maker.MethodDef(maker.Modifiers(toJavacModifier(AccessLevel.PRIVATE)), type.toName("$lombokClean"), maker.Type(Javac.createVoidType(type.getSymbolTable(), CTC_VOID)), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
- recursiveSetGeneratedBy(method, source, type.getContext());
+ JCMethodDecl method = maker.MethodDef(maker.Modifiers(toJavacModifier(AccessLevel.PRIVATE)), job.toName(CLEAN_METHOD_NAME), maker.Type(Javac.createVoidType(job.builderType.getSymbolTable(), CTC_VOID)), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ recursiveSetGeneratedBy(method, job.source, job.getContext());
return method;
}
- static List<JCVariableDecl> generateBuildArgs(CheckerFrameworkVersion cfv, JavacNode type, java.util.List<BuilderFieldData> builderFields) {
- if (!cfv.generateCalledMethods()) return List.<JCVariableDecl>nil();
-
+ static JCVariableDecl generateReceiver(BuilderJob job) {
+ if (!job.checkerFramework.generateCalledMethods()) return null;
+
ArrayList<String> mandatories = new ArrayList<String>();
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.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();
+ JavacTreeMaker maker = job.getTreeMaker();
+ if (mandatories.size() == 0) return null;
if (mandatories.size() == 1) arg = maker.Literal(mandatories.get(0));
else {
List<JCExpression> elems = List.nil();
for (int i = mandatories.size() - 1; i >= 0; i--) elems = elems.prepend(maker.Literal(mandatories.get(i)));
arg = maker.NewArray(null, List.<JCExpression>nil(), elems);
}
- JCAnnotation recvAnno = maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__CALLED), List.of(arg));
- JCClassDecl builderTypeNode = (JCClassDecl) type.get();
- JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(recvAnno)), type.toName("this"), namePlusTypeParamsToTypeReference(maker, type, builderTypeNode.typarams), null);
- return List.of(recv);
+ JCAnnotation recvAnno = maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__CALLED), List.of(arg));
+ JCClassDecl builderTypeNode = (JCClassDecl) job.builderType.get();
+ JCVariableDecl recv = maker.VarDef(maker.Modifiers(Flags.PARAMETER, List.<JCAnnotation>nil()), job.toName("this"), namePlusTypeParamsToTypeReference(maker, job.builderType, builderTypeNode.typarams, List.<JCAnnotation>of(recvAnno)), null);
+ return 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();
+ private JCMethodDecl generateBuildMethod(BuilderJob job, Name staticName, JCExpression returnType, List<JCExpression> thrownExceptions, boolean addCleaning) {
+ JavacTreeMaker maker = job.getTreeMaker();
JCExpression call;
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
if (addCleaning) {
- JCExpression notClean = maker.Unary(CTC_NOT, maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")));
- JCStatement invokeClean = maker.Exec(maker.Apply(List.<JCExpression>nil(), maker.Ident(type.toName("$lombokClean")), List.<JCExpression>nil()));
+ JCExpression notClean = maker.Unary(CTC_NOT, maker.Select(maker.Ident(job.toName("this")), job.toName(CLEAN_FIELD_NAME)));
+ JCStatement invokeClean = maker.Exec(maker.Apply(List.<JCExpression>nil(), maker.Ident(job.toName(CLEAN_METHOD_NAME)), List.<JCExpression>nil()));
JCIf ifUnclean = maker.If(notClean, invokeClean, null);
statements.append(ifUnclean);
}
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
- bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, type, source, statements, bfd.builderFieldName, "this");
+ bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, job.builderType, job.source, statements, bfd.builderFieldName, "this");
}
}
ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
- Name thisName = type.toName("this");
- for (BuilderFieldData bfd : builderFields) {
+ Name thisName = job.toName("this");
+ for (BuilderFieldData bfd : job.builderFields) {
if (bfd.nameOfSetFlag != null) {
- statements.append(maker.VarDef(maker.Modifiers(0L), bfd.builderFieldName, cloneType(maker, bfd.type, source, tdParent.getContext()), maker.Select(maker.Ident(thisName), bfd.builderFieldName)));
- statements.append(maker.If(maker.Unary(CTC_NOT, maker.Select(maker.Ident(thisName), bfd.nameOfSetFlag)), maker.Exec(maker.Assign(maker.Ident(bfd.builderFieldName), maker.Apply(typeParameterNames(maker, ((JCClassDecl) tdParent.get()).typarams), maker.Select(maker.Ident(((JCClassDecl) tdParent.get()).name), bfd.nameOfDefaultProvider), List.<JCExpression>nil()))), null));
+ statements.append(maker.VarDef(maker.Modifiers(0L), bfd.builderFieldName, cloneType(maker, bfd.type, job.source, job.getContext()), maker.Select(maker.Ident(thisName), bfd.builderFieldName)));
+ statements.append(maker.If(maker.Unary(CTC_NOT, maker.Select(maker.Ident(thisName), bfd.nameOfSetFlag)), maker.Exec(maker.Assign(maker.Ident(bfd.builderFieldName), maker.Apply(typeParameterNames(maker, ((JCClassDecl) job.parentType.get()).typarams), maker.Select(maker.Ident(((JCClassDecl) job.parentType.get()).name), bfd.nameOfDefaultProvider), List.<JCExpression>nil()))), null));
}
if (bfd.nameOfSetFlag != null || (bfd.singularData != null && bfd.singularData.getSingularizer().shadowedDuringBuild())) {
args.append(maker.Ident(bfd.builderFieldName));
@@ -700,20 +757,20 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
if (addCleaning) {
- statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(type.toName("this")), type.toName("$lombokUnclean")), maker.Literal(CTC_BOOLEAN, 1))));
+ statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(job.toName("this")), job.toName(CLEAN_FIELD_NAME)), maker.Literal(CTC_BOOLEAN, 1))));
}
- if (builderName == null) {
+ if (staticName == null) {
call = maker.NewClass(null, List.<JCExpression>nil(), returnType, args.toList(), null);
statements.append(maker.Return(call));
} else {
ListBuffer<JCExpression> typeParams = new ListBuffer<JCExpression>();
- for (JCTypeParameter tp : ((JCClassDecl) type.get()).typarams) {
+ for (JCTypeParameter tp : ((JCClassDecl) job.builderType.get()).typarams) {
typeParams.append(maker.Ident(tp.name));
}
- JCExpression callee = maker.Ident(((JCClassDecl) type.up().get()).name);
- if (!isStatic) callee = maker.Select(callee, type.up().toName("this"));
- JCExpression fn = maker.Select(callee, builderName);
+ JCExpression callee = maker.Ident(((JCClassDecl) job.parentType.get()).name);
+ if (!job.isStatic) callee = maker.Select(callee, job.toName("this"));
+ JCExpression fn = maker.Select(callee, staticName);
call = maker.Apply(typeParams.toList(), fn, args.toList());
if (returnType instanceof JCPrimitiveTypeTree && CTC_VOID.equals(typeTag(returnType))) {
statements.append(maker.Exec(call));
@@ -724,10 +781,15 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JCBlock body = maker.Block(0, statements.toList());
- List<JCAnnotation> annsOnMethod = cfv.generateSideEffectFree() ? List.of(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
- List<JCVariableDecl> params = generateBuildArgs(cfv, type, builderFields);
- JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(toJavacModifier(access), annsOnMethod), type.toName(buildName), returnType, List.<JCTypeParameter>nil(), params, thrownExceptions, body, null);
- if (builderName == null) createRelevantNonNullAnnotation(type, methodDef);
+ List<JCAnnotation> annsOnMethod = job.checkerFramework.generateSideEffectFree() ? List.of(maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
+ JCVariableDecl recv = generateReceiver(job);
+ JCMethodDecl methodDef;
+ if (recv != null && maker.hasMethodDefWithRecvParam()) {
+ methodDef = maker.MethodDefWithRecvParam(maker.Modifiers(toJavacModifier(job.accessInners), annsOnMethod), job.toName(job.buildMethodName), returnType, List.<JCTypeParameter>nil(), recv, List.<JCVariableDecl>nil(), thrownExceptions, body, null);
+ } else {
+ methodDef = maker.MethodDef(maker.Modifiers(toJavacModifier(job.accessInners), annsOnMethod), job.toName(job.buildMethodName), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
+ }
+ if (staticName == null) createRelevantNonNullAnnotation(job.builderType, methodDef);
return methodDef;
}
@@ -743,52 +805,54 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
return maker.MethodDef(maker.Modifiers(modifiers), methodName, cloneType(maker, field.vartype, field, fieldNode.getContext()), copyTypeParams(fieldNode, params), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
- public JCMethodDecl generateBuilderMethod(CheckerFrameworkVersion cfv, boolean isStatic, String builderMethodName, String builderClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams, AccessLevel access) {
- JavacTreeMaker maker = type.getTreeMaker();
+ public JCMethodDecl generateBuilderMethod(BuilderJob job) {
+ //String builderClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams, AccessLevel access) {
+ //builderClassName, annotationNode, tdParent, typeParams, accessForOuters);
+
+ JavacTreeMaker maker = job.getTreeMaker();
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
- for (JCTypeParameter typeParam : typeParams) {
+ for (JCTypeParameter typeParam : job.typeParams) {
typeArgs.append(maker.Ident(typeParam.name));
}
JCExpression call;
- if (isStatic) {
- call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), false, typeParams), List.<JCExpression>nil(), null);
+ if (job.isStatic) {
+ call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderClassName), false, job.typeParams), List.<JCExpression>nil(), null);
} else {
- call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, null, type.toName(builderClassName), false, typeParams), List.<JCExpression>nil(), null);
- ((JCNewClass) call).encl = maker.Ident(type.toName("this"));
+ call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, null, job.toName(job.builderClassName), false, job.typeParams), List.<JCExpression>nil(), null);
+ ((JCNewClass) call).encl = maker.Ident(job.toName("this"));
}
JCStatement statement = maker.Return(call);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
- int modifiers = toJavacModifier(access);
- if (isStatic) modifiers |= Flags.STATIC;
- JCAnnotation annUnique = cfv.generateUnique() ? maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil()) : null;
- JCAnnotation annSef = cfv.generateSideEffectFree() ? maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()) : null;
- List<JCAnnotation> annsOnMethod;
- if (annUnique != null && annSef != null) annsOnMethod = List.of(annUnique, annSef);
- else if (annUnique != null) annsOnMethod = List.of(annUnique);
- else if (annSef != null) annsOnMethod = List.of(annSef);
- else annsOnMethod = List.nil();
- JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), type.toName(builderMethodName), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), !isStatic, typeParams), copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
- createRelevantNonNullAnnotation(type, methodDef);
+ int modifiers = toJavacModifier(job.accessOuters);
+ if (job.isStatic) modifiers |= Flags.STATIC;
+ List<JCAnnotation> annsOnMethod = List.nil();
+ if (job.checkerFramework.generateSideEffectFree()) annsOnMethod = List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
+ List<JCAnnotation> annsOnParamType = List.nil();
+ if (job.checkerFramework.generateUnique()) annsOnParamType = List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil()));
+
+ JCExpression returnType = namePlusTypeParamsToTypeReference(maker, job.parentType, job.getBuilderClassName(), !job.isStatic, job.builderTypeParams, annsOnParamType);
+ JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), job.toName(job.builderMethodName), returnType, job.copyTypeParams(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ createRelevantNonNullAnnotation(job.parentType, methodDef);
return methodDef;
}
- public void generateBuilderFields(JavacNode builderType, java.util.List<BuilderFieldData> builderFields, JCTree source) {
- int len = builderFields.size();
+ public void generateBuilderFields(BuilderJob job) {
+ int len = job.builderFields.size();
java.util.List<JavacNode> existing = new ArrayList<JavacNode>();
- for (JavacNode child : builderType.down()) {
+ for (JavacNode child : job.builderType.down()) {
if (child.getKind() == Kind.FIELD) existing.add(child);
}
java.util.List<JCVariableDecl> generated = new ArrayList<JCVariableDecl>();
for (int i = len - 1; i >= 0; i--) {
- BuilderFieldData bfd = builderFields.get(i);
+ BuilderFieldData bfd = job.builderFields.get(i);
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
- bfd.createdFields.addAll(bfd.singularData.getSingularizer().generateFields(bfd.singularData, builderType, source));
+ bfd.createdFields.addAll(bfd.singularData.getSingularizer().generateFields(bfd.singularData, job.builderType, job.source));
} else {
JavacNode field = null, setFlag = null;
for (JavacNode exists : existing) {
@@ -796,40 +860,41 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
if (n.equals(bfd.builderFieldName)) field = exists;
if (n.equals(bfd.nameOfSetFlag)) setFlag = exists;
}
- JavacTreeMaker maker = builderType.getTreeMaker();
+ JavacTreeMaker maker = job.getTreeMaker();
if (field == null) {
JCModifiers mods = maker.Modifiers(Flags.PRIVATE);
- JCVariableDecl newField = maker.VarDef(mods, bfd.builderFieldName, cloneType(maker, bfd.type, source, builderType.getContext()), null);
- field = injectFieldAndMarkGenerated(builderType, newField);
+ JCVariableDecl newField = maker.VarDef(mods, bfd.builderFieldName, cloneType(maker, bfd.type, job.source, job.getContext()), null);
+ field = injectFieldAndMarkGenerated(job.builderType, newField);
generated.add(newField);
}
if (setFlag == null && bfd.nameOfSetFlag != null) {
JCModifiers mods = maker.Modifiers(Flags.PRIVATE);
JCVariableDecl newField = maker.VarDef(mods, bfd.nameOfSetFlag, maker.TypeIdent(CTC_BOOLEAN), null);
- injectFieldAndMarkGenerated(builderType, newField);
+ injectFieldAndMarkGenerated(job.builderType, newField);
generated.add(newField);
}
bfd.createdFields.add(field);
}
}
- for (JCVariableDecl gen : generated) recursiveSetGeneratedBy(gen, source, builderType.getContext());
+ for (JCVariableDecl gen : generated) recursiveSetGeneratedBy(gen, job.source, job.getContext());
}
- 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) {
- makePrefixedSetterMethodForBuilder(cfv, builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, source, fluent, chain, fieldNode.annotations, fieldNode.originalFieldNode, access, prefix);
+ public void makePrefixedSetterMethodsForBuilder(BuilderJob job, BuilderFieldData bfd, String prefix) {
+ boolean deprecate = isFieldDeprecated(bfd.originalFieldNode);
+ if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) {
+ makePrefixedSetterMethodForBuilder(job, bfd, deprecate, prefix);
} else {
- fieldNode.singularData.getSingularizer().generateMethods(cfv, fieldNode.singularData, deprecate, builderType, source.get(), fluent, chain, access);
+ bfd.singularData.getSingularizer().generateMethods(job, bfd.singularData, deprecate);
}
}
- 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);
+ private void makePrefixedSetterMethodForBuilder(BuilderJob job, BuilderFieldData bfd, boolean deprecate, String prefix) {
+ JavacNode fieldNode = bfd.createdFields.get(0);
+ String setterPrefix = !prefix.isEmpty() ? prefix : job.oldFluent ? "" : "set";
+ String setterName = HandlerUtil.buildAccessorName(setterPrefix, bfd.name.toString());
+ Name setterName_ = job.builderType.toName(setterName);
- for (JavacNode child : builderType.down()) {
+ for (JavacNode child : job.builderType.down()) {
if (child.getKind() != Kind.METHOD) continue;
JCMethodDecl methodDecl = (JCMethodDecl) child.get();
Name existingName = methodDecl.name;
@@ -838,23 +903,24 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
JavacTreeMaker maker = fieldNode.getTreeMaker();
- List<JCAnnotation> methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode);
- JCMethodDecl newMethod = HandleSetter.createSetter(toJavacModifier(access), deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, chain, source, methodAnns, annosOnParam);
- if (cfv.generateCalledMethods()) {
- JCAnnotation ncAnno = maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__NOT_CALLED), List.<JCExpression>of(maker.Literal(newMethod.getName().toString())));
- JCClassDecl builderTypeNode = (JCClassDecl) builderType.get();
- JCExpression selfType = namePlusTypeParamsToTypeReference(maker, builderType, builderTypeNode.typarams);
- JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(ncAnno)), builderType.toName("this"), selfType, null);
- newMethod.params = List.of(recv, newMethod.params.get(0));
- }
- recursiveSetGeneratedBy(newMethod, source.get(), builderType.getContext());
- if (source.up().getKind() == Kind.METHOD) {
- copyJavadocFromParam(originalFieldNode.up(), newMethod, paramName.toString());
+ List<JCAnnotation> methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(bfd.originalFieldNode);
+ JCMethodDecl newMethod = null;
+ if (job.checkerFramework.generateCalledMethods() && maker.hasMethodDefWithRecvParam()) {
+ JCAnnotation ncAnno = maker.Annotation(genTypeRef(job.sourceNode, CheckerFrameworkVersion.NAME__NOT_CALLED), List.<JCExpression>of(maker.Literal(setterName.toString())));
+ JCClassDecl builderTypeNode = (JCClassDecl) job.builderType.get();
+ JCExpression selfType = namePlusTypeParamsToTypeReference(maker, job.builderType, builderTypeNode.typarams, List.<JCAnnotation>of(ncAnno));
+ JCVariableDecl recv = maker.VarDef(maker.Modifiers(Flags.PARAMETER, List.<JCAnnotation>nil()), job.builderType.toName("this"), selfType, null);
+ newMethod = HandleSetter.createSetterWithRecv(toJavacModifier(job.accessInners), deprecate, fieldNode, maker, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, job.sourceNode, methodAnns, bfd.annotations, recv);
+ }
+ if (newMethod == null) newMethod = HandleSetter.createSetter(toJavacModifier(job.accessInners), deprecate, fieldNode, maker, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, job.sourceNode, methodAnns, bfd.annotations);
+ recursiveSetGeneratedBy(newMethod, job.source, job.getContext());
+ if (job.sourceNode.up().getKind() == Kind.METHOD) {
+ copyJavadocFromParam(bfd.originalFieldNode.up(), newMethod, bfd.name.toString());
} else {
- copyJavadoc(originalFieldNode, newMethod, CopyJavadoc.SETTER, true);
+ copyJavadoc(bfd.originalFieldNode, newMethod, CopyJavadoc.SETTER, true);
}
- injectMethod(builderType, newMethod);
+ injectMethod(job.builderType, newMethod);
}
private void copyJavadocFromParam(JavacNode from, JCMethodDecl to, String param) {
@@ -871,14 +937,16 @@ public class HandleBuilder extends JavacAnnotationHandler<Builder> {
}
} catch (Exception ignore) {}
}
-
- public JavacNode makeBuilderClass(boolean isStatic, JavacNode source, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast, AccessLevel access) {
- JavacTreeMaker maker = tdParent.getTreeMaker();
- int modifiers = toJavacModifier(access);
- if (isStatic) modifiers |= Flags.STATIC;
+
+ public JavacNode makeBuilderClass(BuilderJob job) {
+ //boolean isStatic, JavacNode source, JavacNode tdParent, String builderClassName, List<JCTypeParameter> typeParams, JCAnnotation ast, AccessLevel access) {
+ //isStatic, annotationNode, tdParent, builderClassName, typeParams, ast, accessForOuters
+ JavacTreeMaker maker = job.getTreeMaker();
+ int modifiers = toJavacModifier(job.accessOuters);
+ if (job.isStatic) modifiers |= Flags.STATIC;
JCModifiers mods = maker.Modifiers(modifiers);
- JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderClassName), copyTypeParams(source, typeParams), null, List.<JCExpression>nil(), List.<JCTree>nil());
- return injectType(tdParent, builder);
+ JCClassDecl builder = maker.ClassDef(mods, job.getBuilderClassName(), job.copyTypeParams(), null, List.<JCExpression>nil(), List.<JCTree>nil());
+ return injectType(job.parentType, builder);
}
private void addObtainVia(BuilderFieldData bfd, JavacNode node) {
diff --git a/src/core/lombok/javac/handlers/HandleConstructor.java b/src/core/lombok/javac/handlers/HandleConstructor.java
index 2a683767..f30320dc 100644
--- a/src/core/lombok/javac/handlers/HandleConstructor.java
+++ b/src/core/lombok/javac/handlers/HandleConstructor.java
@@ -377,7 +377,6 @@ public class HandleConstructor {
addConstructorProperties(mods, typeNode, fieldsToParam);
}
if (onConstructor != null) mods.annotations = mods.annotations.appendList(copyAnnotations(onConstructor));
- if (getCheckerFrameworkVersion(source).generateUnique()) mods.annotations = mods.annotations.prepend(maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil()));
return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("<init>"),
null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(),
maker.Block(0L, nullChecks.appendList(assigns).toList()), null), source.get(), typeNode.getContext());
@@ -456,7 +455,6 @@ public class HandleConstructor {
JCClassDecl type = (JCClassDecl) typeNode.get();
JCModifiers mods = maker.Modifiers(Flags.STATIC | toJavacModifier(level));
- if (getCheckerFrameworkVersion(typeNode).generateUnique()) mods.annotations = mods.annotations.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil()));
JCExpression returnType, constructorType;
@@ -469,7 +467,9 @@ public class HandleConstructor {
typeParams.append(maker.TypeParameter(param.name, param.bounds));
}
}
- returnType = namePlusTypeParamsToTypeReference(maker, typeNode, type.typarams);
+ List<JCAnnotation> annsOnReturnType = List.nil();
+ if (getCheckerFrameworkVersion(typeNode).generateUnique()) annsOnReturnType = List.of(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil()));
+ returnType = namePlusTypeParamsToTypeReference(maker, typeNode, type.typarams, annsOnReturnType);
constructorType = namePlusTypeParamsToTypeReference(maker, typeNode, type.typarams);
for (JavacNode fieldNode : fields) {
diff --git a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
index d490738e..3935ab4e 100644
--- a/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
+++ b/src/core/lombok/javac/handlers/HandleEqualsAndHashCode.java
@@ -234,7 +234,7 @@ public class HandleEqualsAndHashCode extends JavacAnnotationHandler<EqualsAndHas
/* ... 1; */
init = maker.Literal(1);
}
- statements.append(maker.VarDef(maker.Modifiers(isEmpty ? finalFlag : 0), resultName, maker.TypeIdent(CTC_INT), init));
+ statements.append(maker.VarDef(maker.Modifiers(isEmpty ? finalFlag : 0L), resultName, maker.TypeIdent(CTC_INT), init));
}
for (Included<JavacNode, EqualsAndHashCode.Include> member : members) {
diff --git a/src/core/lombok/javac/handlers/HandleGetter.java b/src/core/lombok/javac/handlers/HandleGetter.java
index 110941d6..afe2c1b6 100644
--- a/src/core/lombok/javac/handlers/HandleGetter.java
+++ b/src/core/lombok/javac/handlers/HandleGetter.java
@@ -380,7 +380,7 @@ public class HandleGetter extends JavacAnnotationHandler<Getter> {
/* java.lang.Object value = this.fieldName.get();*/ {
JCExpression valueVarType = genJavaLangTypeRef(fieldNode, "Object");
- statements.append(maker.VarDef(maker.Modifiers(0), valueName, valueVarType, callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD))));
+ statements.append(maker.VarDef(maker.Modifiers(0L), valueName, valueVarType, callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD))));
}
/* if (value == null) { */ {
diff --git a/src/core/lombok/javac/handlers/HandleSetter.java b/src/core/lombok/javac/handlers/HandleSetter.java
index 82c95719..5c4c7681 100644
--- a/src/core/lombok/javac/handlers/HandleSetter.java
+++ b/src/core/lombok/javac/handlers/HandleSetter.java
@@ -226,7 +226,30 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> {
return d;
}
+ public static JCMethodDecl createSetterWithRecv(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name paramName, Name booleanFieldToSet, boolean shouldReturnThis, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam, JCVariableDecl recv) {
+ JCExpression returnType = null;
+ JCReturn returnStatement = null;
+ if (shouldReturnThis) {
+ returnType = cloneSelfType(field);
+ returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this")));
+ }
+
+ JCMethodDecl d = createSetterWithRecv(access, deprecate, field, treeMaker, setterName, paramName, booleanFieldToSet, returnType, returnStatement, source, onMethod, onParam, recv);
+ if (shouldReturnThis && getCheckerFrameworkVersion(source).generateReturnsReceiver()) {
+ List<JCAnnotation> annotations = d.mods.annotations;
+ if (annotations == null) annotations = List.nil();
+ JCAnnotation anno = treeMaker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil());
+ recursiveSetGeneratedBy(anno, source.get(), field.getContext());
+ d.mods.annotations = annotations.prepend(anno);
+ }
+ return d;
+ }
+
public static JCMethodDecl createSetter(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name paramName, Name booleanFieldToSet, JCExpression methodType, JCStatement returnStatement, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
+ return createSetterWithRecv(access, deprecate, field, treeMaker, setterName, paramName, booleanFieldToSet, methodType, returnStatement, source, onMethod, onParam, null);
+ }
+
+ public static JCMethodDecl createSetterWithRecv(long access, boolean deprecate, JavacNode field, JavacTreeMaker treeMaker, String setterName, Name paramName, Name booleanFieldToSet, JCExpression methodType, JCStatement returnStatement, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam, JCVariableDecl recv) {
if (setterName == null) return null;
JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
@@ -277,8 +300,14 @@ public class HandleSetter extends JavacAnnotationHandler<Setter> {
annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
}
- JCMethodDecl methodDef = treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType,
- methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue);
+ JCMethodDecl methodDef;
+ if (recv != null && treeMaker.hasMethodDefWithRecvParam()) {
+ methodDef = treeMaker.MethodDefWithRecvParam(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType,
+ methodGenericParams, recv, parameters, throwsClauses, methodBody, annotationMethodDefaultValue);
+ } else {
+ methodDef = treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType,
+ methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue);
+ }
if (returnStatement != null) createRelevantNonNullAnnotation(source, methodDef);
JCMethodDecl decl = recursiveSetGeneratedBy(methodDef, source.get(), field.getContext());
copyJavadoc(field, decl, CopyJavadoc.SETTER, returnStatement != null);
diff --git a/src/core/lombok/javac/handlers/HandleSuperBuilder.java b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
index f6bf9e1f..99f0ea6a 100644
--- a/src/core/lombok/javac/handlers/HandleSuperBuilder.java
+++ b/src/core/lombok/javac/handlers/HandleSuperBuilder.java
@@ -21,6 +21,7 @@
*/
package lombok.javac.handlers;
+import static lombok.javac.handlers.HandleBuilder.*;
import static lombok.core.handlers.HandlerUtil.*;
import static lombok.javac.Javac.*;
import static lombok.javac.handlers.JavacHandlerUtil.*;
@@ -78,6 +79,7 @@ import lombok.javac.JavacAnnotationHandler;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
import lombok.javac.handlers.HandleBuilder.BuilderFieldData;
+import lombok.javac.handlers.HandleBuilder.BuilderJob;
import lombok.javac.handlers.JavacHandlerUtil.MemberExistsResult;
import lombok.javac.handlers.JavacSingularsRecipes.ExpressionMaker;
import lombok.javac.handlers.JavacSingularsRecipes.JavacSingularizer;
@@ -88,58 +90,91 @@ import lombok.javac.handlers.JavacSingularsRecipes.StatementMaker;
@HandlerPriority(-1024) //-2^10; to ensure we've picked up @FieldDefault's changes (-2048) but @Value hasn't removed itself yet (-512), so that we can error on presence of it on the builder classes.
public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
private static final String SELF_METHOD = "self";
- private static final String TO_BUILDER_METHOD_NAME = "toBuilder";
private static final String FILL_VALUES_METHOD_NAME = "$fillValuesFrom";
private static final String STATIC_FILL_VALUES_METHOD_NAME = "$fillValuesFromInstanceIntoBuilder";
private static final String INSTANCE_VARIABLE_NAME = "instance";
private static final String BUILDER_VARIABLE_NAME = "b";
-
+
+ class SuperBuilderJob extends BuilderJob {
+ JavacNode builderAbstractType;
+ String builderAbstractClassName;
+ JavacNode builderImplType;
+ String builderImplClassName;
+ List<JCTypeParameter> builderTypeParams_;
+
+ void init(AnnotationValues<SuperBuilder> annValues, SuperBuilder ann, JavacNode node) {
+ accessOuters = accessInners = AccessLevel.PUBLIC;
+ oldFluent = true;
+ oldChain = true;
+
+ builderMethodName = ann.builderMethodName();
+ buildMethodName = ann.buildMethodName();
+ toBuilder = ann.toBuilder();
+
+ if (builderMethodName == null) builderMethodName = "builder";
+ if (buildMethodName == null) buildMethodName = "build";
+ builderClassName = fixBuilderClassName(node, "");
+ }
+
+ void setBuilderToImpl() {
+ builderType = builderImplType;
+ builderClassName = builderImplClassName;
+ builderTypeParams = typeParams;
+ }
+
+ void setBuilderToAbstract() {
+ builderType = builderAbstractType;
+ builderClassName = builderAbstractClassName;
+ builderTypeParams = builderTypeParams_;
+ }
+ }
+
@Override
public void handle(AnnotationValues<SuperBuilder> annotation, JCAnnotation ast, JavacNode annotationNode) {
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.SUPERBUILDER_FLAG_USAGE, "@SuperBuilder");
- CheckerFrameworkVersion cfv = getCheckerFrameworkVersion(annotationNode);
- SuperBuilder superbuilderAnnotation = annotation.getInstance();
- // Do not delete the SuperBuilder annotation here, we need it for @Jacksonized.
+ SuperBuilderJob job = new SuperBuilderJob();
+ job.sourceNode = annotationNode;
+ job.source = ast;
+ job.checkerFramework = getCheckerFrameworkVersion(annotationNode);
+ job.isStatic = true;
- String builderMethodName = superbuilderAnnotation.builderMethodName();
- String buildMethodName = superbuilderAnnotation.buildMethodName();
+ SuperBuilder annInstance = annotation.getInstance();
- if (builderMethodName == null) builderMethodName = "builder";
- if (buildMethodName == null) buildMethodName = "build";
+ job.init(annotation, annInstance, annotationNode);
boolean generateBuilderMethod;
- if (builderMethodName.isEmpty()) {
+ if (job.builderMethodName.isEmpty()) {
generateBuilderMethod = false;
- } else if (!checkName("builderMethodName", builderMethodName, annotationNode)) {
+ } else if (!checkName("builderMethodName", job.builderMethodName, annotationNode)) {
return;
} else {
generateBuilderMethod = true;
}
- if (!checkName("buildMethodName", buildMethodName, annotationNode)) return;
+ if (!checkName("buildMethodName", job.buildMethodName, annotationNode)) return;
- boolean toBuilder = superbuilderAnnotation.toBuilder();
+ // Do not delete the SuperBuilder annotation here, we need it for @Jacksonized.
- JavacNode tdParent = annotationNode.up();
+ JavacNode parent = annotationNode.up();
- java.util.List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
- List<JCTypeParameter> typeParams = List.nil();
- List<JCExpression> thrownExceptions = List.nil();
+ job.builderFields = new ArrayList<BuilderFieldData>();
+ job.typeParams = List.nil();
+ List<JCExpression> buildMethodThrownExceptions = List.nil();
List<JCExpression> superclassTypeParams = List.nil();
-
boolean addCleaning = false;
- if (!(tdParent.get() instanceof JCClassDecl)) {
+ if (!(parent.get() instanceof JCClassDecl)) {
annotationNode.addError("@SuperBuilder is only supported on types.");
return;
}
// Gather all fields of the class that should be set by the builder.
- JCClassDecl td = (JCClassDecl) tdParent.get();
+ job.parentType = parent;
+ JCClassDecl td = (JCClassDecl) parent.get();
ListBuffer<JavacNode> allFields = new ListBuffer<JavacNode>();
ArrayList<JavacNode> nonFinalNonDefaultedFields = null;
- boolean valuePresent = (hasAnnotation(lombok.Value.class, tdParent) || hasAnnotation("lombok.experimental.Value", tdParent));
- for (JavacNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) {
+ boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation("lombok.experimental.Value", parent));
+ for (JavacNode fieldNode : HandleConstructor.findAllFields(parent, true)) {
JCVariableDecl fd = (JCVariableDecl) fieldNode.get();
JavacNode isDefault = findAnnotation(Builder.Default.class, fieldNode, true);
boolean isFinal = (fd.mods.flags & Flags.FINAL) != 0 || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode));
@@ -149,7 +184,7 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
bfd.builderFieldName = bfd.name;
bfd.annotations = findCopyableAnnotations(fieldNode);
bfd.type = fd.vartype;
- bfd.singularData = getSingularData(fieldNode, superbuilderAnnotation.setterPrefix());
+ bfd.singularData = getSingularData(fieldNode, annInstance.setterPrefix());
bfd.originalFieldNode = fieldNode;
if (bfd.singularData != null && isDefault != null) {
@@ -169,44 +204,21 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
}
if (isDefault != null) {
- bfd.nameOfDefaultProvider = tdParent.toName("$default$" + bfd.name);
- bfd.nameOfSetFlag = tdParent.toName(bfd.name + "$set");
- bfd.builderFieldName = tdParent.toName(bfd.name + "$value");
+ bfd.nameOfDefaultProvider = parent.toName(DEFAULT_PREFIX + bfd.name);
+ bfd.nameOfSetFlag = parent.toName(bfd.name + SET_PREFIX);
+ bfd.builderFieldName = parent.toName(bfd.name + VALUE_PREFIX);
JCMethodDecl md = HandleBuilder.generateDefaultProvider(bfd.nameOfDefaultProvider, fieldNode, td.typarams);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
- if (md != null) injectMethod(tdParent, md);
+ if (md != null) injectMethod(parent, md);
}
addObtainVia(bfd, fieldNode);
- builderFields.add(bfd);
+ job.builderFields.add(bfd);
allFields.append(fieldNode);
}
- // Set the names of the builder classes.
- String builderClassNameTemplate = annotationNode.getAst().readConfiguration(ConfigurationKeys.BUILDER_CLASS_NAME);
- if (builderClassNameTemplate == null || builderClassNameTemplate.isEmpty()) builderClassNameTemplate = "*Builder";
- String builderClassName = builderClassNameTemplate.replace("*", td.name.toString());
- String builderImplClassName = builderClassName + "Impl";
- JCTree extendsClause = Javac.getExtendsClause(td);
- JCExpression superclassBuilderClassExpression = null;
- if (extendsClause instanceof JCTypeApply) {
- // Remember the type arguments, because we need them for the extends clause of our abstract builder class.
- superclassTypeParams = ((JCTypeApply) extendsClause).getTypeArguments();
- // A class name with a generics type, e.g., "Superclass<A>".
- extendsClause = ((JCTypeApply) extendsClause).getType();
- }
- if (extendsClause instanceof JCFieldAccess) {
- Name superclassClassName = ((JCFieldAccess)extendsClause).getIdentifier();
- String superclassBuilderClassName = builderClassNameTemplate.replace("*", superclassClassName);
- superclassBuilderClassExpression = tdParent.getTreeMaker().Select((JCFieldAccess) extendsClause,
- tdParent.toName(superclassBuilderClassName));
- } else if (extendsClause != null) {
- String superclassBuilderClassName = builderClassNameTemplate.replace("*", extendsClause.toString());
- superclassBuilderClassExpression = chainDots(tdParent, extendsClause.toString(), superclassBuilderClassName);
- }
- // If there is no superclass, superclassBuilderClassExpression is still == null at this point.
- // You can use it to check whether to inherit or not.
-
- typeParams = td.typarams;
+ job.typeParams = job.builderTypeParams = td.typarams;
+ job.builderClassName = job.replaceBuilderClassName(td.name);
+ if (!checkName("builderClassName", job.builderClassName, annotationNode)) return;
// <C, B> are the generics for our builder.
String classGenericName = "C";
@@ -214,14 +226,46 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
// We have to make sure that the generics' names do not collide with any generics on the annotated class,
// the classname itself, or any member type name of the annotated class.
// For instance, if there are generics <B, B2, C> on the annotated class, use "C2" and "B3" for our builder.
- java.util.HashSet<String> usedNames = gatherUsedTypeNames(typeParams, td);
+ java.util.HashSet<String> usedNames = gatherUsedTypeNames(job.typeParams, td);
classGenericName = generateNonclashingNameFor(classGenericName, usedNames);
builderGenericName = generateNonclashingNameFor(builderGenericName, usedNames);
- thrownExceptions = List.nil();
+ JavacTreeMaker maker = annotationNode.getTreeMaker();
+
+ {
+ JCExpression annotatedClass = namePlusTypeParamsToTypeReference(maker, parent, job.typeParams);
+ JCTypeParameter c = maker.TypeParameter(parent.toName(classGenericName), List.<JCExpression>of(annotatedClass));
+ ListBuffer<JCExpression> typeParamsForBuilder = getTypeParamExpressions(job.typeParams, maker, job.sourceNode.getContext());
+ typeParamsForBuilder.add(maker.Ident(parent.toName(classGenericName)));
+ typeParamsForBuilder.add(maker.Ident(parent.toName(builderGenericName)));
+ JCTypeApply typeApply = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, parent, job.getBuilderClassName(), false, List.<JCTypeParameter>nil()), typeParamsForBuilder.toList());
+ JCTypeParameter d = maker.TypeParameter(parent.toName(builderGenericName), List.<JCExpression>of(typeApply));
+ if (job.typeParams == null || job.typeParams.isEmpty()) {
+ job.builderTypeParams_ = List.of(c, d);
+ } else {
+ job.builderTypeParams_ = job.typeParams.append(c).append(d);
+ }
+ }
+
+ JCTree extendsClause = Javac.getExtendsClause(td);
+ JCExpression superclassBuilderClass = null;
+ if (extendsClause instanceof JCTypeApply) {
+ // Remember the type arguments, because we need them for the extends clause of our abstract builder class.
+ superclassTypeParams = ((JCTypeApply) extendsClause).getTypeArguments();
+ // A class name with a generics type, e.g., "Superclass<A>".
+ extendsClause = ((JCTypeApply) extendsClause).getType();
+ }
+ if (extendsClause instanceof JCFieldAccess) {
+ Name superclassName = ((JCFieldAccess) extendsClause).getIdentifier();
+ String superclassBuilderClassName = superclassName.toString() + "Builder";
+ superclassBuilderClass = parent.getTreeMaker().Select((JCFieldAccess) extendsClause, parent.toName(superclassBuilderClassName));
+ } else if (extendsClause != null) {
+ String superclassBuilderClassName = extendsClause.toString() + "Builder";
+ superclassBuilderClass = chainDots(parent, extendsClause.toString(), superclassBuilderClassName);
+ }
// Check validity of @ObtainVia fields, and add check if adding cleaning for @Singular is necessary.
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
if (bfd.singularData.getSingularizer().requiresCleaning()) {
addCleaning = true;
@@ -240,83 +284,85 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
}
}
+ job.builderAbstractClassName = job.builderClassName = job.replaceBuilderClassName(td.name);
+ job.builderImplClassName = job.builderAbstractClassName + "Impl";
+
// Create the abstract builder class.
- JavacNode builderType = findInnerClass(tdParent, builderClassName);
- if (builderType == null) {
- builderType = generateBuilderAbstractClass(annotationNode, tdParent, builderClassName, superclassBuilderClassExpression,
- typeParams, superclassTypeParams, classGenericName, builderGenericName);
- recursiveSetGeneratedBy(builderType.get(), ast, annotationNode.getContext());
+ job.builderAbstractType = findInnerClass(parent, job.builderClassName);
+ if (job.builderAbstractType == null) {
+ job.builderAbstractType = generateBuilderAbstractClass(job, superclassBuilderClass, superclassTypeParams, classGenericName, builderGenericName);
+ recursiveSetGeneratedBy(job.builderAbstractType.get(), ast, annotationNode.getContext());
} else {
- JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get();
+ JCClassDecl builderTypeDeclaration = (JCClassDecl) job.builderAbstractType.get();
if (!builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)
|| !builderTypeDeclaration.getModifiers().getFlags().contains(Modifier.ABSTRACT)) {
annotationNode.addError("Existing Builder must be an abstract static inner class.");
return;
}
- sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
+ sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(job.builderAbstractType, annotationNode);
// Generate errors for @Singular BFDs that have one already defined node.
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.builderFields) {
SingularData sd = bfd.singularData;
if (sd == null) continue;
JavacSingularizer singularizer = sd.getSingularizer();
if (singularizer == null) continue;
- if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
+ if (singularizer.checkForAlreadyExistingNodesAndGenerateError(job.builderType, sd)) {
bfd.singularData = null;
}
}
}
// Generate the fields in the abstract builder class that hold the values for the instance.
- generateBuilderFields(builderType, builderFields, ast);
+ job.setBuilderToAbstract();
+ generateBuilderFields(job.builderType, job.builderFields, ast);
if (addCleaning) {
- JavacTreeMaker maker = builderType.getTreeMaker();
- JCVariableDecl uncleanField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), builderType.toName("$lombokUnclean"), maker.TypeIdent(CTC_BOOLEAN), null);
+ JCVariableDecl uncleanField = maker.VarDef(maker.Modifiers(Flags.PRIVATE), job.toName("$lombokUnclean"), maker.TypeIdent(CTC_BOOLEAN), null);
recursiveSetGeneratedBy(uncleanField, ast, annotationNode.getContext());
- injectFieldAndMarkGenerated(builderType, uncleanField);
+ injectFieldAndMarkGenerated(job.builderType, uncleanField);
}
- if (toBuilder) {
+ if (job.toBuilder) {
// Generate $fillValuesFrom() method in the abstract builder.
- JCMethodDecl fvm = generateFillValuesMethod(tdParent, superclassBuilderClassExpression != null, builderGenericName, classGenericName, builderClassName);
+ JCMethodDecl fvm = generateFillValuesMethod(job, superclassBuilderClass != null, builderGenericName, classGenericName);
recursiveSetGeneratedBy(fvm, ast, annotationNode.getContext());
- injectMethod(builderType, fvm);
+ injectMethod(job.builderType, fvm);
// Generate $fillValuesFromInstanceIntoBuilder() method in the builder implementation class.
- JCMethodDecl sfvm = generateStaticFillValuesMethod(tdParent, builderClassName, typeParams, builderFields, superbuilderAnnotation.setterPrefix());
+ JCMethodDecl sfvm = generateStaticFillValuesMethod(job, annInstance.setterPrefix());
recursiveSetGeneratedBy(sfvm, ast, annotationNode.getContext());
- injectMethod(builderType, sfvm);
+ injectMethod(job.builderType, sfvm);
}
// Generate abstract self() and build() methods in the abstract builder.
- JCMethodDecl asm = generateAbstractSelfMethod(cfv, tdParent, superclassBuilderClassExpression != null, builderGenericName);
+ JCMethodDecl asm = generateAbstractSelfMethod(job, superclassBuilderClass != null, builderGenericName);
recursiveSetGeneratedBy(asm, ast, annotationNode.getContext());
- injectMethod(builderType, asm);
- JCMethodDecl abm = generateAbstractBuildMethod(cfv, tdParent, buildMethodName, builderFields, superclassBuilderClassExpression != null, classGenericName);
+ injectMethod(job.builderType, asm);
+ JCMethodDecl abm = generateAbstractBuildMethod(job, superclassBuilderClass != null, classGenericName);
recursiveSetGeneratedBy(abm, ast, annotationNode.getContext());
- injectMethod(builderType, abm);
+ injectMethod(job.builderType, abm);
// Create the setter methods in the abstract builder.
- for (BuilderFieldData bfd : builderFields) {
- generateSetterMethodsForBuilder(cfv, builderType, bfd, annotationNode, builderGenericName, superbuilderAnnotation.setterPrefix());
+ for (BuilderFieldData bfd : job.builderFields) {
+ generateSetterMethodsForBuilder(job, bfd, builderGenericName, annInstance.setterPrefix());
}
// Create the toString() method for the abstract builder.
java.util.List<Included<JavacNode, ToString.Include>> fieldNodes = new ArrayList<Included<JavacNode, ToString.Include>>();
- for (BuilderFieldData bfd : builderFields) {
+ for (BuilderFieldData bfd : job.builderFields) {
for (JavacNode f : bfd.createdFields) {
fieldNodes.add(new Included<JavacNode, ToString.Include>(f, null, true, false));
}
}
// Let toString() call super.toString() if there is a superclass, so that it also shows fields from the superclass' builder.
- JCMethodDecl toStringMethod = HandleToString.createToString(builderType, fieldNodes, true, superclassBuilderClassExpression != null, FieldAccess.ALWAYS_FIELD, ast);
- if (toStringMethod != null) injectMethod(builderType, toStringMethod);
+ JCMethodDecl toStringMethod = HandleToString.createToString(job.builderType, fieldNodes, true, superclassBuilderClass != null, FieldAccess.ALWAYS_FIELD, ast);
+ if (toStringMethod != null) injectMethod(job.builderType, toStringMethod);
// If clean methods are requested, add them now.
if (addCleaning) {
- JCMethodDecl md = generateCleanMethod(builderFields, builderType, ast);
+ JCMethodDecl md = generateCleanMethod(job.builderFields, job.builderType, ast);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
- injectMethod(builderType, md);
+ injectMethod(job.builderType, md);
}
boolean isAbstract = (td.mods.flags & Flags.ABSTRACT) != 0;
@@ -324,69 +370,71 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
// Only non-abstract classes get the Builder implementation.
// Create the builder implementation class.
- JavacNode builderImplType = findInnerClass(tdParent, builderImplClassName);
- if (builderImplType == null) {
- builderImplType = generateBuilderImplClass(annotationNode, tdParent, builderImplClassName, builderClassName, typeParams);
- recursiveSetGeneratedBy(builderImplType.get(), ast, annotationNode.getContext());
+ job.builderImplType = findInnerClass(parent, job.builderImplClassName);
+ if (job.builderImplType == null) {
+ job.builderImplType = generateBuilderImplClass(job);
+ recursiveSetGeneratedBy(job.builderImplType.get(), ast, annotationNode.getContext());
} else {
- JCClassDecl builderImplTypeDeclaration = (JCClassDecl) builderImplType.get();
+ JCClassDecl builderImplTypeDeclaration = (JCClassDecl) job.builderImplType.get();
if (!builderImplTypeDeclaration.getModifiers().getFlags().contains(Modifier.STATIC)
|| builderImplTypeDeclaration.getModifiers().getFlags().contains(Modifier.ABSTRACT)) {
annotationNode.addError("Existing BuilderImpl must be a non-abstract static inner class.");
return;
}
- sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderImplType, annotationNode);
+ sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(job.builderImplType, annotationNode);
}
// Create a simple constructor for the BuilderImpl class.
- JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PRIVATE, List.<JCAnnotation>nil(), builderImplType, List.<JavacNode>nil(), false, annotationNode);
- if (cd != null) injectMethod(builderImplType, cd);
+ JCMethodDecl cd = HandleConstructor.createConstructor(AccessLevel.PRIVATE, List.<JCAnnotation>nil(), job.builderImplType, List.<JavacNode>nil(), false, annotationNode);
+ if (cd != null) injectMethod(job.builderImplType, cd);
+ job.setBuilderToImpl();
// Create the self() and build() methods in the BuilderImpl.
- JCMethodDecl selfMethod = generateSelfMethod(cfv, builderImplType, typeParams);
+ JCMethodDecl selfMethod = generateSelfMethod(job);
recursiveSetGeneratedBy(selfMethod, ast, annotationNode.getContext());
- injectMethod(builderImplType, selfMethod);
- if (methodExists(buildMethodName, builderImplType, -1) == MemberExistsResult.NOT_EXISTS) {
- JCMethodDecl buildMethod = generateBuildMethod(cfv, buildMethodName, tdParent, builderImplType, builderFields, thrownExceptions);
+ injectMethod(job.builderType, selfMethod);
+ if (methodExists(job.buildMethodName, job.builderType, -1) == MemberExistsResult.NOT_EXISTS) {
+ JCMethodDecl buildMethod = generateBuildMethod(job, buildMethodThrownExceptions);
recursiveSetGeneratedBy(buildMethod, ast, annotationNode.getContext());
- injectMethod(builderImplType, buildMethod);
+ injectMethod(job.builderType, buildMethod);
}
}
// Generate a constructor in the annotated class that takes a builder as argument.
- if (!constructorExists(tdParent, builderClassName)) {
- generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName,
- superclassBuilderClassExpression != null);
+ if (!constructorExists(job.parentType, job.builderAbstractClassName)) {
+ job.setBuilderToAbstract();
+ generateBuilderBasedConstructor(job, superclassBuilderClass != null);
}
- if (isAbstract) {
+ if (!isAbstract) {
// Only non-abstract classes get the builder() and toBuilder() methods.
- return;
- }
- // Add the builder() method to the annotated class.
- // Allow users to specify their own builder() methods, e.g., to provide default values.
- if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
- if (generateBuilderMethod) {
- JCMethodDecl builderMethod = generateBuilderMethod(cfv, builderMethodName, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams);
- recursiveSetGeneratedBy(builderMethod, ast, annotationNode.getContext());
- if (builderMethod != null) injectMethod(tdParent, builderMethod);
- }
-
- // Add the toBuilder() method to the annotated class.
- if (toBuilder) {
- switch (methodExists(TO_BUILDER_METHOD_NAME, tdParent, 0)) {
- case EXISTS_BY_USER:
- break;
- case NOT_EXISTS:
- JCMethodDecl md = generateToBuilderMethod(cfv, builderClassName, builderImplClassName, annotationNode, tdParent, typeParams);
- if (md != null) {
- recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
- injectMethod(tdParent, md);
+ // Add the builder() method to the annotated class.
+ // Allow users to specify their own builder() methods, e.g., to provide default values.
+ if (generateBuilderMethod && methodExists(job.builderMethodName, job.parentType, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
+ if (generateBuilderMethod) {
+ JCMethodDecl builderMethod = generateBuilderMethod(job);
+ if (builderMethod != null) {
+ recursiveSetGeneratedBy(builderMethod, ast, annotationNode.getContext());
+ injectMethod(job.parentType, builderMethod);
+ }
+ }
+
+ // Add the toBuilder() method to the annotated class.
+ if (job.toBuilder) {
+ switch (methodExists(TO_BUILDER_METHOD_NAME, job.parentType, 0)) {
+ case EXISTS_BY_USER:
+ break;
+ case NOT_EXISTS:
+ JCMethodDecl md = generateToBuilderMethod(job);
+ if (md != null) {
+ recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
+ injectMethod(job.parentType, md);
+ }
+ break;
+ default:
+ // Should not happen.
}
- break;
- default:
- // Should not happen.
}
}
@@ -400,95 +448,86 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
/**
* Creates and returns the abstract builder class and injects it into the annotated class.
*/
- private JavacNode generateBuilderAbstractClass(JavacNode source, JavacNode tdParent, String builderClass,
- JCExpression superclassBuilderClassExpression, List<JCTypeParameter> typeParams,
- List<JCExpression> superclassTypeParams, String classGenericName, String builderGenericName) {
-
- JavacTreeMaker maker = tdParent.getTreeMaker();
+ private JavacNode generateBuilderAbstractClass(SuperBuilderJob job, JCExpression superclassBuilderClass, List<JCExpression> superclassTypeParams, String classGenericName, String builderGenericName) {
+ JavacTreeMaker maker = job.parentType.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.STATIC | Flags.ABSTRACT | Flags.PUBLIC);
// Keep any type params of the annotated class.
ListBuffer<JCTypeParameter> allTypeParams = new ListBuffer<JCTypeParameter>();
- allTypeParams.addAll(copyTypeParams(source, typeParams));
+ allTypeParams.addAll(copyTypeParams(job.sourceNode, job.typeParams));
// Add builder-specific type params required for inheritable builders.
// 1. The return type for the build() method, named "C", which extends the annotated class.
- JCExpression annotatedClass = namePlusTypeParamsToTypeReference(maker, tdParent, typeParams);
+ JCExpression annotatedClass = namePlusTypeParamsToTypeReference(maker, job.parentType, job.typeParams);
- allTypeParams.add(maker.TypeParameter(tdParent.toName(classGenericName), List.<JCExpression>of(annotatedClass)));
+ allTypeParams.add(maker.TypeParameter(job.toName(classGenericName), List.<JCExpression>of(annotatedClass)));
// 2. The return type for all setter methods, named "B", which extends this builder class.
- Name builderClassName = tdParent.toName(builderClass);
- ListBuffer<JCExpression> typeParamsForBuilder = getTypeParamExpressions(typeParams, maker, source.getContext());
- typeParamsForBuilder.add(maker.Ident(tdParent.toName(classGenericName)));
- typeParamsForBuilder.add(maker.Ident(tdParent.toName(builderGenericName)));
- JCTypeApply typeApply = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, tdParent, builderClassName, false, List.<JCTypeParameter>nil()), typeParamsForBuilder.toList());
- allTypeParams.add(maker.TypeParameter(tdParent.toName(builderGenericName), List.<JCExpression>of(typeApply)));
+ Name builderClassName = job.toName(job.builderClassName);
+ ListBuffer<JCExpression> typeParamsForBuilder = getTypeParamExpressions(job.typeParams, maker, job.sourceNode.getContext());
+ typeParamsForBuilder.add(maker.Ident(job.toName(classGenericName)));
+ typeParamsForBuilder.add(maker.Ident(job.toName(builderGenericName)));
+ JCTypeApply typeApply = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, job.parentType, builderClassName, false, List.<JCTypeParameter>nil()), typeParamsForBuilder.toList());
+ allTypeParams.add(maker.TypeParameter(job.toName(builderGenericName), List.<JCExpression>of(typeApply)));
JCExpression extending = null;
- if (superclassBuilderClassExpression != null) {
+ if (superclassBuilderClass != null) {
// If the annotated class extends another class, we want this builder to extend the builder of the superclass.
// 1. Add the type parameters of the superclass.
- typeParamsForBuilder = getTypeParamExpressions(superclassTypeParams, maker, source.getContext());
+ typeParamsForBuilder = getTypeParamExpressions(superclassTypeParams, maker, job.sourceNode.getContext());
// 2. Add the builder type params <C, B>.
- typeParamsForBuilder.add(maker.Ident(tdParent.toName(classGenericName)));
- typeParamsForBuilder.add(maker.Ident(tdParent.toName(builderGenericName)));
- extending = maker.TypeApply(superclassBuilderClassExpression, typeParamsForBuilder.toList());
+ typeParamsForBuilder.add(maker.Ident(job.toName(classGenericName)));
+ typeParamsForBuilder.add(maker.Ident(job.toName(builderGenericName)));
+ extending = maker.TypeApply(superclassBuilderClass, typeParamsForBuilder.toList());
}
JCClassDecl builder = maker.ClassDef(mods, builderClassName, allTypeParams.toList(), extending, List.<JCExpression>nil(), List.<JCTree>nil());
- return injectType(tdParent, builder);
+ return injectType(job.parentType, builder);
}
/**
* Creates and returns the concrete builder implementation class and injects it into the annotated class.
*/
- private JavacNode generateBuilderImplClass(JavacNode source, JavacNode tdParent, String builderImplClass, String builderAbstractClass, List<JCTypeParameter> typeParams) {
- JavacTreeMaker maker = tdParent.getTreeMaker();
+ private JavacNode generateBuilderImplClass(SuperBuilderJob job) {
+ JavacTreeMaker maker = job.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.STATIC | Flags.PRIVATE | Flags.FINAL);
// Extend the abstract builder.
- JCExpression extending = namePlusTypeParamsToTypeReference(maker, tdParent, tdParent.toName(builderAbstractClass), false, List.<JCTypeParameter>nil());
+ JCExpression extending = namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderAbstractClassName), false, List.<JCTypeParameter>nil());
// Add any type params of the annotated class.
ListBuffer<JCTypeParameter> allTypeParams = new ListBuffer<JCTypeParameter>();
- allTypeParams.addAll(copyTypeParams(source, typeParams));
+ allTypeParams.addAll(copyTypeParams(job.sourceNode, job.typeParams));
// Add builder-specific type params required for inheritable builders.
// 1. The return type for the build() method (named "C" in the abstract builder), which is the annotated class.
- JCExpression annotatedClass = namePlusTypeParamsToTypeReference(maker, tdParent, typeParams);
+ JCExpression annotatedClass = namePlusTypeParamsToTypeReference(maker, job.parentType, job.typeParams);
// 2. The return type for all setter methods (named "B" in the abstract builder), which is this builder class.
- JCExpression builderImplClassExpression = namePlusTypeParamsToTypeReference(maker, tdParent, tdParent.toName(builderImplClass), false, typeParams);
+ JCExpression builderImplClassExpression = namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderImplClassName), false, job.typeParams);
- ListBuffer<JCExpression> typeParamsForBuilder = getTypeParamExpressions(typeParams, maker, source.getContext());
+ ListBuffer<JCExpression> typeParamsForBuilder = getTypeParamExpressions(job.typeParams, maker, job.getContext());
typeParamsForBuilder.add(annotatedClass);
typeParamsForBuilder.add(builderImplClassExpression);
extending = maker.TypeApply(extending, typeParamsForBuilder.toList());
- JCClassDecl builder = maker.ClassDef(mods, tdParent.toName(builderImplClass), copyTypeParams(source, typeParams), extending, List.<JCExpression>nil(), List.<JCTree>nil());
- return injectType(tdParent, builder);
+ JCClassDecl builder = maker.ClassDef(mods, job.toName(job.builderImplClassName), copyTypeParams(job.parentType, job.typeParams), extending, List.<JCExpression>nil(), List.<JCTree>nil());
+ return injectType(job.parentType, builder);
}
/**
* Generates a constructor that has a builder as the only parameter.
* The values from the builder are used to initialize the fields of new instances.
*
- * @param typeNode
- * the type (with the {@code @Builder} annotation) for which a
- * constructor should be generated.
- * @param typeParams
- * @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
* If {@code true}, the constructor will explicitly call a super
* constructor with the builder as argument. Requires
* {@code builderClassAsParameter != null}.
*/
- private void generateBuilderBasedConstructor(CheckerFrameworkVersion cfv, JavacNode typeNode, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, JavacNode source, String builderClassName, boolean callBuilderBasedSuperConstructor) {
- JavacTreeMaker maker = typeNode.getTreeMaker();
+ private void generateBuilderBasedConstructor(SuperBuilderJob job, boolean callBuilderBasedSuperConstructor) {
+ JavacTreeMaker maker = job.getTreeMaker();
AccessLevel level = AccessLevel.PROTECTED;
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
- Name builderVariableName = typeNode.toName(BUILDER_VARIABLE_NAME);
- for (BuilderFieldData bfd : builderFields) {
+ Name builderVariableName = job.toName(BUILDER_VARIABLE_NAME);
+ for (BuilderFieldData bfd : job.builderFields) {
JCExpression rhs;
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, bfd.originalFieldNode, bfd.type, statements, bfd.builderFieldName, "b");
@@ -496,67 +535,66 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
} else {
rhs = maker.Select(maker.Ident(builderVariableName), bfd.builderFieldName);
}
- JCFieldAccess fieldInThis = maker.Select(maker.Ident(typeNode.toName("this")), bfd.rawName);
+ JCFieldAccess fieldInThis = maker.Select(maker.Ident(job.toName("this")), bfd.rawName);
JCStatement assign = maker.Exec(maker.Assign(fieldInThis, rhs));
// In case of @Builder.Default, set the value to the default if it was not set in the builder.
if (bfd.nameOfSetFlag != null) {
JCFieldAccess setField = maker.Select(maker.Ident(builderVariableName), bfd.nameOfSetFlag);
- fieldInThis = maker.Select(maker.Ident(typeNode.toName("this")), bfd.rawName);
- JCExpression parentTypeRef = namePlusTypeParamsToTypeReference(maker, typeNode, List.<JCTypeParameter>nil());
- JCAssign assignDefault = maker.Assign(fieldInThis, maker.Apply(typeParameterNames(maker, ((JCClassDecl) typeNode.get()).typarams), maker.Select(parentTypeRef, bfd.nameOfDefaultProvider), List.<JCExpression>nil()));
+ fieldInThis = maker.Select(maker.Ident(job.toName("this")), bfd.rawName);
+ JCExpression parentTypeRef = namePlusTypeParamsToTypeReference(maker, job.parentType, List.<JCTypeParameter>nil());
+ JCAssign assignDefault = maker.Assign(fieldInThis, maker.Apply(typeParameterNames(maker, ((JCClassDecl) job.parentType.get()).typarams), maker.Select(parentTypeRef, bfd.nameOfDefaultProvider), List.<JCExpression>nil()));
statements.append(maker.If(setField, assign, maker.Exec(assignDefault)));
} else {
statements.append(assign);
}
if (hasNonNullAnnotations(bfd.originalFieldNode)) {
- JCStatement nullCheck = generateNullCheck(maker, bfd.originalFieldNode, source);
+ JCStatement nullCheck = generateNullCheck(maker, bfd.originalFieldNode, job.sourceNode);
if (nullCheck != null) statements.append(nullCheck);
}
}
- List<JCAnnotation> annsOnMethod = cfv.generateUnique() ? List.of(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
+ List<JCAnnotation> annsOnMethod = job.checkerFramework.generateUnique() ? List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
JCModifiers mods = maker.Modifiers(toJavacModifier(level), annsOnMethod);
// Create a constructor that has just the builder as parameter.
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
- long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
- Name builderClassname = typeNode.toName(builderClassName);
+ long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, job.getContext());
// First add all generics that are present on the parent type.
- ListBuffer<JCExpression> typeParamsForBuilderParameter = getTypeParamExpressions(typeParams, maker, typeNode.getContext());
+ ListBuffer<JCExpression> typeParamsForBuilderParameter = getTypeParamExpressions(job.typeParams, maker, job.getContext());
// Now add the <?, ?>.
JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParamsForBuilderParameter.add(wildcard);
wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParamsForBuilderParameter.add(wildcard);
- JCTypeApply paramType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, typeNode, builderClassname, false, List.<JCTypeParameter>nil()), typeParamsForBuilderParameter.toList());
+ JCTypeApply paramType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, job.parentType, job.getBuilderClassName(), false, List.<JCTypeParameter>nil()), typeParamsForBuilderParameter.toList());
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags), builderVariableName, paramType, null);
params.append(param);
if (callBuilderBasedSuperConstructor) {
// The first statement must be the call to the super constructor.
JCMethodInvocation callToSuperConstructor = maker.Apply(List.<JCExpression>nil(),
- maker.Ident(typeNode.toName("super")),
+ maker.Ident(job.toName("super")),
List.<JCExpression>of(maker.Ident(builderVariableName)));
statements.prepend(maker.Exec(callToSuperConstructor));
}
- JCMethodDecl constr = recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("<init>"),
+ JCMethodDecl constr = recursiveSetGeneratedBy(maker.MethodDef(mods, job.toName("<init>"),
null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(),
- maker.Block(0L, statements.toList()), null), source.get(), typeNode.getContext());
+ maker.Block(0L, statements.toList()), null), job.source, job.getContext());
- injectMethod(typeNode, constr, null, Javac.createVoidType(typeNode.getSymbolTable(), CTC_VOID));
+ injectMethod(job.parentType, constr, null, Javac.createVoidType(job.builderType.getSymbolTable(), CTC_VOID));
}
- private JCMethodDecl generateBuilderMethod(CheckerFrameworkVersion cfv, String builderMethodName, String builderClassName, String builderImplClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams) {
- JavacTreeMaker maker = type.getTreeMaker();
+ private JCMethodDecl generateBuilderMethod(SuperBuilderJob job) {
+ JavacTreeMaker maker = job.getTreeMaker();
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
- for (JCTypeParameter typeParam : typeParams) typeArgs.append(maker.Ident(typeParam.name));
+ for (JCTypeParameter typeParam : job.typeParams) typeArgs.append(maker.Ident(typeParam.name));
- JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderImplClassName), false, typeParams), List.<JCExpression>nil(), null);
+ JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderImplClassName), false, job.typeParams), List.<JCExpression>nil(), null);
JCStatement statement = maker.Return(call);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
@@ -565,16 +603,16 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
// Add any type params of the annotated class to the return type.
ListBuffer<JCExpression> typeParameterNames = new ListBuffer<JCExpression>();
- typeParameterNames.addAll(typeParameterNames(maker, typeParams));
+ typeParameterNames.addAll(typeParameterNames(maker, job.typeParams));
// Now add the <?, ?>.
JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParameterNames.add(wildcard);
typeParameterNames.add(wildcard);
- JCTypeApply returnType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), false, List.<JCTypeParameter>nil()), typeParameterNames.toList());
+ JCTypeApply returnType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderAbstractClassName), false, List.<JCTypeParameter>nil()), typeParameterNames.toList());
- List<JCAnnotation> annsOnMethod = cfv.generateUnique() ? List.of(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
- JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), type.toName(builderMethodName), returnType, copyTypeParams(source, typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
- createRelevantNonNullAnnotation(type, methodDef);
+ List<JCAnnotation> annsOnMethod = job.checkerFramework.generateUnique() ? List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
+ JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), job.toName(job.builderMethodName), returnType, copyTypeParams(job.sourceNode, job.typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ createRelevantNonNullAnnotation(job.parentType, methodDef);
return methodDef;
}
@@ -586,15 +624,15 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
* }
* </pre>
*/
- private JCMethodDecl generateToBuilderMethod(CheckerFrameworkVersion cfv, String builderClassName, String builderImplClassName, JavacNode source, JavacNode type, List<JCTypeParameter> typeParams) {
- JavacTreeMaker maker = type.getTreeMaker();
+ private JCMethodDecl generateToBuilderMethod(SuperBuilderJob job) {
+ JavacTreeMaker maker = job.getTreeMaker();
ListBuffer<JCExpression> typeArgs = new ListBuffer<JCExpression>();
- for (JCTypeParameter typeParam : typeParams) typeArgs.append(maker.Ident(typeParam.name));
+ for (JCTypeParameter typeParam : job.typeParams) typeArgs.append(maker.Ident(typeParam.name));
- JCExpression newClass = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, type, type.toName(builderImplClassName), false, typeParams), List.<JCExpression>nil(), null);
- List<JCExpression> methodArgs = List.<JCExpression>of(maker.Ident(type.toName("this")));
- JCMethodInvocation invokeFillMethod = maker.Apply(List.<JCExpression>nil(), maker.Select(newClass, type.toName(FILL_VALUES_METHOD_NAME)), methodArgs);
+ JCExpression newClass = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderImplClassName), false, job.typeParams), List.<JCExpression>nil(), null);
+ List<JCExpression> methodArgs = List.<JCExpression>of(maker.Ident(job.toName("this")));
+ JCMethodInvocation invokeFillMethod = maker.Apply(List.<JCExpression>nil(), maker.Select(newClass, job.toName(FILL_VALUES_METHOD_NAME)), methodArgs);
JCStatement statement = maker.Return(invokeFillMethod);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
@@ -602,16 +640,16 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
// Add any type params of the annotated class to the return type.
ListBuffer<JCExpression> typeParameterNames = new ListBuffer<JCExpression>();
- typeParameterNames.addAll(typeParameterNames(maker, typeParams));
+ typeParameterNames.addAll(typeParameterNames(maker, job.typeParams));
// Now add the <?, ?>.
JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParameterNames.add(wildcard);
typeParameterNames.add(wildcard);
- JCTypeApply returnType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassName), false, List.<JCTypeParameter>nil()), typeParameterNames.toList());
+ JCTypeApply returnType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderAbstractClassName), false, List.<JCTypeParameter>nil()), typeParameterNames.toList());
- List<JCAnnotation> annsOnMethod = cfv.generateUnique() ? List.of(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
- JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), type.toName(TO_BUILDER_METHOD_NAME), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
- createRelevantNonNullAnnotation(type, methodDef);
+ List<JCAnnotation> annsOnMethod = job.checkerFramework.generateUnique() ? List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
+ JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), job.toName(TO_BUILDER_METHOD_NAME), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
+ createRelevantNonNullAnnotation(job.parentType, methodDef);
return methodDef;
}
@@ -621,43 +659,43 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
* <pre>
* protected B $fillValuesFrom(final C instance) {
* super.$fillValuesFrom(instance);
- * FoobarBuilderImpl.$fillValuesFromInstanceIntoBuilder(instance, this);
+ * FoobarBuilder.$fillValuesFromInstanceIntoBuilder(instance, this);
* return self();
* }
* </pre>
*/
- private JCMethodDecl generateFillValuesMethod(JavacNode type, boolean inherited, String builderGenericName, String classGenericName, String builderImplClassName) {
- JavacTreeMaker maker = type.getTreeMaker();
+ private JCMethodDecl generateFillValuesMethod(SuperBuilderJob job, boolean inherited, String builderGenericName, String classGenericName) {
+ JavacTreeMaker maker = job.getTreeMaker();
List<JCAnnotation> annotations = List.nil();
if (inherited) {
- JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(type, "Override"), List.<JCExpression>nil());
+ JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(job.builderType, "Override"), List.<JCExpression>nil());
annotations = List.of(overrideAnnotation);
}
JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED, annotations);
- Name name = type.toName(FILL_VALUES_METHOD_NAME);
- JCExpression returnType = maker.Ident(type.toName(builderGenericName));
+ Name name = job.toName(FILL_VALUES_METHOD_NAME);
+ JCExpression returnType = maker.Ident(job.toName(builderGenericName));
- JCExpression classGenericNameExpr = maker.Ident(type.toName(classGenericName));
- JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.LocalVarFlags), type.toName(INSTANCE_VARIABLE_NAME), classGenericNameExpr, null);
+ JCExpression classGenericNameExpr = maker.Ident(job.toName(classGenericName));
+ JCVariableDecl param = maker.VarDef(maker.Modifiers(Flags.PARAMETER | Flags.FINAL), job.toName(INSTANCE_VARIABLE_NAME), classGenericNameExpr, null);
ListBuffer<JCStatement> body = new ListBuffer<JCStatement>();
if (inherited) {
// Call super.
JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(),
- maker.Select(maker.Ident(type.toName("super")), name),
- List.<JCExpression>of(maker.Ident(type.toName(INSTANCE_VARIABLE_NAME))));
+ maker.Select(maker.Ident(job.toName("super")), name),
+ List.<JCExpression>of(maker.Ident(job.toName(INSTANCE_VARIABLE_NAME))));
body.append(maker.Exec(callToSuper));
}
// Call the builder implemention's helper method that actually fills the values from the instance.
- JCExpression ref = namePlusTypeParamsToTypeReference(maker, type, type.toName(builderImplClassName), false, List.<JCTypeParameter>nil());
+ JCExpression ref = namePlusTypeParamsToTypeReference(maker, job.parentType, job.getBuilderClassName(), false, List.<JCTypeParameter>nil());
JCMethodInvocation callStaticFillValuesMethod = maker.Apply(List.<JCExpression>nil(),
- maker.Select(ref, type.toName(STATIC_FILL_VALUES_METHOD_NAME)),
- List.<JCExpression>of(maker.Ident(type.toName(INSTANCE_VARIABLE_NAME)), maker.Ident(type.toName("this"))));
+ maker.Select(ref, job.toName(STATIC_FILL_VALUES_METHOD_NAME)),
+ List.<JCExpression>of(maker.Ident(job.toName(INSTANCE_VARIABLE_NAME)), maker.Ident(job.toName("this"))));
body.append(maker.Exec(callStaticFillValuesMethod));
- JCReturn returnStatement = maker.Return(maker.Apply(List.<JCExpression>nil(), maker.Ident(type.toName(SELF_METHOD)), List.<JCExpression>nil()));
+ JCReturn returnStatement = maker.Return(maker.Apply(List.<JCExpression>nil(), maker.Ident(job.toName(SELF_METHOD)), List.<JCExpression>nil()));
body.append(returnStatement);
JCBlock bodyBlock = maker.Block(0, body.toList());
@@ -674,40 +712,39 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
* b.field(instance.field);
* }
* </pre>
- * @param setterPrefix the prefix for setter methods
*/
- private JCMethodDecl generateStaticFillValuesMethod(JavacNode type, String builderClassname, List<JCTypeParameter> typeParams, java.util.List<BuilderFieldData> builderFields, String setterPrefix) {
- JavacTreeMaker maker = type.getTreeMaker();
+ private JCMethodDecl generateStaticFillValuesMethod(SuperBuilderJob job, String setterPrefix) {
+ JavacTreeMaker maker = job.getTreeMaker();
List<JCAnnotation> annotations = List.nil();
JCModifiers modifiers = maker.Modifiers(Flags.PRIVATE | Flags.STATIC, annotations);
- Name name = type.toName(STATIC_FILL_VALUES_METHOD_NAME);
+ Name name = job.toName(STATIC_FILL_VALUES_METHOD_NAME);
JCExpression returnType = maker.TypeIdent(CTC_VOID);
// 1st parameter: "Foobar instance"
- JCVariableDecl paramInstance = maker.VarDef(maker.Modifiers(Flags.LocalVarFlags), type.toName(INSTANCE_VARIABLE_NAME), cloneSelfType(type), null);
+ JCVariableDecl paramInstance = maker.VarDef(maker.Modifiers(Flags.PARAMETER | Flags.FINAL), job.toName(INSTANCE_VARIABLE_NAME), cloneSelfType(job.parentType), null);
// 2nd parameter: "FoobarBuilder<?, ?> b" (plus generics on the annotated type)
// First add all generics that are present on the parent type.
- ListBuffer<JCExpression> typeParamsForBuilderParameter = getTypeParamExpressions(typeParams, maker, type.getContext());
+ ListBuffer<JCExpression> typeParamsForBuilderParameter = getTypeParamExpressions(job.typeParams, maker, job.getContext());
// Now add the <?, ?>.
JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParamsForBuilderParameter.add(wildcard);
wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParamsForBuilderParameter.add(wildcard);
- JCTypeApply builderType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, type, type.toName(builderClassname), false, List.<JCTypeParameter>nil()), typeParamsForBuilderParameter.toList());
- JCVariableDecl paramBuilder = maker.VarDef(maker.Modifiers(Flags.LocalVarFlags), type.toName(BUILDER_VARIABLE_NAME), builderType, null);
-
+ JCTypeApply builderType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, job.parentType, job.getBuilderClassName(), false, List.<JCTypeParameter>nil()), typeParamsForBuilderParameter.toList());
+ JCVariableDecl paramBuilder = maker.VarDef(maker.Modifiers(Flags.PARAMETER | Flags.FINAL), job.toName(BUILDER_VARIABLE_NAME), builderType, null);
+
ListBuffer<JCStatement> body = new ListBuffer<JCStatement>();
// Call the builder's setter methods to fill the values from the instance.
- for (BuilderFieldData bfd : builderFields) {
- JCExpressionStatement exec = createSetterCallWithInstanceValue(bfd, type, maker, setterPrefix);
+ for (BuilderFieldData bfd : job.builderFields) {
+ JCExpressionStatement exec = createSetterCallWithInstanceValue(bfd, job.parentType, maker, setterPrefix);
body.append(exec);
}
JCBlock bodyBlock = maker.Block(0, body.toList());
-
- return maker.MethodDef(modifiers, name, returnType, copyTypeParams(type, typeParams), List.of(paramInstance, paramBuilder), List.<JCExpression>nil(), bodyBlock, null);
+
+ return maker.MethodDef(modifiers, name, returnType, copyTypeParams(job.builderType, job.typeParams), List.of(paramInstance, paramBuilder), List.<JCExpression>nil(), bodyBlock, null);
}
private JCExpressionStatement createSetterCallWithInstanceValue(BuilderFieldData bfd, JavacNode type, JavacTreeMaker maker, String setterPrefix) {
@@ -747,80 +784,91 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
return exec;
}
- private JCMethodDecl generateAbstractSelfMethod(CheckerFrameworkVersion cfv, JavacNode type, boolean override, String builderGenericName) {
- JavacTreeMaker maker = type.getTreeMaker();
+ private JCMethodDecl generateAbstractSelfMethod(SuperBuilderJob job, boolean override, String builderGenericName) {
+ JavacTreeMaker maker = job.getTreeMaker();
List<JCAnnotation> annotations = List.nil();
- JCAnnotation overrideAnnotation = override ? maker.Annotation(genJavaLangTypeRef(type, "Override"), List.<JCExpression>nil()) : null;
- JCAnnotation rrAnnotation = cfv.generateReturnsReceiver() ? maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()) : null;
- JCAnnotation sefAnnotation = cfv.generatePure() ? maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()) : null;
+ JCAnnotation overrideAnnotation = override ? maker.Annotation(genJavaLangTypeRef(job.builderType, "Override"), List.<JCExpression>nil()) : null;
+ JCAnnotation rrAnnotation = job.checkerFramework.generateReturnsReceiver() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()) : null;
+ JCAnnotation sefAnnotation = job.checkerFramework.generatePure() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()) : null;
if (sefAnnotation != null) annotations = annotations.prepend(sefAnnotation);
if (rrAnnotation != null) annotations = annotations.prepend(rrAnnotation);
if (overrideAnnotation != null) annotations = annotations.prepend(overrideAnnotation);
JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED | Flags.ABSTRACT, annotations);
- Name name = type.toName(SELF_METHOD);
- JCExpression returnType = maker.Ident(type.toName(builderGenericName));
+ Name name = job.toName(SELF_METHOD);
+ JCExpression returnType = maker.Ident(job.toName(builderGenericName));
return maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
}
- private JCMethodDecl generateSelfMethod(CheckerFrameworkVersion cfv, JavacNode builderImplType, List<JCTypeParameter> typeParams) {
- JavacTreeMaker maker = builderImplType.getTreeMaker();
+ private JCMethodDecl generateSelfMethod(SuperBuilderJob job) {
+ JavacTreeMaker maker = job.getTreeMaker();
- JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(builderImplType, "Override"), List.<JCExpression>nil());
- JCAnnotation rrAnnotation = cfv.generateReturnsReceiver() ? maker.Annotation(genTypeRef(builderImplType, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()) : null;
- JCAnnotation sefAnnotation = cfv.generatePure() ? maker.Annotation(genTypeRef(builderImplType, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()) : null;
+ JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(job.builderType, "Override"), List.<JCExpression>nil());
+ JCAnnotation rrAnnotation = job.checkerFramework.generateReturnsReceiver() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil()) : null;
+ JCAnnotation sefAnnotation = job.checkerFramework.generatePure() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()) : null;
List<JCAnnotation> annsOnMethod = List.nil();
if (sefAnnotation != null) annsOnMethod = annsOnMethod.prepend(sefAnnotation);
if (rrAnnotation != null) annsOnMethod = annsOnMethod.prepend(rrAnnotation);
annsOnMethod = annsOnMethod.prepend(overrideAnnotation);
JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED, annsOnMethod);
- Name name = builderImplType.toName(SELF_METHOD);
+ Name name = job.toName(SELF_METHOD);
- JCExpression returnType = namePlusTypeParamsToTypeReference(maker, builderImplType.up(), builderImplType.toName(builderImplType.getName()), false, typeParams);
- JCStatement statement = maker.Return(maker.Ident(builderImplType.toName("this")));
+ JCExpression returnType = namePlusTypeParamsToTypeReference(maker, job.builderType.up(), job.getBuilderClassName(), false, job.typeParams);
+ JCStatement statement = maker.Return(maker.Ident(job.toName("this")));
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
return maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
}
- private JCMethodDecl generateAbstractBuildMethod(CheckerFrameworkVersion cfv, JavacNode type, String methodName, java.util.List<BuilderFieldData> builderFields, boolean override, String classGenericName) {
- JavacTreeMaker maker = type.getTreeMaker();
+ private JCMethodDecl generateAbstractBuildMethod(SuperBuilderJob job, boolean override, String classGenericName) {
+ JavacTreeMaker maker = job.getTreeMaker();
List<JCAnnotation> annotations = List.nil();
if (override) {
- JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(type, "Override"), List.<JCExpression>nil());
+ JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(job.builderType, "Override"), List.<JCExpression>nil());
annotations = List.of(overrideAnnotation);
}
- if (cfv.generateSideEffectFree()) annotations = annotations.prepend(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
+ if (job.checkerFramework.generateSideEffectFree()) annotations = annotations.prepend(maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
JCModifiers modifiers = maker.Modifiers(Flags.PUBLIC | Flags.ABSTRACT, annotations);
- Name name = type.toName(methodName);
- JCExpression returnType = maker.Ident(type.toName(classGenericName));
+ Name name = job.toName(job.buildMethodName);
+ JCExpression returnType = maker.Ident(job.toName(classGenericName));
- List<JCVariableDecl> params = HandleBuilder.generateBuildArgs(cfv, type, builderFields);
- return maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), null, null);
+ JCVariableDecl recv = HandleBuilder.generateReceiver(job);
+ JCMethodDecl methodDef;
+ if (recv != null && maker.hasMethodDefWithRecvParam()) {
+ methodDef = maker.MethodDefWithRecvParam(modifiers, name, returnType, List.<JCTypeParameter>nil(), recv, List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
+ } else {
+ methodDef = maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
+ }
+ return methodDef;
}
-
- private JCMethodDecl generateBuildMethod(CheckerFrameworkVersion cfv, String buildName, JavacNode returnType, JavacNode type, java.util.List<BuilderFieldData> builderFields, List<JCExpression> thrownExceptions) {
- JavacTreeMaker maker = type.getTreeMaker();
+
+ private JCMethodDecl generateBuildMethod(SuperBuilderJob job, List<JCExpression> thrownExceptions) {
+ JavacTreeMaker maker = job.getTreeMaker();
JCExpression call;
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
// Use a constructor that only has this builder as parameter.
- List<JCExpression> builderArg = List.<JCExpression>of(maker.Ident(type.toName("this")));
- call = maker.NewClass(null, List.<JCExpression>nil(), cloneSelfType(returnType), builderArg, null);
+ List<JCExpression> builderArg = List.<JCExpression>of(maker.Ident(job.toName("this")));
+ call = maker.NewClass(null, List.<JCExpression>nil(), cloneSelfType(job.parentType), builderArg, null);
statements.append(maker.Return(call));
JCBlock body = maker.Block(0, statements.toList());
- JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(type, "Override"), List.<JCExpression>nil());
+ JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(job.builderType, "Override"), List.<JCExpression>nil());
List<JCAnnotation> annsOnMethod = List.of(overrideAnnotation);
- if (cfv.generateSideEffectFree()) annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(type, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
+ if (job.checkerFramework.generateSideEffectFree()) annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
JCModifiers modifiers = maker.Modifiers(Flags.PUBLIC, annsOnMethod);
- List<JCVariableDecl> params = HandleBuilder.generateBuildArgs(cfv, type, builderFields);
- JCMethodDecl methodDef = maker.MethodDef(modifiers, type.toName(buildName), cloneSelfType(returnType), List.<JCTypeParameter>nil(), params, thrownExceptions, body, null);
- createRelevantNonNullAnnotation(type, methodDef);
+ JCVariableDecl recv = HandleBuilder.generateReceiver(job);
+ JCMethodDecl methodDef;
+ if (recv != null && maker.hasMethodDefWithRecvParam()) {
+ methodDef = maker.MethodDefWithRecvParam(modifiers, job.toName(job.buildMethodName), cloneSelfType(job.parentType), List.<JCTypeParameter>nil(), recv, List.<JCVariableDecl>nil(), thrownExceptions, body, null);
+ } else {
+ methodDef = maker.MethodDef(modifiers, job.toName(job.buildMethodName), cloneSelfType(job.parentType), List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), thrownExceptions, body, null);
+ }
+ createRelevantNonNullAnnotation(job.builderType, methodDef);
return methodDef;
}
@@ -878,29 +926,30 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
for (JCVariableDecl gen : generated) recursiveSetGeneratedBy(gen, source, builderType.getContext());
}
- private void generateSetterMethodsForBuilder(CheckerFrameworkVersion cfv, final JavacNode builderType, BuilderFieldData fieldNode, JavacNode source, final String builderGenericName, String setterPrefix) {
+ private void generateSetterMethodsForBuilder(final SuperBuilderJob job, BuilderFieldData fieldNode, final String builderGenericName, String setterPrefix) {
boolean deprecate = isFieldDeprecated(fieldNode.originalFieldNode);
- final JavacTreeMaker maker = builderType.getTreeMaker();
+ final JavacTreeMaker maker = job.getTreeMaker();
ExpressionMaker returnTypeMaker = new ExpressionMaker() { @Override public JCExpression make() {
- return maker.Ident(builderType.toName(builderGenericName));
+ return maker.Ident(job.toName(builderGenericName));
}};
StatementMaker returnStatementMaker = new StatementMaker() { @Override public JCStatement make() {
- return maker.Return(maker.Apply(List.<JCExpression>nil(), maker.Ident(builderType.toName(SELF_METHOD)), List.<JCExpression>nil()));
+ return maker.Return(maker.Apply(List.<JCExpression>nil(), maker.Ident(job.toName(SELF_METHOD)), List.<JCExpression>nil()));
}};
if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
- generateSimpleSetterMethodForBuilder(cfv, builderType, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, source, returnTypeMaker.make(), returnStatementMaker.make(), fieldNode.annotations, fieldNode.originalFieldNode, setterPrefix);
+ generateSimpleSetterMethodForBuilder(job, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, returnTypeMaker.make(), returnStatementMaker.make(), fieldNode.annotations, fieldNode.originalFieldNode, setterPrefix);
} else {
- fieldNode.singularData.getSingularizer().generateMethods(cfv, fieldNode.singularData, deprecate, builderType, source.get(), true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
+ fieldNode.singularData.getSingularizer().generateMethods(job.checkerFramework, fieldNode.singularData, deprecate, job.builderType,
+ job.source, true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
}
}
- private void generateSimpleSetterMethodForBuilder(CheckerFrameworkVersion cfv, JavacNode builderType, boolean deprecate, JavacNode fieldNode, Name paramName, Name nameOfSetFlag, JavacNode source, JCExpression returnType, JCStatement returnStatement, List<JCAnnotation> annosOnParam, JavacNode originalFieldNode, String setterPrefix) {
+ private void generateSimpleSetterMethodForBuilder(SuperBuilderJob job, boolean deprecate, JavacNode fieldNode, Name paramName, Name nameOfSetFlag, JCExpression returnType, JCStatement returnStatement, List<JCAnnotation> annosOnParam, JavacNode originalFieldNode, String setterPrefix) {
String setterName = HandlerUtil.buildAccessorName(setterPrefix, paramName.toString());
- Name setterName_ = builderType.toName(setterName);
+ Name setterName_ = job.builderType.toName(setterName);
- for (JavacNode child : builderType.down()) {
+ for (JavacNode child : job.builderType.down()) {
if (child.getKind() != Kind.METHOD) continue;
JCMethodDecl methodDecl = (JCMethodDecl) child.get();
Name existingName = methodDecl.name;
@@ -910,23 +959,24 @@ public class HandleSuperBuilder extends JavacAnnotationHandler<SuperBuilder> {
JavacTreeMaker maker = fieldNode.getTreeMaker();
List<JCAnnotation> methodAnns = JavacHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode);
- JCMethodDecl newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, source, methodAnns, annosOnParam);
- if (cfv.generateCalledMethods()) {
- JCAnnotation ncAnno = maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__NOT_CALLED), List.<JCExpression>of(maker.Literal(newMethod.getName().toString())));
- JCClassDecl builderTypeNode = (JCClassDecl) builderType.get();
- JCExpression selfType = namePlusTypeParamsToTypeReference(maker, builderType, builderTypeNode.typarams);
- JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>of(ncAnno)), builderType.toName("this"), selfType, null);
- newMethod.params = List.of(recv, newMethod.params.get(0));
+ JCMethodDecl newMethod = null;
+ if (job.checkerFramework.generateCalledMethods() && maker.hasMethodDefWithRecvParam()) {
+ JCAnnotation ncAnno = maker.Annotation(genTypeRef(job.sourceNode, CheckerFrameworkVersion.NAME__NOT_CALLED), List.<JCExpression>of(maker.Literal(setterName.toString())));
+ JCClassDecl builderTypeNode = (JCClassDecl) job.builderType.get();
+ JCExpression selfType = namePlusTypeParamsToTypeReference(maker, job.builderType, builderTypeNode.typarams, List.<JCAnnotation>of(ncAnno));
+ JCVariableDecl recv = maker.VarDef(maker.Modifiers(0L, List.<JCAnnotation>nil()), job.toName("this"), selfType, null);
+ newMethod = HandleSetter.createSetterWithRecv(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, job.sourceNode, methodAnns, annosOnParam, recv);
}
- if (cfv.generateReturnsReceiver()) {
+ if (newMethod == null) newMethod = HandleSetter.createSetter(Flags.PUBLIC, deprecate, fieldNode, maker, setterName, paramName, nameOfSetFlag, returnType, returnStatement, job.sourceNode, methodAnns, annosOnParam);
+ if (job.checkerFramework.generateReturnsReceiver()) {
List<JCAnnotation> annotations = newMethod.mods.annotations;
if (annotations == null) annotations = List.nil();
- JCAnnotation anno = maker.Annotation(genTypeRef(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil());
- recursiveSetGeneratedBy(anno, source.get(), builderType.getContext());
+ JCAnnotation anno = maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER), List.<JCExpression>nil());
+ recursiveSetGeneratedBy(anno, job.source, job.getContext());
newMethod.mods.annotations = annotations.prepend(anno);
}
- injectMethod(builderType, newMethod);
+ injectMethod(job.builderType, newMethod);
}
private void addObtainVia(BuilderFieldData bfd, JavacNode node) {
diff --git a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
index 7cd52c8c..2fc9329c 100644
--- a/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
+++ b/src/core/lombok/javac/handlers/JavacSingularsRecipes.java
@@ -57,6 +57,7 @@ import lombok.core.configuration.CheckerFrameworkVersion;
import lombok.core.handlers.HandlerUtil;
import lombok.javac.JavacNode;
import lombok.javac.JavacTreeMaker;
+import lombok.javac.handlers.HandleBuilder.BuilderJob;
public class JavacSingularsRecipes {
public interface ExpressionMaker {
@@ -243,20 +244,22 @@ public class JavacSingularsRecipes {
* If you need more control over the return type and value, use
* {@link #generateMethods(SingularData, boolean, JavacNode, JCTree, boolean, ExpressionMaker, StatementMaker)}.
*/
- public void generateMethods(CheckerFrameworkVersion cfv, SingularData data, boolean deprecate, final JavacNode builderType, JCTree source, boolean fluent, final boolean chain, AccessLevel access) {
- final JavacTreeMaker maker = builderType.getTreeMaker();
+ public void generateMethods(final BuilderJob job, SingularData data, boolean deprecate) {
+ //job.checkerFramework, job.builderType, job.source, job.oldFluent, job.oldChain, job.accessInners
+ //CheckerFrameworkVersion cfv, final JavacNode builderType, JCTree source, boolean fluent, final boolean chain, AccessLevel access) {
+ final JavacTreeMaker maker = job.builderType.getTreeMaker();
ExpressionMaker returnTypeMaker = new ExpressionMaker() { @Override public JCExpression make() {
- return chain ?
- cloneSelfType(builderType) :
- maker.Type(createVoidType(builderType.getSymbolTable(), CTC_VOID));
+ return job.oldChain ?
+ cloneSelfType(job.builderType) :
+ maker.Type(createVoidType(job.builderType.getSymbolTable(), CTC_VOID));
}};
StatementMaker returnStatementMaker = new StatementMaker() { @Override public JCStatement make() {
- return chain ? maker.Return(maker.Ident(builderType.toName("this"))) : null;
+ return job.oldChain ? maker.Return(maker.Ident(job.builderType.toName("this"))) : null;
}};
- generateMethods(cfv, data, deprecate, builderType, source, fluent, returnTypeMaker, returnStatementMaker, access);
+ generateMethods(job.checkerFramework, data, deprecate, job.builderType, job.source, job.oldFluent, returnTypeMaker, returnStatementMaker, job.accessInners);
}
/**
diff --git a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
index 7cd676c0..dadf881d 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacGuavaSingularizer.java
@@ -151,7 +151,7 @@ abstract class JavacGuavaSingularizer extends JavacSingularizer {
JCExpression init = maker.Conditional(isNull, empty, invokeBuild); // this.pluralName == null ? ImmutableX.of() : this.pluralName.build()
- JCStatement jcs = maker.VarDef(maker.Modifiers(0), data.getPluralName(), varType, init);
+ JCStatement jcs = maker.VarDef(maker.Modifiers(0L), data.getPluralName(), varType, init);
statements.append(jcs);
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java
index b4ad3428..1f8bbbe9 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilListSingularizer.java
@@ -89,7 +89,7 @@ public class JavacJavaUtilListSingularizer extends JavacJavaUtilListSetSingulari
JCStatement switchStat = maker.Switch(getSize(maker, builderType, data.getPluralName(), true, false, builderVariable), cases.toList());
JCExpression localShadowerType = chainDotsString(builderType, data.getTargetFqn());
localShadowerType = addTypeArgs(1, false, builderType, localShadowerType, data.getTypeArgs(), source);
- JCStatement varDefStat = maker.VarDef(maker.Modifiers(0), data.getPluralName(), localShadowerType, null);
+ JCStatement varDefStat = maker.VarDef(maker.Modifiers(0L), data.getPluralName(), localShadowerType, null);
statements.append(varDefStat);
statements.append(switchStat);
}
diff --git a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java
index 50950915..5670b5e6 100644
--- a/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java
+++ b/src/core/lombok/javac/handlers/singulars/JavacJavaUtilSingularizer.java
@@ -84,7 +84,7 @@ abstract class JavacJavaUtilSingularizer extends JavacSingularizer {
JCStatement switchStat = maker.Switch(getSize(maker, builderType, mapMode ? builderType.toName(data.getPluralName() + "$key") : data.getPluralName(), true, false, builderVariable), cases.toList());
JCExpression localShadowerType = chainDotsString(builderType, data.getTargetFqn());
localShadowerType = addTypeArgs(mapMode ? 2 : 1, false, builderType, localShadowerType, data.getTypeArgs(), source);
- JCStatement varDefStat = maker.VarDef(maker.Modifiers(0), data.getPluralName(), localShadowerType, null);
+ JCStatement varDefStat = maker.VarDef(maker.Modifiers(0L), data.getPluralName(), localShadowerType, null);
return List.of(varDefStat, switchStat);
}
@@ -143,7 +143,7 @@ abstract class JavacJavaUtilSingularizer extends JavacSingularizer {
if (defineVar) {
JCExpression localShadowerType = chainDotsString(builderType, data.getTargetFqn());
localShadowerType = addTypeArgs(mapMode ? 2 : 1, false, builderType, localShadowerType, data.getTypeArgs(), source);
- createStat = maker.VarDef(maker.Modifiers(0), data.getPluralName(), localShadowerType, constructorCall);
+ createStat = maker.VarDef(maker.Modifiers(0L), data.getPluralName(), localShadowerType, constructorCall);
} else {
createStat = maker.Exec(maker.Assign(maker.Ident(data.getPluralName()), constructorCall));
}
@@ -161,7 +161,7 @@ abstract class JavacJavaUtilSingularizer extends JavacSingularizer {
// error: method put in interface Map<K#2,V#2> cannot be applied to given types;
arg2 = maker.TypeCast(createTypeArgs(2, false, builderType, data.getTypeArgs(), source).get(1), arg2);
JCStatement putStatement = maker.Exec(maker.Apply(jceBlank, pluralnameDotPut, List.of(arg1, arg2)));
- JCStatement forInit = maker.VarDef(maker.Modifiers(0), ivar, maker.TypeIdent(CTC_INT), maker.Literal(CTC_INT, 0));
+ JCStatement forInit = maker.VarDef(maker.Modifiers(0L), ivar, maker.TypeIdent(CTC_INT), maker.Literal(CTC_INT, 0));
JCExpression checkExpr = maker.Binary(CTC_LESS_THAN, maker.Ident(ivar), getSize(maker, builderType, keyVarName, nullGuard, true, builderVariable));
JCExpression incrementExpr = maker.Unary(CTC_POSTINC, maker.Ident(ivar));
fillStat = maker.ForLoop(List.of(forInit), checkExpr, List.of(maker.Exec(incrementExpr)), putStatement);