mirror of
https://github.com/tiennm99/lombok.git
synced 2026-10-14 04:16:19 +00:00
[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.
This commit is contained in:
27 files changed
+1161
-997
No files matched your search
@@ -106,8 +106,16 @@ import lombok.experimental.NonFinal;
|
||||
public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
private HandleConstructor handleConstructor = new HandleConstructor();
|
||||
|
||||
private static final char[] CLEAN_FIELD_NAME = "$lombokUnclean".toCharArray();
|
||||
private static final char[] CLEAN_METHOD_NAME = "$lombokClean".toCharArray();
|
||||
static final char[] CLEAN_FIELD_NAME = "$lombokUnclean".toCharArray();
|
||||
static final char[] CLEAN_METHOD_NAME = "$lombokClean".toCharArray();
|
||||
static final String TO_BUILDER_METHOD_NAME_STRING = "toBuilder";
|
||||
static final char[] TO_BUILDER_METHOD_NAME = TO_BUILDER_METHOD_NAME_STRING.toCharArray();
|
||||
static final char[] DEFAULT_PREFIX = {'$', 'd', 'e', 'f', 'a', 'u', 'l', 't', '$'};
|
||||
static final char[] SET_PREFIX = {'$', 's', 'e', 't'};
|
||||
static final char[] VALUE_PREFIX = {'$', 'v', 'a', 'l', 'u', 'e'};
|
||||
static final char[] BUILDER_TEMP_VAR = {'b', 'u', 'i', 'l', 'd', 'e', 'r'};
|
||||
static final AbstractMethodDeclaration[] EMPTY_METHODS = {};
|
||||
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;
|
||||
@@ -118,22 +126,28 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
|
||||
static class BuilderJob {
|
||||
CheckerFrameworkVersion checkerFramework;
|
||||
EclipseNode builderTypeParent, builderType;
|
||||
String builderClassName, builderMethodName, buildMethodName, toBuilderMethodName;
|
||||
EclipseNode parentType;
|
||||
String builderMethodName, buildMethodName;
|
||||
boolean isStatic;
|
||||
TypeParameter[] typeParams;
|
||||
TypeParameter[] builderTypeParams;
|
||||
ASTNode source;
|
||||
EclipseNode sourceNode;
|
||||
List<BuilderFieldData> builderFields;
|
||||
AccessLevel accessInners, accessOuters;
|
||||
boolean oldFluent, oldChain, toBuilder;
|
||||
|
||||
TypeParameter[] copyTypeParams() {
|
||||
return EclipseHandlerUtil.copyTypeParams(typeParams, source);
|
||||
EclipseNode builderType;
|
||||
String builderClassName;
|
||||
char[] builderClassNameArr;
|
||||
|
||||
void setBuilderClassName(String builderClassName) {
|
||||
this.builderClassName = builderClassName;
|
||||
this.builderClassNameArr = builderClassName.toCharArray();
|
||||
}
|
||||
|
||||
char[] getBuilderClassName() {
|
||||
return builderClassName.toCharArray();
|
||||
TypeParameter[] copyTypeParams() {
|
||||
return EclipseHandlerUtil.copyTypeParams(typeParams, source);
|
||||
}
|
||||
|
||||
long getPos() {
|
||||
@@ -141,22 +155,22 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
public TypeReference createBuilderTypeReference() {
|
||||
return namePlusTypeParamsToTypeReference(builderTypeParent, getBuilderClassName(), !isStatic, typeParams, getPos());
|
||||
return namePlusTypeParamsToTypeReference(parentType, builderClassNameArr, !isStatic, builderTypeParams, getPos());
|
||||
}
|
||||
|
||||
public TypeReference createBuilderTypeReferenceForceStatic() {
|
||||
return namePlusTypeParamsToTypeReference(builderTypeParent, getBuilderClassName(), false, typeParams, getPos());
|
||||
return namePlusTypeParamsToTypeReference(parentType, builderClassNameArr, false, builderTypeParams, getPos());
|
||||
}
|
||||
|
||||
public TypeReference createBuilderParentTypeReference() {
|
||||
return namePlusTypeParamsToTypeReference(builderTypeParent, typeParams, getPos());
|
||||
return namePlusTypeParamsToTypeReference(parentType, typeParams, getPos());
|
||||
}
|
||||
|
||||
public EclipseNode getTopNode() {
|
||||
return builderTypeParent.top();
|
||||
return parentType.top();
|
||||
}
|
||||
|
||||
public void init(AnnotationValues<Builder> node, Builder ann) {
|
||||
void init(AnnotationValues<Builder> annValues, Builder ann, EclipseNode node) {
|
||||
accessOuters = ann.access();
|
||||
if (accessOuters == null) accessOuters = AccessLevel.PUBLIC;
|
||||
if (accessOuters == AccessLevel.NONE) {
|
||||
@@ -166,23 +180,37 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
accessInners = accessOuters == AccessLevel.PROTECTED ? AccessLevel.PUBLIC : accessOuters;
|
||||
|
||||
// These exist just to support the 'old' lombok.experimental.Builder, which had these properties. lombok.Builder no longer has them.
|
||||
oldFluent = toBoolean(node.getActualExpression("fluent"), true);
|
||||
oldChain = toBoolean(node.getActualExpression("chain"), true);
|
||||
oldFluent = toBoolean(annValues.getActualExpression("fluent"), true);
|
||||
oldChain = toBoolean(annValues.getActualExpression("chain"), true);
|
||||
|
||||
builderMethodName = ann.builderMethodName();
|
||||
buildMethodName = ann.buildMethodName();
|
||||
builderClassName = ann.builderClassName();
|
||||
toBuilderMethodName = "toBuilder";
|
||||
setBuilderClassName(fixBuilderClassName(node, ann.builderClassName()));
|
||||
toBuilder = ann.toBuilder();
|
||||
|
||||
if (builderMethodName == null) builderMethodName = "builder";
|
||||
if (buildMethodName == null) buildMethodName = "build";
|
||||
if (builderClassName == null) builderClassName = "";
|
||||
}
|
||||
|
||||
public MethodDeclaration createNewMethodDeclaration() {
|
||||
static String fixBuilderClassName(EclipseNode 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";
|
||||
}
|
||||
|
||||
MethodDeclaration createNewMethodDeclaration() {
|
||||
return new MethodDeclaration(((CompilationUnitDeclaration) getTopNode().get()).compilationResult);
|
||||
}
|
||||
|
||||
String replaceBuilderClassName(char[] name) {
|
||||
if (builderClassName.indexOf('*') == -1) return builderClassName;
|
||||
return builderClassName.replace("*", new String(name));
|
||||
}
|
||||
|
||||
String replaceBuilderClassName(String name) {
|
||||
return builderClassName.replace("*", name);
|
||||
}
|
||||
}
|
||||
|
||||
static class BuilderFieldData {
|
||||
@@ -219,10 +247,6 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static final char[] DEFAULT_PREFIX = {'$', 'd', 'e', 'f', 'a', 'u', 'l', 't', '$'};
|
||||
private static final char[] SET_PREFIX = {'$', 's', 'e', 't'};
|
||||
private static final char[] VALUE_PREFIX = {'$', 'v', 'a', 'l', 'u', 'e'};
|
||||
|
||||
private static final char[] prefixWith(char[] prefix, char[] name) {
|
||||
char[] out = new char[prefix.length + name.length];
|
||||
System.arraycopy(prefix, 0, out, 0, prefix.length);
|
||||
@@ -236,9 +260,10 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
job.sourceNode = annotationNode;
|
||||
job.source = ast;
|
||||
job.checkerFramework = getCheckerFrameworkVersion(annotationNode);
|
||||
job.isStatic = true;
|
||||
|
||||
Builder annInstance = annotation.getInstance();
|
||||
job.init(annotation, annInstance);
|
||||
job.init(annotation, annInstance, annotationNode);
|
||||
List<char[]> typeArgsForToBuilder = null;
|
||||
|
||||
boolean generateBuilderMethod;
|
||||
@@ -251,45 +276,35 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
if (!checkName("buildMethodName", job.buildMethodName, annotationNode)) return;
|
||||
if (!job.builderClassName.isEmpty()) {
|
||||
if (!checkName("builderClassName", job.builderClassName, annotationNode)) return;
|
||||
}
|
||||
|
||||
EclipseNode parent = annotationNode.up();
|
||||
|
||||
job.builderFields = new ArrayList<BuilderFieldData>();
|
||||
TypeReference buildMethodReturnType;
|
||||
TypeReference[] buildMethodThrownExceptions;
|
||||
char[] nameOfStaticBuilderMethod;
|
||||
char[] nameOfBuilderMethod;
|
||||
|
||||
EclipseNode fillParametersFrom = parent.get() instanceof AbstractMethodDeclaration ? parent : null;
|
||||
boolean addCleaning = false;
|
||||
job.isStatic = true;
|
||||
|
||||
List<EclipseNode> nonFinalNonDefaultedFields = null;
|
||||
|
||||
if (job.builderClassName.isEmpty()) job.builderClassName = annotationNode.getAst().readConfiguration(ConfigurationKeys.BUILDER_CLASS_NAME);
|
||||
if (job.builderClassName == null || job.builderClassName.isEmpty()) job.builderClassName = "*Builder";
|
||||
boolean replaceNameInBuilderClassName = job.builderClassName.contains("*");
|
||||
|
||||
if (parent.get() instanceof TypeDeclaration) {
|
||||
job.builderTypeParent = parent;
|
||||
TypeDeclaration td = (TypeDeclaration) job.builderTypeParent.get();
|
||||
job.parentType = parent;
|
||||
TypeDeclaration td = (TypeDeclaration) parent.get();
|
||||
|
||||
List<EclipseNode> allFields = new ArrayList<EclipseNode>();
|
||||
boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation("lombok.experimental.Value", parent));
|
||||
for (EclipseNode fieldNode : HandleConstructor.findAllFields(job.builderTypeParent, true)) {
|
||||
for (EclipseNode fieldNode : HandleConstructor.findAllFields(parent, true)) {
|
||||
FieldDeclaration fd = (FieldDeclaration) fieldNode.get();
|
||||
EclipseNode isDefault = findAnnotation(Builder.Default.class, fieldNode);
|
||||
boolean isFinal = ((fd.modifiers & ClassFileConstants.AccFinal) != 0) || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode));
|
||||
|
||||
Annotation[] copyableAnnotations = findCopyableAnnotations(fieldNode);
|
||||
|
||||
BuilderFieldData bfd = new BuilderFieldData();
|
||||
bfd.rawName = fieldNode.getName().toCharArray();
|
||||
bfd.name = removePrefixFromField(fieldNode);
|
||||
bfd.builderFieldName = bfd.name;
|
||||
bfd.annotations = copyAnnotations(fd, copyableAnnotations);
|
||||
bfd.annotations = copyAnnotations(fd, findCopyableAnnotations(fieldNode));
|
||||
bfd.type = fd.type;
|
||||
bfd.singularData = getSingularData(fieldNode, ast, annInstance.setterPrefix());
|
||||
bfd.originalFieldNode = fieldNode;
|
||||
@@ -316,22 +331,22 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
bfd.builderFieldName = prefixWith(bfd.name, VALUE_PREFIX);
|
||||
|
||||
MethodDeclaration md = generateDefaultProvider(bfd.nameOfDefaultProvider, td.typeParameters, fieldNode, ast);
|
||||
if (md != null) injectMethod(job.builderTypeParent, md);
|
||||
if (md != null) injectMethod(parent, md);
|
||||
}
|
||||
addObtainVia(bfd, fieldNode);
|
||||
job.builderFields.add(bfd);
|
||||
allFields.add(fieldNode);
|
||||
}
|
||||
|
||||
handleConstructor.generateConstructor(job.builderTypeParent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER,
|
||||
handleConstructor.generateConstructor(parent, AccessLevel.PACKAGE, allFields, false, null, SkipIfConstructorExists.I_AM_BUILDER,
|
||||
Collections.<Annotation>emptyList(), annotationNode);
|
||||
|
||||
job.typeParams = td.typeParameters;
|
||||
job.typeParams = job.builderTypeParams = td.typeParameters;
|
||||
buildMethodReturnType = job.createBuilderParentTypeReference();
|
||||
buildMethodThrownExceptions = null;
|
||||
nameOfStaticBuilderMethod = null;
|
||||
if (replaceNameInBuilderClassName) job.builderClassName = job.builderClassName.replace("*", new String(td.name));
|
||||
replaceNameInBuilderClassName = false;
|
||||
nameOfBuilderMethod = null;
|
||||
job.setBuilderClassName(job.replaceBuilderClassName(td.name));
|
||||
if (!checkName("builderClassName", job.builderClassName, annotationNode)) return;
|
||||
} else if (parent.get() instanceof ConstructorDeclaration) {
|
||||
ConstructorDeclaration cd = (ConstructorDeclaration) parent.get();
|
||||
if (cd.typeParameters != null && cd.typeParameters.length > 0) {
|
||||
@@ -339,21 +354,20 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
return;
|
||||
}
|
||||
|
||||
job.builderTypeParent = parent.up();
|
||||
TypeDeclaration td = (TypeDeclaration) job.builderTypeParent.get();
|
||||
job.typeParams = td.typeParameters;
|
||||
job.parentType = parent.up();
|
||||
TypeDeclaration td = (TypeDeclaration) job.parentType.get();
|
||||
job.typeParams = job.builderTypeParams = td.typeParameters;
|
||||
buildMethodReturnType = job.createBuilderParentTypeReference();
|
||||
buildMethodThrownExceptions = cd.thrownExceptions;
|
||||
nameOfStaticBuilderMethod = null;
|
||||
if (replaceNameInBuilderClassName) job.builderClassName = job.builderClassName.replace("*", new String(cd.selector));
|
||||
replaceNameInBuilderClassName = false;
|
||||
nameOfBuilderMethod = null;
|
||||
job.setBuilderClassName(job.replaceBuilderClassName(cd.selector));
|
||||
if (!checkName("builderClassName", job.builderClassName, annotationNode)) return;
|
||||
} else if (parent.get() instanceof MethodDeclaration) {
|
||||
MethodDeclaration md = (MethodDeclaration) parent.get();
|
||||
job.builderTypeParent = parent.up();
|
||||
job.parentType = parent.up();
|
||||
job.isStatic = md.isStatic();
|
||||
|
||||
if (job.toBuilder) {
|
||||
final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
|
||||
char[] token;
|
||||
char[][] pkg = null;
|
||||
if (md.returnType.dimensions() > 0) {
|
||||
@@ -379,12 +393,12 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
return;
|
||||
}
|
||||
|
||||
if (job.builderTypeParent == null || !equals(job.builderTypeParent.getName(), token)) {
|
||||
if (job.parentType == null || !equals(job.parentType.getName(), token)) {
|
||||
annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
TypeParameter[] tpOnType = ((TypeDeclaration) job.builderTypeParent.get()).typeParameters;
|
||||
TypeParameter[] tpOnType = ((TypeDeclaration) job.parentType.get()).typeParameters;
|
||||
TypeParameter[] tpOnMethod = md.typeParameters;
|
||||
TypeReference[][] tpOnRet_ = null;
|
||||
if (md.returnType instanceof ParameterizedSingleTypeReference) {
|
||||
@@ -423,15 +437,15 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
}
|
||||
|
||||
job.typeParams = md.typeParameters;
|
||||
job.typeParams = job.builderTypeParams = md.typeParameters;
|
||||
buildMethodReturnType = copyType(md.returnType, ast);
|
||||
buildMethodThrownExceptions = md.thrownExceptions;
|
||||
nameOfStaticBuilderMethod = md.selector;
|
||||
if (replaceNameInBuilderClassName) {
|
||||
nameOfBuilderMethod = md.selector;
|
||||
if (job.builderClassName.indexOf('*') > -1) {
|
||||
char[] token = returnTypeToBuilderClassName(annotationNode, md, job.typeParams);
|
||||
if (token == null)
|
||||
return;
|
||||
job.builderClassName = job.builderClassName.replace("*", new String(token));
|
||||
if (token == null) return; // should not happen.
|
||||
job.setBuilderClassName(job.replaceBuilderClassName(token));
|
||||
if (!checkName("builderClassName", job.builderClassName, annotationNode)) return;
|
||||
}
|
||||
} else {
|
||||
annotationNode.addError("@Builder is only supported on types, constructors, and methods.");
|
||||
@@ -458,7 +472,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
}
|
||||
|
||||
job.builderType = findInnerClass(job.builderTypeParent, job.builderClassName);
|
||||
job.builderType = findInnerClass(job.parentType, job.builderClassName);
|
||||
if (job.builderType == null) makeBuilderClass(job);
|
||||
else {
|
||||
TypeDeclaration builderTypeDeclaration = (TypeDeclaration) job.builderType.get();
|
||||
@@ -527,7 +541,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
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) {
|
||||
MethodDeclaration md = generateBuildMethod(job, nameOfStaticBuilderMethod, buildMethodReturnType, buildMethodThrownExceptions, addCleaning);
|
||||
MethodDeclaration md = generateBuildMethod(job, nameOfBuilderMethod, buildMethodReturnType, buildMethodThrownExceptions, addCleaning);
|
||||
if (md != null) injectMethod(job.builderType, md);
|
||||
}
|
||||
}
|
||||
@@ -548,13 +562,13 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
if (cleanMethod != null) injectMethod(job.builderType, cleanMethod);
|
||||
}
|
||||
|
||||
if (generateBuilderMethod && methodExists(job.builderMethodName, job.builderTypeParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
|
||||
if (generateBuilderMethod && methodExists(job.builderMethodName, job.parentType, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
|
||||
if (generateBuilderMethod) {
|
||||
MethodDeclaration md = generateBuilderMethod(job);
|
||||
if (md != null) injectMethod(job.builderTypeParent, md);
|
||||
if (md != null) injectMethod(job.parentType, md);
|
||||
}
|
||||
|
||||
if (job.toBuilder) switch (methodExists(job.toBuilderMethodName, job.builderTypeParent, 0)) {
|
||||
if (job.toBuilder) switch (methodExists(TO_BUILDER_METHOD_NAME_STRING, job.parentType, 0)) {
|
||||
case EXISTS_BY_USER:
|
||||
annotationNode.addWarning("Not generating toBuilder() as it already exists.");
|
||||
break;
|
||||
@@ -569,7 +583,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
MethodDeclaration md = generateToBuilderMethod(job, tps, annInstance.setterPrefix());
|
||||
|
||||
if (md != null) injectMethod(job.builderTypeParent, md);
|
||||
if (md != null) injectMethod(job.parentType, md);
|
||||
}
|
||||
|
||||
if (nonFinalNonDefaultedFields != null && generateBuilderMethod) {
|
||||
@@ -608,13 +622,12 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
return token;
|
||||
}
|
||||
|
||||
private static final char[] BUILDER_TEMP_VAR = {'b', 'u', 'i', 'l', 'd', 'e', 'r'};
|
||||
private MethodDeclaration generateToBuilderMethod(BuilderJob job, TypeParameter[] typeParameters, String prefix) {
|
||||
int pS = job.source.sourceStart, pE = job.source.sourceEnd;
|
||||
long p = job.getPos();
|
||||
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.selector = job.toBuilderMethodName.toCharArray();
|
||||
out.selector = TO_BUILDER_METHOD_NAME;
|
||||
out.modifiers = toEclipseModifier(job.accessOuters);
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
|
||||
@@ -657,7 +670,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
obtainExpr.typeArguments[j] = new SingleTypeReference(typeParameters[j].name, 0);
|
||||
}
|
||||
}
|
||||
obtainExpr.receiver = generateNameReference(job.builderTypeParent, 0);
|
||||
obtainExpr.receiver = generateNameReference(job.parentType, 0);
|
||||
} else {
|
||||
obtainExpr.receiver = new ThisReference(0, 0);
|
||||
}
|
||||
@@ -709,8 +722,8 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
out.statements[preSs] = new ReturnStatement(receiver, pS, pE);
|
||||
}
|
||||
|
||||
createRelevantNonNullAnnotation(job.builderTypeParent, out);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), ((TypeDeclaration) job.builderTypeParent.get()).scope);
|
||||
createRelevantNonNullAnnotation(job.parentType, out);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), ((TypeDeclaration) job.parentType.get()).scope);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -736,6 +749,18 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
return decl;
|
||||
}
|
||||
|
||||
static Receiver generateNotCalledReceiver(BuilderJob job, String setterName) {
|
||||
char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
|
||||
SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(job.source, nameNotCalled.length)), job.source.sourceStart);
|
||||
ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
|
||||
|
||||
TypeReference typeReference = job.createBuilderTypeReference();
|
||||
int trLen = typeReference.getTypeName().length;
|
||||
typeReference.annotations = new Annotation[trLen][];
|
||||
typeReference.annotations[trLen - 1] = new Annotation[] {ann};
|
||||
return new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, 0);
|
||||
}
|
||||
|
||||
static Receiver generateBuildReceiver(BuilderJob job) {
|
||||
if (!job.checkerFramework.generateCalledMethods()) return null;
|
||||
|
||||
@@ -803,7 +828,7 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
MessageSend inv = new MessageSend();
|
||||
inv.sourceStart = job.source.sourceStart;
|
||||
inv.sourceEnd = job.source.sourceEnd;
|
||||
inv.receiver = new SingleNameReference(((TypeDeclaration) job.builderTypeParent.get()).name, 0L);
|
||||
inv.receiver = new SingleNameReference(((TypeDeclaration) job.parentType.get()).name, 0L);
|
||||
inv.selector = bfd.nameOfDefaultProvider;
|
||||
inv.typeArguments = typeParameterNames(((TypeDeclaration) job.builderType.get()).typeParameters);
|
||||
|
||||
@@ -897,7 +922,6 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
public MethodDeclaration generateBuilderMethod(BuilderJob job) {
|
||||
int pS = job.source.sourceStart, pE = job.source.sourceEnd;
|
||||
long p = job.getPos();
|
||||
char[] builderClassName = job.getBuilderClassName();
|
||||
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.selector = job.builderMethodName.toCharArray();
|
||||
@@ -920,9 +944,9 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
QualifiedAllocationExpression qualifiedInvoke = new QualifiedAllocationExpression();
|
||||
qualifiedInvoke.enclosingInstance = new ThisReference(pS, pE);
|
||||
if (job.typeParams == null || job.typeParams.length == 0) {
|
||||
qualifiedInvoke.type = new SingleTypeReference(builderClassName, p);
|
||||
qualifiedInvoke.type = new SingleTypeReference(job.builderClassNameArr, p);
|
||||
} else {
|
||||
qualifiedInvoke.type = namePlusTypeParamsToTypeReference(null, builderClassName, false, job.typeParams, p);
|
||||
qualifiedInvoke.type = namePlusTypeParamsToTypeReference(null, job.builderClassNameArr, false, job.typeParams, p);
|
||||
}
|
||||
|
||||
out.statements = new Statement[] {new ReturnStatement(qualifiedInvoke, pS, pE)};
|
||||
@@ -973,29 +997,27 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
}
|
||||
|
||||
private static final AbstractMethodDeclaration[] EMPTY = {};
|
||||
|
||||
public void makePrefixedSetterMethodsForBuilder(BuilderJob job, BuilderFieldData bfd, String prefix) {
|
||||
boolean deprecate = isFieldDeprecated(bfd.originalFieldNode);
|
||||
if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) {
|
||||
makePrefixedSetterMethodForBuilder(job, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, bfd.annotations, bfd.originalFieldNode, prefix);
|
||||
makePrefixedSetterMethodForBuilder(job, bfd, deprecate, prefix);
|
||||
} else {
|
||||
bfd.singularData.getSingularizer().generateMethods(job, bfd.singularData, deprecate);
|
||||
}
|
||||
}
|
||||
|
||||
private void makePrefixedSetterMethodForBuilder(BuilderJob job, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, Annotation[] annotations, EclipseNode originalFieldNode, String prefix) {
|
||||
private void makePrefixedSetterMethodForBuilder(BuilderJob job, BuilderFieldData bfd, boolean deprecate, String prefix) {
|
||||
TypeDeclaration td = (TypeDeclaration) job.builderType.get();
|
||||
EclipseNode fieldNode = bfd.createdFields.get(0);
|
||||
AbstractMethodDeclaration[] existing = td.methods;
|
||||
if (existing == null) existing = EMPTY;
|
||||
if (existing == null) existing = EMPTY_METHODS;
|
||||
int len = existing.length;
|
||||
|
||||
String setterPrefix = prefix.isEmpty() ? "set" : prefix;
|
||||
String setterName;
|
||||
if (job.oldFluent) {
|
||||
setterName = prefix.isEmpty() ? new String(paramName) : HandlerUtil.buildAccessorName(setterPrefix, new String(paramName));
|
||||
setterName = prefix.isEmpty() ? new String(bfd.name) : HandlerUtil.buildAccessorName(setterPrefix, new String(bfd.name));
|
||||
} else {
|
||||
setterName = HandlerUtil.buildAccessorName(setterPrefix, new String(paramName));
|
||||
setterName = HandlerUtil.buildAccessorName(setterPrefix, new String(bfd.name));
|
||||
}
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
@@ -1005,26 +1027,16 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
List<Annotation> methodAnnsList = Collections.<Annotation>emptyList();
|
||||
Annotation[] methodAnns = EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode);
|
||||
Annotation[] methodAnns = EclipseHandlerUtil.findCopyableToSetterAnnotations(bfd.originalFieldNode);
|
||||
if (methodAnns != null && methodAnns.length > 0) methodAnnsList = Arrays.asList(methodAnns);
|
||||
ASTNode source = job.sourceNode.get();
|
||||
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, job.oldChain, toEclipseModifier(job.accessInners),
|
||||
job.sourceNode, methodAnnsList, annotations != null ? Arrays.asList(copyAnnotations(source, annotations)) : Collections.<Annotation>emptyList());
|
||||
if (job.checkerFramework.generateCalledMethods()) {
|
||||
char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
|
||||
SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart);
|
||||
ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
|
||||
|
||||
TypeReference typeReference = job.createBuilderTypeReference();
|
||||
int trLen = typeReference.getTypeName().length;
|
||||
typeReference.annotations = new Annotation[trLen][];
|
||||
typeReference.annotations[trLen - 1] = new Annotation[] {ann};
|
||||
setter.receiver = new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, 0);
|
||||
}
|
||||
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, bfd.name, bfd.nameOfSetFlag, job.oldChain, toEclipseModifier(job.accessInners),
|
||||
job.sourceNode, methodAnnsList, bfd.annotations != null ? Arrays.asList(copyAnnotations(source, bfd.annotations)) : Collections.<Annotation>emptyList());
|
||||
if (job.checkerFramework.generateCalledMethods()) setter.receiver = generateNotCalledReceiver(job, setterName);
|
||||
if (job.sourceNode.up().getKind() == Kind.METHOD) {
|
||||
copyJavadocFromParam(originalFieldNode.up(), setter, td, paramName.toString());
|
||||
copyJavadocFromParam(bfd.originalFieldNode.up(), setter, td, bfd.name.toString());
|
||||
} else {
|
||||
copyJavadoc(originalFieldNode, setter, td, CopyJavadoc.SETTER, true);
|
||||
copyJavadoc(bfd.originalFieldNode, setter, td, CopyJavadoc.SETTER, true);
|
||||
}
|
||||
injectMethod(job.builderType, setter);
|
||||
}
|
||||
@@ -1045,15 +1057,15 @@ public class HandleBuilder extends EclipseAnnotationHandler<Builder> {
|
||||
}
|
||||
|
||||
public void makeBuilderClass(BuilderJob job) {
|
||||
TypeDeclaration parent = (TypeDeclaration) job.builderTypeParent.get();
|
||||
TypeDeclaration parent = (TypeDeclaration) job.parentType.get();
|
||||
TypeDeclaration builder = new TypeDeclaration(parent.compilationResult);
|
||||
builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
builder.modifiers |= toEclipseModifier(job.accessOuters);
|
||||
if (job.isStatic) builder.modifiers |= ClassFileConstants.AccStatic;
|
||||
builder.typeParameters = job.copyTypeParams();
|
||||
builder.name = job.getBuilderClassName();
|
||||
builder.name = job.builderClassNameArr;
|
||||
builder.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
job.builderType = injectType(job.builderTypeParent, builder);
|
||||
job.builderType = injectType(job.parentType, builder);
|
||||
}
|
||||
|
||||
private void addObtainVia(BuilderFieldData bfd, EclipseNode node) {
|
||||
|
||||
@@ -461,14 +461,12 @@ public class HandleConstructor {
|
||||
constructor.arguments = params.isEmpty() ? null : params.toArray(new Argument[0]);
|
||||
|
||||
/* Generate annotations that must be put on the generated method, and attach them. */ {
|
||||
Annotation[] constructorProperties = null, checkerFramework = null;
|
||||
Annotation[] constructorProperties = null;
|
||||
if (addConstructorProperties && !isLocalType(type)) constructorProperties = createConstructorProperties(source, fieldsToParam);
|
||||
if (getCheckerFrameworkVersion(type).generateUnique()) checkerFramework = new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE) };
|
||||
|
||||
constructor.annotations = copyAnnotations(source,
|
||||
onConstructor.toArray(new Annotation[0]),
|
||||
constructorProperties,
|
||||
checkerFramework);
|
||||
constructorProperties);
|
||||
}
|
||||
|
||||
constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
|
||||
@@ -536,6 +534,11 @@ public class HandleConstructor {
|
||||
TypeDeclaration typeDecl = (TypeDeclaration) type.get();
|
||||
constructor.returnType = EclipseHandlerUtil.namePlusTypeParamsToTypeReference(type, typeDecl.typeParameters, p);
|
||||
constructor.annotations = null;
|
||||
if (getCheckerFrameworkVersion(type).generateUnique()) {
|
||||
int len = constructor.returnType.getTypeName().length;
|
||||
constructor.returnType.annotations = new Annotation[len][];
|
||||
constructor.returnType.annotations[len - 1] = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
|
||||
}
|
||||
constructor.selector = name.toCharArray();
|
||||
constructor.thrownExceptions = null;
|
||||
constructor.typeParameters = copyTypeParams(((TypeDeclaration) type.get()).typeParameters, source);
|
||||
@@ -556,9 +559,7 @@ public class HandleConstructor {
|
||||
assigns.add(nameRef);
|
||||
|
||||
Argument parameter = new Argument(field.name, fieldPos, copyType(field.type, source), Modifier.FINAL);
|
||||
Annotation[] checkerFramework = null;
|
||||
if (getCheckerFrameworkVersion(fieldNode).generateUnique()) checkerFramework = new Annotation[] { generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE) };
|
||||
parameter.annotations = copyAnnotations(source, findCopyableAnnotations(fieldNode), checkerFramework);
|
||||
parameter.annotations = copyAnnotations(source, findCopyableAnnotations(fieldNode));
|
||||
params.add(parameter);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
package lombok.eclipse.handlers;
|
||||
|
||||
import static lombok.eclipse.handlers.HandleBuilder.*;
|
||||
import static lombok.core.handlers.HandlerUtil.*;
|
||||
import static lombok.eclipse.Eclipse.*;
|
||||
import static lombok.eclipse.handlers.EclipseHandlerUtil.*;
|
||||
@@ -57,13 +58,10 @@ import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference
|
||||
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.Receiver;
|
||||
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
|
||||
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.Statement;
|
||||
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
|
||||
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
|
||||
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
|
||||
@@ -99,75 +97,100 @@ import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
|
||||
import lombok.eclipse.handlers.EclipseSingularsRecipes.StatementMaker;
|
||||
import lombok.eclipse.handlers.EclipseSingularsRecipes.TypeReferenceMaker;
|
||||
import lombok.eclipse.handlers.HandleBuilder.BuilderFieldData;
|
||||
import lombok.eclipse.handlers.HandleBuilder.BuilderJob;
|
||||
import lombok.experimental.NonFinal;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
@ProviderFor(EclipseAnnotationHandler.class)
|
||||
@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 EclipseAnnotationHandler<SuperBuilder> {
|
||||
private static final char[] CLEAN_FIELD_NAME = "$lombokUnclean".toCharArray();
|
||||
private static final char[] CLEAN_METHOD_NAME = "$lombokClean".toCharArray();
|
||||
private static final char[] DEFAULT_PREFIX = "$default$".toCharArray();
|
||||
private static final char[] SET_PREFIX = "$set".toCharArray();
|
||||
private static final char[] VALUE_PREFIX = "$value".toCharArray();
|
||||
private static final char[] SELF_METHOD_NAME = "self".toCharArray();
|
||||
private static final String TO_BUILDER_METHOD_NAME_STRING = "toBuilder";
|
||||
private static final char[] TO_BUILDER_METHOD_NAME = TO_BUILDER_METHOD_NAME_STRING.toCharArray();
|
||||
private static final char[] FILL_VALUES_METHOD_NAME = "$fillValuesFrom".toCharArray();
|
||||
private static final char[] FILL_VALUES_STATIC_METHOD_NAME = "$fillValuesFromInstanceIntoBuilder".toCharArray();
|
||||
private static final char[] INSTANCE_VARIABLE_NAME = "instance".toCharArray();
|
||||
private static final String BUILDER_VARIABLE_NAME_STRING = "b";
|
||||
private static final char[] BUILDER_VARIABLE_NAME = BUILDER_VARIABLE_NAME_STRING.toCharArray();
|
||||
|
||||
private static final AbstractMethodDeclaration[] EMPTY_METHODS = {};
|
||||
class SuperBuilderJob extends BuilderJob {
|
||||
void init(AnnotationValues<SuperBuilder> annValues, SuperBuilder ann, EclipseNode 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, "");
|
||||
}
|
||||
|
||||
EclipseNode builderAbstractType;
|
||||
String builderAbstractClassName;
|
||||
char[] builderAbstractClassNameArr;
|
||||
EclipseNode builderImplType;
|
||||
String builderImplClassName;
|
||||
char[] builderImplClassNameArr;
|
||||
private TypeParameter[] builderTypeParams_;
|
||||
void setBuilderToImpl() {
|
||||
builderType = builderImplType;
|
||||
builderClassName = builderImplClassName;
|
||||
builderClassNameArr = builderImplClassNameArr;
|
||||
builderTypeParams = typeParams;
|
||||
}
|
||||
|
||||
void setBuilderToAbstract() {
|
||||
builderType = builderAbstractType;
|
||||
builderClassName = builderAbstractClassName;
|
||||
builderClassNameArr = builderAbstractClassNameArr;
|
||||
builderTypeParams = builderTypeParams_;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(AnnotationValues<SuperBuilder> annotation, Annotation ast, EclipseNode annotationNode) {
|
||||
@Override public void handle(AnnotationValues<SuperBuilder> annotation, Annotation ast, EclipseNode annotationNode) {
|
||||
handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.SUPERBUILDER_FLAG_USAGE, "@SuperBuilder");
|
||||
CheckerFrameworkVersion cfv = getCheckerFrameworkVersion(annotationNode);
|
||||
SuperBuilderJob job = new SuperBuilderJob();
|
||||
job.sourceNode = annotationNode;
|
||||
job.source = ast;
|
||||
job.checkerFramework = getCheckerFrameworkVersion(annotationNode);
|
||||
job.isStatic = true;
|
||||
|
||||
long p = (long) ast.sourceStart << 32 | ast.sourceEnd;
|
||||
|
||||
SuperBuilder superbuilderAnnotation = annotation.getInstance();
|
||||
|
||||
String builderMethodName = superbuilderAnnotation.builderMethodName();
|
||||
String buildMethodName = superbuilderAnnotation.buildMethodName();
|
||||
|
||||
if (builderMethodName == null) builderMethodName = "builder";
|
||||
if (buildMethodName == null) buildMethodName = "build";
|
||||
SuperBuilder annInstance = annotation.getInstance();
|
||||
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;
|
||||
|
||||
boolean toBuilder = superbuilderAnnotation.toBuilder();
|
||||
if (!checkName("buildMethodName", job.buildMethodName, annotationNode)) return;
|
||||
|
||||
EclipseNode tdParent = annotationNode.up();
|
||||
EclipseNode parent = annotationNode.up();
|
||||
|
||||
java.util.List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
|
||||
TypeReference returnType;
|
||||
TypeParameter[] typeParams;
|
||||
job.builderFields = new ArrayList<BuilderFieldData>();
|
||||
TypeReference buildMethodReturnType;
|
||||
|
||||
boolean addCleaning = false;
|
||||
|
||||
if (!(tdParent.get() instanceof TypeDeclaration)) {
|
||||
List<EclipseNode> nonFinalNonDefaultedFields = null;
|
||||
|
||||
if (!(parent.get() instanceof TypeDeclaration)) {
|
||||
annotationNode.addError("@SuperBuilder is only supported on types.");
|
||||
return;
|
||||
}
|
||||
TypeDeclaration td = (TypeDeclaration) tdParent.get();
|
||||
job.parentType = parent;
|
||||
TypeDeclaration td = (TypeDeclaration) parent.get();
|
||||
|
||||
// Gather all fields of the class that should be set by the builder.
|
||||
List<EclipseNode> allFields = new ArrayList<EclipseNode>();
|
||||
List<EclipseNode> nonFinalNonDefaultedFields = null;
|
||||
|
||||
boolean valuePresent = (hasAnnotation(lombok.Value.class, tdParent) || hasAnnotation("lombok.experimental.Value", tdParent));
|
||||
for (EclipseNode fieldNode : HandleConstructor.findAllFields(tdParent, true)) {
|
||||
boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation("lombok.experimental.Value", parent));
|
||||
for (EclipseNode fieldNode : HandleConstructor.findAllFields(parent, true)) {
|
||||
FieldDeclaration fd = (FieldDeclaration) fieldNode.get();
|
||||
EclipseNode isDefault = findAnnotation(Builder.Default.class, fieldNode);
|
||||
boolean isFinal = ((fd.modifiers & ClassFileConstants.AccFinal) != 0) || (valuePresent && !hasAnnotation(NonFinal.class, fieldNode));
|
||||
@@ -180,7 +203,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
bfd.builderFieldName = bfd.name;
|
||||
bfd.annotations = copyAnnotations(fd, copyableAnnotations);
|
||||
bfd.type = fd.type;
|
||||
bfd.singularData = getSingularData(fieldNode, ast, superbuilderAnnotation.setterPrefix());
|
||||
bfd.singularData = getSingularData(fieldNode, ast, annInstance.setterPrefix());
|
||||
bfd.originalFieldNode = fieldNode;
|
||||
|
||||
if (bfd.singularData != null && isDefault != null) {
|
||||
@@ -205,21 +228,15 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
bfd.builderFieldName = prefixWith(bfd.name, VALUE_PREFIX);
|
||||
|
||||
MethodDeclaration md = HandleBuilder.generateDefaultProvider(bfd.nameOfDefaultProvider, td.typeParameters, fieldNode, ast);
|
||||
if (md != null) injectMethod(tdParent, md);
|
||||
if (md != null) injectMethod(parent, md);
|
||||
}
|
||||
addObtainVia(bfd, fieldNode);
|
||||
builderFields.add(bfd);
|
||||
job.builderFields.add(bfd);
|
||||
allFields.add(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("*", String.valueOf(td.name));
|
||||
String builderImplClassName = builderClassName + "Impl";
|
||||
|
||||
typeParams = td.typeParameters != null ? td.typeParameters : new TypeParameter[0];
|
||||
returnType = namePlusTypeParamsToTypeReference(tdParent, typeParams, p);
|
||||
job.typeParams = td.typeParameters != null ? td.typeParameters : new TypeParameter[0];
|
||||
buildMethodReturnType = job.createBuilderParentTypeReference();
|
||||
|
||||
// <C, B> are the generics for our builder.
|
||||
String classGenericName = "C";
|
||||
@@ -227,25 +244,41 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<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.Set<String> usedNames = gatherUsedTypeNames(typeParams, td);
|
||||
java.util.Set<String> usedNames = gatherUsedTypeNames(job.typeParams, td);
|
||||
classGenericName = generateNonclashingNameFor(classGenericName, usedNames);
|
||||
builderGenericName = generateNonclashingNameFor(builderGenericName, usedNames);
|
||||
|
||||
TypeParameter[] paddedTypeParameters; {
|
||||
paddedTypeParameters = new TypeParameter[job.typeParams.length + 2];
|
||||
System.arraycopy(job.typeParams, 0, paddedTypeParameters, 0, job.typeParams.length);
|
||||
|
||||
TypeParameter c = new TypeParameter();
|
||||
c.name = classGenericName.toCharArray();
|
||||
c.type = cloneSelfType(job.parentType, job.source);
|
||||
paddedTypeParameters[paddedTypeParameters.length - 2] = c;
|
||||
|
||||
TypeParameter b = new TypeParameter();
|
||||
b.name = builderGenericName.toCharArray();
|
||||
b.type = cloneSelfType(job.parentType, job.source);
|
||||
paddedTypeParameters[paddedTypeParameters.length - 1] = b;
|
||||
}
|
||||
job.builderTypeParams = job.builderTypeParams_ = paddedTypeParameters;
|
||||
|
||||
TypeReference extendsClause = td.superclass;
|
||||
TypeReference superclassBuilderClass = null;
|
||||
TypeReference[] typeArguments = new TypeReference[] {
|
||||
new SingleTypeReference(classGenericName.toCharArray(), 0),
|
||||
new SingleTypeReference(builderGenericName.toCharArray(), 0)
|
||||
new SingleTypeReference(builderGenericName.toCharArray(), 0),
|
||||
};
|
||||
if (extendsClause instanceof QualifiedTypeReference) {
|
||||
QualifiedTypeReference qualifiedTypeReference = (QualifiedTypeReference)extendsClause;
|
||||
String superclassClassName = String.valueOf(qualifiedTypeReference.getLastToken());
|
||||
String superclassBuilderClassName = builderClassNameTemplate.replace("*", superclassClassName);
|
||||
String superclassBuilderClassName = job.replaceBuilderClassName(superclassClassName);
|
||||
|
||||
char[][] tokens = Arrays.copyOf(qualifiedTypeReference.tokens, qualifiedTypeReference.tokens.length + 1);
|
||||
tokens[tokens.length-1] = superclassBuilderClassName.toCharArray();
|
||||
long[] poss = new long[tokens.length];
|
||||
Arrays.fill(poss, p);
|
||||
Arrays.fill(poss, job.getPos());
|
||||
|
||||
TypeReference[] superclassTypeArgs = getTypeParametersFrom(extendsClause);
|
||||
|
||||
@@ -261,7 +294,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
|
||||
char[][] tokens = new char[][] {superClass.toCharArray(), superclassBuilderClassName.toCharArray()};
|
||||
long[] poss = new long[tokens.length];
|
||||
Arrays.fill(poss, p);
|
||||
Arrays.fill(poss, job.getPos());
|
||||
|
||||
TypeReference[] superclassTypeArgs = getTypeParametersFrom(extendsClause);
|
||||
|
||||
@@ -272,40 +305,43 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
|
||||
superclassBuilderClass = new ParameterizedQualifiedTypeReference(tokens, typeArgsForTokens, 0, poss);
|
||||
}
|
||||
job.builderAbstractClassName = job.builderClassName = job.replaceBuilderClassName(td.name);
|
||||
job.builderAbstractClassNameArr = job.builderClassNameArr = job.builderAbstractClassName.toCharArray();
|
||||
job.builderImplClassName = job.builderAbstractClassName + "Impl";
|
||||
job.builderImplClassNameArr = job.builderImplClassName.toCharArray();
|
||||
|
||||
// If there is no superclass, superclassBuilderClassExpression is still == null at this point.
|
||||
// You can use it to check whether to inherit or not.
|
||||
|
||||
if (!constructorExists(tdParent, builderClassName)) {
|
||||
generateBuilderBasedConstructor(cfv, tdParent, typeParams, builderFields, annotationNode, builderClassName,
|
||||
superclassBuilderClass != null);
|
||||
if (!constructorExists(parent, job.builderClassName)) {
|
||||
generateBuilderBasedConstructor(job, superclassBuilderClass != null);
|
||||
}
|
||||
|
||||
// Create the abstract builder class, or reuse an existing one.
|
||||
EclipseNode builderType = findInnerClass(tdParent, builderClassName);
|
||||
if (builderType == null) {
|
||||
builderType = generateBuilderAbstractClass(tdParent, builderClassName, superclassBuilderClass,
|
||||
typeParams, ast, classGenericName, builderGenericName);
|
||||
job.builderAbstractType = findInnerClass(parent, job.builderClassName);
|
||||
if (job.builderAbstractType == null) {
|
||||
job.builderAbstractType = generateBuilderAbstractClass(job, superclassBuilderClass, classGenericName, builderGenericName);
|
||||
} else {
|
||||
TypeDeclaration builderTypeDeclaration = (TypeDeclaration) builderType.get();
|
||||
TypeDeclaration builderTypeDeclaration = (TypeDeclaration) job.builderAbstractType.get();
|
||||
if ((builderTypeDeclaration.modifiers & (ClassFileConstants.AccStatic | ClassFileConstants.AccAbstract)) == 0) {
|
||||
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;
|
||||
EclipseSingularizer singularizer = sd.getSingularizer();
|
||||
if (singularizer == null) continue;
|
||||
if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
|
||||
if (singularizer.checkForAlreadyExistingNodesAndGenerateError(job.builderAbstractType, sd)) {
|
||||
bfd.singularData = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -325,47 +361,52 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
}
|
||||
|
||||
// Generate the fields in the abstract builder class that hold the values for the instance.
|
||||
generateBuilderFields(builderType, builderFields, ast);
|
||||
job.setBuilderToAbstract();
|
||||
generateBuilderFields(job);
|
||||
if (addCleaning) {
|
||||
FieldDeclaration cleanDecl = new FieldDeclaration(CLEAN_FIELD_NAME, 0, -1);
|
||||
cleanDecl.declarationSourceEnd = -1;
|
||||
cleanDecl.modifiers = ClassFileConstants.AccPrivate;
|
||||
cleanDecl.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
|
||||
injectFieldAndMarkGenerated(builderType, cleanDecl);
|
||||
injectFieldAndMarkGenerated(job.builderType, cleanDecl);
|
||||
}
|
||||
|
||||
if (toBuilder) {
|
||||
if (job.toBuilder) {
|
||||
// Generate $fillValuesFrom() method in the abstract builder.
|
||||
injectMethod(builderType, generateFillValuesMethod(tdParent, superclassBuilderClass != null, builderGenericName, classGenericName, builderClassName, typeParams));
|
||||
injectMethod(job.builderType, generateFillValuesMethod(job, superclassBuilderClass != null, builderGenericName, classGenericName));
|
||||
// Generate $fillValuesFromInstanceIntoBuilder() method in the builder implementation class.
|
||||
injectMethod(builderType, generateStaticFillValuesMethod(tdParent, builderClassName, typeParams, builderFields, ast, superbuilderAnnotation.setterPrefix()));
|
||||
injectMethod(job.builderType, generateStaticFillValuesMethod(job, annInstance.setterPrefix()));
|
||||
}
|
||||
|
||||
// Generate abstract self() and build() methods in the abstract builder.
|
||||
injectMethod(builderType, generateAbstractSelfMethod(cfv, tdParent, superclassBuilderClass != null, builderGenericName));
|
||||
injectMethod(builderType, generateAbstractBuildMethod(cfv, builderType, buildMethodName, builderFields, superclassBuilderClass != null, classGenericName, ast));
|
||||
injectMethod(job.builderType, generateAbstractSelfMethod(job, superclassBuilderClass != null, builderGenericName));
|
||||
job.setBuilderToAbstract();
|
||||
injectMethod(job.builderType, generateAbstractBuildMethod(job, superclassBuilderClass != null, classGenericName));
|
||||
|
||||
// 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.
|
||||
if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
|
||||
if (methodExists("toString", job.builderType, 0) == MemberExistsResult.NOT_EXISTS) {
|
||||
List<Included<EclipseNode, ToString.Include>> fieldNodes = new ArrayList<Included<EclipseNode, ToString.Include>>();
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
for (BuilderFieldData bfd : job.builderFields) {
|
||||
for (EclipseNode f : bfd.createdFields) {
|
||||
fieldNodes.add(new Included<EclipseNode, 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.
|
||||
MethodDeclaration md = HandleToString.createToString(builderType, fieldNodes, true, superclassBuilderClass != null, ast, FieldAccess.ALWAYS_FIELD);
|
||||
MethodDeclaration md = HandleToString.createToString(job.builderType, fieldNodes, true, superclassBuilderClass != null, ast, FieldAccess.ALWAYS_FIELD);
|
||||
if (md != null) {
|
||||
injectMethod(builderType, md);
|
||||
injectMethod(job.builderType, md);
|
||||
}
|
||||
}
|
||||
|
||||
if (addCleaning) injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
|
||||
if (addCleaning) {
|
||||
job.setBuilderToAbstract();
|
||||
injectMethod(job.builderType, generateCleanMethod(job));
|
||||
}
|
||||
|
||||
boolean isAbstract = (td.modifiers & ClassFileConstants.AccAbstract) != 0;
|
||||
if (isAbstract) {
|
||||
@@ -374,26 +415,27 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
}
|
||||
|
||||
// Create the builder implementation class, or reuse an existing one.
|
||||
EclipseNode builderImplType = findInnerClass(tdParent, builderImplClassName);
|
||||
if (builderImplType == null) {
|
||||
builderImplType = generateBuilderImplClass(tdParent, builderImplClassName, builderClassName, typeParams, ast);
|
||||
job.builderImplType = findInnerClass(parent, job.builderImplClassName);
|
||||
if (job.builderImplType == null) {
|
||||
job.builderImplType = generateBuilderImplClass(job, job.builderImplClassName);
|
||||
} else {
|
||||
TypeDeclaration builderImplTypeDeclaration = (TypeDeclaration) builderImplType.get();
|
||||
TypeDeclaration builderImplTypeDeclaration = (TypeDeclaration) job.builderImplType.get();
|
||||
if ((builderImplTypeDeclaration.modifiers & ClassFileConstants.AccAbstract) != 0 ||
|
||||
(builderImplTypeDeclaration.modifiers & ClassFileConstants.AccStatic) == 0) {
|
||||
annotationNode.addError("Existing BuilderImpl must be a non-abstract static inner class.");
|
||||
return;
|
||||
}
|
||||
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderImplType, annotationNode);
|
||||
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(job.builderImplType, annotationNode);
|
||||
}
|
||||
|
||||
if (toBuilder) {
|
||||
job.setBuilderToImpl();
|
||||
if (job.toBuilder) {
|
||||
// Add the toBuilder() method to the annotated class.
|
||||
switch (methodExists(TO_BUILDER_METHOD_NAME_STRING, tdParent, 0)) {
|
||||
switch (methodExists(TO_BUILDER_METHOD_NAME_STRING, job.parentType, 0)) {
|
||||
case EXISTS_BY_USER:
|
||||
break;
|
||||
case NOT_EXISTS:
|
||||
injectMethod(tdParent, generateToBuilderMethod(cfv, builderClassName, builderImplClassName, tdParent, typeParams, ast));
|
||||
injectMethod(parent, generateToBuilderMethod(job));
|
||||
break;
|
||||
default:
|
||||
// Should not happen.
|
||||
@@ -401,17 +443,19 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
}
|
||||
|
||||
// Create the self() and build() methods in the BuilderImpl.
|
||||
injectMethod(builderImplType, generateSelfMethod(cfv, builderImplType, typeParams, p));
|
||||
job.setBuilderToImpl();
|
||||
injectMethod(job.builderImplType, generateSelfMethod(job));
|
||||
|
||||
if (methodExists(buildMethodName, builderImplType, -1) == MemberExistsResult.NOT_EXISTS) {
|
||||
injectMethod(builderImplType, generateBuildMethod(cfv, builderImplType, buildMethodName, returnType, builderFields, ast));
|
||||
if (methodExists(job.buildMethodName, job.builderImplType, -1) == MemberExistsResult.NOT_EXISTS) {
|
||||
job.setBuilderToImpl();
|
||||
injectMethod(job.builderImplType, generateBuildMethod(job, buildMethodReturnType));
|
||||
}
|
||||
|
||||
// Add the builder() method to the annotated class.
|
||||
if (generateBuilderMethod && methodExists(builderMethodName, tdParent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
|
||||
if (generateBuilderMethod && methodExists(job.builderMethodName, parent, -1) != MemberExistsResult.NOT_EXISTS) generateBuilderMethod = false;
|
||||
if (generateBuilderMethod) {
|
||||
MethodDeclaration md = generateBuilderMethod(cfv, builderMethodName, builderClassName, builderImplClassName, tdParent, typeParams, ast);
|
||||
if (md != null) injectMethod(tdParent, md);
|
||||
MethodDeclaration md = generateBuilderMethod(job);
|
||||
if (md != null) injectMethod(parent, md);
|
||||
}
|
||||
|
||||
if (nonFinalNonDefaultedFields != null && generateBuilderMethod) {
|
||||
@@ -421,97 +465,82 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
}
|
||||
}
|
||||
|
||||
private EclipseNode generateBuilderAbstractClass(EclipseNode tdParent, String builderClass,
|
||||
TypeReference superclassBuilderClass, TypeParameter[] typeParams,
|
||||
ASTNode source, String classGenericName, String builderGenericName) {
|
||||
|
||||
TypeDeclaration parent = (TypeDeclaration) tdParent.get();
|
||||
private EclipseNode generateBuilderAbstractClass(BuilderJob job, TypeReference superclassBuilderClass, String classGenericName, String builderGenericName) {
|
||||
TypeDeclaration parent = (TypeDeclaration) job.parentType.get();
|
||||
TypeDeclaration builder = new TypeDeclaration(parent.compilationResult);
|
||||
builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
builder.modifiers |= ClassFileConstants.AccPublic | ClassFileConstants.AccStatic | ClassFileConstants.AccAbstract;
|
||||
builder.name = builderClass.toCharArray();
|
||||
builder.name = job.builderClassNameArr;
|
||||
|
||||
// Keep any type params of the annotated class.
|
||||
builder.typeParameters = Arrays.copyOf(copyTypeParams(typeParams, source), typeParams.length + 2);
|
||||
builder.typeParameters = Arrays.copyOf(copyTypeParams(job.typeParams, job.source), job.typeParams.length + 2);
|
||||
// Add builder-specific type params required for inheritable builders.
|
||||
// 1. The return type for the build() method, named "C", which extends the annotated class.
|
||||
TypeParameter o = new TypeParameter();
|
||||
o.name = classGenericName.toCharArray();
|
||||
o.type = cloneSelfType(tdParent, source);
|
||||
o.type = cloneSelfType(job.parentType, job.source);
|
||||
builder.typeParameters[builder.typeParameters.length - 2] = o;
|
||||
// 2. The return type for all setter methods, named "B", which extends this builder class.
|
||||
o = new TypeParameter();
|
||||
o.name = builderGenericName.toCharArray();
|
||||
TypeReference[] typerefs = appendBuilderTypeReferences(typeParams, classGenericName, builderGenericName);
|
||||
o.type = generateParameterizedTypeReference(tdParent, builderClass.toCharArray(), false, typerefs, 0);
|
||||
TypeReference[] typerefs = appendBuilderTypeReferences(job.typeParams, classGenericName, builderGenericName);
|
||||
o.type = generateParameterizedTypeReference(job.parentType, job.builderClassNameArr, false, typerefs, 0);
|
||||
builder.typeParameters[builder.typeParameters.length - 1] = o;
|
||||
|
||||
builder.superclass = copyType(superclassBuilderClass, source);
|
||||
if (superclassBuilderClass != null) builder.superclass = copyType(superclassBuilderClass, job.source);
|
||||
|
||||
builder.createDefaultConstructor(false, true);
|
||||
|
||||
builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
|
||||
return injectType(tdParent, builder);
|
||||
builder.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
return injectType(job.parentType, builder);
|
||||
}
|
||||
|
||||
private EclipseNode generateBuilderImplClass(EclipseNode tdParent, String builderImplClass, String builderAbstractClass, TypeParameter[] typeParams, ASTNode source) {
|
||||
TypeDeclaration parent = (TypeDeclaration) tdParent.get();
|
||||
private EclipseNode generateBuilderImplClass(BuilderJob job, String builderImplClass) {
|
||||
TypeDeclaration parent = (TypeDeclaration) job.parentType.get();
|
||||
TypeDeclaration builder = new TypeDeclaration(parent.compilationResult);
|
||||
builder.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
builder.modifiers |= ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic | ClassFileConstants.AccFinal;
|
||||
builder.name = builderImplClass.toCharArray();
|
||||
|
||||
// Add type params if there are any.
|
||||
if (typeParams != null && typeParams.length > 0) builder.typeParameters = copyTypeParams(typeParams, source);
|
||||
if (job.typeParams != null && job.typeParams.length > 0) builder.typeParameters = copyTypeParams(job.typeParams, job.source);
|
||||
|
||||
if (builderAbstractClass != null) {
|
||||
if (job.builderClassName != null) {
|
||||
// Extend the abstract builder.
|
||||
// 1. Add any type params of the annotated class.
|
||||
TypeReference[] typeArgs = new TypeReference[typeParams.length + 2];
|
||||
for (int i = 0; i < typeParams.length; i++) {
|
||||
typeArgs[i] = new SingleTypeReference(typeParams[i].name, 0);
|
||||
TypeReference[] typeArgs = new TypeReference[job.typeParams.length + 2];
|
||||
for (int i = 0; i < job.typeParams.length; i++) {
|
||||
typeArgs[i] = new SingleTypeReference(job.typeParams[i].name, 0);
|
||||
}
|
||||
// 2. The return type for the build() method (named "C" in the abstract builder), which is the annotated class.
|
||||
// 3. The return type for all setter methods (named "B" in the abstract builder), which is this builder class.
|
||||
typeArgs[typeArgs.length - 2] = cloneSelfType(tdParent, source);
|
||||
typeArgs[typeArgs.length - 1] = createTypeReferenceWithTypeParameters(tdParent, builderImplClass, typeParams);
|
||||
builder.superclass = generateParameterizedTypeReference(tdParent, builderAbstractClass.toCharArray(), false, typeArgs, 0);
|
||||
typeArgs[typeArgs.length - 2] = cloneSelfType(job.parentType, job.source);
|
||||
typeArgs[typeArgs.length - 1] = createTypeReferenceWithTypeParameters(job.parentType, builderImplClass, job.typeParams);
|
||||
builder.superclass = generateParameterizedTypeReference(job.parentType, job.builderClassNameArr, false, typeArgs, 0);
|
||||
}
|
||||
|
||||
builder.createDefaultConstructor(false, true);
|
||||
|
||||
builder.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
|
||||
return injectType(tdParent, builder);
|
||||
builder.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
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 cfv Settings for generating checker framework annotations
|
||||
* @param builderFields a list of fields in the builder which should be assigned to new instances.
|
||||
* @param source the annotation (used for setting source code locations for the generated code).
|
||||
* @param callBuilderBasedSuperConstructor
|
||||
* 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, EclipseNode typeNode, TypeParameter[] typeParams, List<BuilderFieldData> builderFields,
|
||||
EclipseNode sourceNode, String builderClassName, boolean callBuilderBasedSuperConstructor) {
|
||||
private void generateBuilderBasedConstructor(BuilderJob job, boolean callBuilderBasedSuperConstructor) {
|
||||
TypeDeclaration typeDeclaration = ((TypeDeclaration) job.parentType.get());
|
||||
long p = job.getPos();
|
||||
|
||||
ASTNode source = sourceNode.get();
|
||||
|
||||
TypeDeclaration typeDeclaration = ((TypeDeclaration) typeNode.get());
|
||||
long p = (long) source.sourceStart << 32 | source.sourceEnd;
|
||||
|
||||
ConstructorDeclaration constructor = new ConstructorDeclaration(((CompilationUnitDeclaration) typeNode.top().get()).compilationResult);
|
||||
ConstructorDeclaration constructor = new ConstructorDeclaration(((CompilationUnitDeclaration) job.parentType.top().get()).compilationResult);
|
||||
|
||||
constructor.modifiers = toEclipseModifier(AccessLevel.PROTECTED);
|
||||
if (cfv.generateUnique()) constructor.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
|
||||
constructor.selector = typeDeclaration.name;
|
||||
if (callBuilderBasedSuperConstructor) {
|
||||
constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.Super);
|
||||
@@ -519,21 +548,21 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
} else {
|
||||
constructor.constructorCall = new ExplicitConstructorCall(ExplicitConstructorCall.ImplicitSuper);
|
||||
}
|
||||
constructor.constructorCall.sourceStart = source.sourceStart;
|
||||
constructor.constructorCall.sourceEnd = source.sourceEnd;
|
||||
constructor.constructorCall.sourceStart = job.source.sourceStart;
|
||||
constructor.constructorCall.sourceEnd = job.source.sourceEnd;
|
||||
constructor.thrownExceptions = null;
|
||||
constructor.typeParameters = null;
|
||||
constructor.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = source.sourceStart;
|
||||
constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = source.sourceEnd;
|
||||
constructor.bodyStart = constructor.declarationSourceStart = constructor.sourceStart = job.source.sourceStart;
|
||||
constructor.bodyEnd = constructor.declarationSourceEnd = constructor.sourceEnd = job.source.sourceEnd;
|
||||
|
||||
TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND)};
|
||||
TypeReference builderType = generateParameterizedTypeReference(typeNode, builderClassName.toCharArray(), false, mergeToTypeReferences(typeParams, wildcards), p);
|
||||
TypeReference builderType = generateParameterizedTypeReference(job.parentType, job.builderClassNameArr, false, mergeToTypeReferences(job.typeParams, wildcards), p);
|
||||
constructor.arguments = new Argument[] {new Argument(BUILDER_VARIABLE_NAME, p, builderType, Modifier.FINAL)};
|
||||
|
||||
List<Statement> statements = new ArrayList<Statement>();
|
||||
|
||||
for (BuilderFieldData fieldNode : builderFields) {
|
||||
for (BuilderFieldData fieldNode : job.builderFields) {
|
||||
FieldReference fieldInThis = new FieldReference(fieldNode.rawName, p);
|
||||
int s = (int) (p >> 32);
|
||||
int e = (int) p;
|
||||
@@ -541,7 +570,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
|
||||
Expression assignmentExpr;
|
||||
if (fieldNode.singularData != null && fieldNode.singularData.getSingularizer() != null) {
|
||||
fieldNode.singularData.getSingularizer().appendBuildCode(fieldNode.singularData, typeNode, statements, fieldNode.builderFieldName, BUILDER_VARIABLE_NAME_STRING);
|
||||
fieldNode.singularData.getSingularizer().appendBuildCode(fieldNode.singularData, job.parentType, statements, fieldNode.builderFieldName, BUILDER_VARIABLE_NAME_STRING);
|
||||
assignmentExpr = new SingleNameReference(fieldNode.builderFieldName, p);
|
||||
} else {
|
||||
char[][] variableInBuilder = new char[][] {BUILDER_VARIABLE_NAME, fieldNode.builderFieldName};
|
||||
@@ -557,11 +586,11 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
QualifiedNameReference setVariableInBuilderRef = new QualifiedNameReference(setVariableInBuilder, positions, s, e);
|
||||
|
||||
MessageSend defaultMethodCall = new MessageSend();
|
||||
defaultMethodCall.sourceStart = source.sourceStart;
|
||||
defaultMethodCall.sourceEnd = source.sourceEnd;
|
||||
defaultMethodCall.receiver = generateNameReference(typeNode, 0L);
|
||||
defaultMethodCall.sourceStart = job.source.sourceStart;
|
||||
defaultMethodCall.sourceEnd = job.source.sourceEnd;
|
||||
defaultMethodCall.receiver = generateNameReference(job.parentType, 0L);
|
||||
defaultMethodCall.selector = fieldNode.nameOfDefaultProvider;
|
||||
defaultMethodCall.typeArguments = typeParameterNames(((TypeDeclaration) typeNode.get()).typeParameters);
|
||||
defaultMethodCall.typeArguments = typeParameterNames(((TypeDeclaration) job.parentType.get()).typeParameters);
|
||||
|
||||
Statement defaultAssignment = new Assignment(fieldInThis, defaultMethodCall, (int) p);
|
||||
IfStatement ifBlockForDefault = new IfStatement(setVariableInBuilderRef, assignment, defaultAssignment, s, e);
|
||||
@@ -571,41 +600,44 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
}
|
||||
|
||||
if (hasNonNullAnnotations(fieldNode.originalFieldNode)) {
|
||||
Statement nullCheck = generateNullCheck((FieldDeclaration) fieldNode.originalFieldNode.get(), sourceNode, null);
|
||||
Statement nullCheck = generateNullCheck((FieldDeclaration) fieldNode.originalFieldNode.get(), job.sourceNode, null);
|
||||
if (nullCheck != null) statements.add(nullCheck);
|
||||
}
|
||||
}
|
||||
|
||||
constructor.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
|
||||
|
||||
constructor.traverse(new SetGeneratedByVisitor(source), typeDeclaration.scope);
|
||||
constructor.traverse(new SetGeneratedByVisitor(job.source), typeDeclaration.scope);
|
||||
|
||||
injectMethod(typeNode, constructor);
|
||||
injectMethod(job.parentType, constructor);
|
||||
}
|
||||
|
||||
private MethodDeclaration generateBuilderMethod(CheckerFrameworkVersion cfv, String builderMethodName, String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
|
||||
int pS = source.sourceStart, pE = source.sourceEnd;
|
||||
private MethodDeclaration generateBuilderMethod(SuperBuilderJob job) {
|
||||
int pS = job.source.sourceStart, pE = job.source.sourceEnd;
|
||||
long p = (long) pS << 32 | pE;
|
||||
|
||||
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
|
||||
out.selector = builderMethodName.toCharArray();
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.selector = job.builderMethodName.toCharArray();
|
||||
out.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccStatic;
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
|
||||
// Add type params if there are any.
|
||||
if (typeParams != null && typeParams.length > 0) out.typeParameters = copyTypeParams(typeParams, source);
|
||||
if (job.typeParams != null && job.typeParams.length > 0) out.typeParameters = copyTypeParams(job.typeParams, job.source);
|
||||
|
||||
TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) };
|
||||
out.returnType = generateParameterizedTypeReference(type, builderClassName.toCharArray(), false, mergeToTypeReferences(typeParams, wildcards), p);
|
||||
out.returnType = generateParameterizedTypeReference(job.parentType, job.builderAbstractClassNameArr, false, mergeToTypeReferences(job.typeParams, wildcards), p);
|
||||
if (job.checkerFramework.generateUnique()) {
|
||||
int len = out.returnType.getTypeName().length;
|
||||
out.returnType.annotations = new Annotation[len][];
|
||||
out.returnType.annotations[len - 1] = new Annotation[] {generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__UNIQUE)};
|
||||
}
|
||||
|
||||
AllocationExpression invoke = new AllocationExpression();
|
||||
invoke.type = namePlusTypeParamsToTypeReference(type, builderImplClassName.toCharArray(), false, typeParams, p);
|
||||
invoke.type = namePlusTypeParamsToTypeReference(job.parentType, job.builderImplClassNameArr, false, job.typeParams, p);
|
||||
out.statements = new Statement[] {new ReturnStatement(invoke, pS, pE)};
|
||||
|
||||
if (cfv.generateUnique()) out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
|
||||
|
||||
createRelevantNonNullAnnotation(type, out);
|
||||
out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
|
||||
createRelevantNonNullAnnotation(job.parentType, out);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), ((TypeDeclaration) job.parentType.get()).scope);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -617,30 +649,33 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
private MethodDeclaration generateToBuilderMethod(CheckerFrameworkVersion cfv, String builderClassName, String builderImplClassName, EclipseNode type, TypeParameter[] typeParams, ASTNode source) {
|
||||
int pS = source.sourceStart, pE = source.sourceEnd;
|
||||
private MethodDeclaration generateToBuilderMethod(SuperBuilderJob job) {
|
||||
int pS = job.source.sourceStart, pE = job.source.sourceEnd;
|
||||
long p = (long) pS << 32 | pE;
|
||||
|
||||
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) type.top().get()).compilationResult);
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.selector = TO_BUILDER_METHOD_NAME;
|
||||
out.modifiers = ClassFileConstants.AccPublic;
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
|
||||
TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND) };
|
||||
out.returnType = generateParameterizedTypeReference(type, builderClassName.toCharArray(), false, mergeToTypeReferences(typeParams, wildcards), p);
|
||||
out.returnType = generateParameterizedTypeReference(job.parentType, job.builderAbstractClassNameArr, false, mergeToTypeReferences(job.typeParams, wildcards), p);
|
||||
if (job.checkerFramework.generateUnique()) {
|
||||
int len = out.returnType.getTypeName().length;
|
||||
out.returnType.annotations = new Annotation[len][];
|
||||
out.returnType.annotations[len - 1] = new Annotation[] {generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__UNIQUE)};
|
||||
}
|
||||
|
||||
AllocationExpression newClass = new AllocationExpression();
|
||||
newClass.type = namePlusTypeParamsToTypeReference(type, builderImplClassName.toCharArray(), false, typeParams, p);
|
||||
newClass.type = namePlusTypeParamsToTypeReference(job.parentType, job.builderImplClassNameArr, false, job.typeParams, p);
|
||||
MessageSend invokeFillMethod = new MessageSend();
|
||||
invokeFillMethod.receiver = newClass;
|
||||
invokeFillMethod.selector = FILL_VALUES_METHOD_NAME;
|
||||
invokeFillMethod.arguments = new Expression[] {new ThisReference(0, 0)};
|
||||
out.statements = new Statement[] {new ReturnStatement(invokeFillMethod, pS, pE)};
|
||||
|
||||
if (cfv.generateUnique()) out.annotations = new Annotation[] {generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__UNIQUE)};
|
||||
|
||||
createRelevantNonNullAnnotation(type, out);
|
||||
out.traverse(new SetGeneratedByVisitor(source), ((TypeDeclaration) type.get()).scope);
|
||||
createRelevantNonNullAnnotation(job.parentType, out);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), ((TypeDeclaration) job.parentType.get()).scope);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -650,17 +685,17 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
* <pre>
|
||||
* protected B $fillValuesFrom(final C instance) {
|
||||
* super.$fillValuesFrom(instance);
|
||||
* Foobar.FoobarBuilderImpl.$fillValuesFromInstanceIntoBuilder(instance, this);
|
||||
* Foobar.FoobarBuilder.$fillValuesFromInstanceIntoBuilder(instance, this);
|
||||
* return self();
|
||||
* }
|
||||
* </pre>
|
||||
*/
|
||||
private MethodDeclaration generateFillValuesMethod(EclipseNode tdParent, boolean inherited, String builderGenericName, String classGenericName, String builderClassName, TypeParameter[] typeParams) {
|
||||
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) tdParent.top().get()).compilationResult);
|
||||
private MethodDeclaration generateFillValuesMethod(SuperBuilderJob job, boolean inherited, String builderGenericName, String classGenericName) {
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.selector = FILL_VALUES_METHOD_NAME;
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
out.modifiers = ClassFileConstants.AccProtected;
|
||||
if (inherited) out.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, tdParent.get())};
|
||||
if (inherited) out.annotations = new Annotation[] {makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.parentType.get())};
|
||||
out.returnType = new SingleTypeReference(builderGenericName.toCharArray(), 0);
|
||||
|
||||
TypeReference builderType = new SingleTypeReference(classGenericName.toCharArray(), 0);
|
||||
@@ -679,7 +714,7 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
|
||||
// Call the builder implemention's helper method that actually fills the values from the instance.
|
||||
MessageSend callStaticFillValuesMethod = new MessageSend();
|
||||
callStaticFillValuesMethod.receiver = generateNameReference(tdParent, builderClassName.toCharArray(), 0);
|
||||
callStaticFillValuesMethod.receiver = generateNameReference(job.parentType, job.builderAbstractClassNameArr, 0);
|
||||
callStaticFillValuesMethod.selector = FILL_VALUES_STATIC_METHOD_NAME;
|
||||
callStaticFillValuesMethod.arguments = new Expression[] {new SingleNameReference(INSTANCE_VARIABLE_NAME, 0), new ThisReference(0, 0)};
|
||||
body.add(callStaticFillValuesMethod);
|
||||
@@ -707,41 +742,40 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
* </pre>
|
||||
* @param setterPrefix the prefix for setter methods
|
||||
*/
|
||||
private MethodDeclaration generateStaticFillValuesMethod(EclipseNode tdParent, String builderClassName, TypeParameter[] typeParams, java.util.List<BuilderFieldData> builderFields, ASTNode source, String setterPrefix) {
|
||||
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) tdParent.top().get()).compilationResult);
|
||||
private MethodDeclaration generateStaticFillValuesMethod(BuilderJob job, String setterPrefix) {
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.selector = FILL_VALUES_STATIC_METHOD_NAME;
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
out.modifiers = ClassFileConstants.AccPrivate | ClassFileConstants.AccStatic;
|
||||
out.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
|
||||
|
||||
TypeReference[] wildcards = new TypeReference[] {new Wildcard(Wildcard.UNBOUND), new Wildcard(Wildcard.UNBOUND)};
|
||||
TypeReference builderType = generateParameterizedTypeReference(tdParent, builderClassName.toCharArray(), false, mergeToTypeReferences(typeParams, wildcards), 0);
|
||||
TypeReference builderType = generateParameterizedTypeReference(job.parentType, job.builderClassNameArr, false, mergeToTypeReferences(job.typeParams, wildcards), 0);
|
||||
Argument builderArgument = new Argument(BUILDER_VARIABLE_NAME, 0, builderType, Modifier.FINAL);
|
||||
TypeReference[] typerefs = null;
|
||||
if (typeParams.length > 0) {
|
||||
typerefs = new TypeReference[typeParams.length];
|
||||
for (int i = 0; i < typeParams.length; i++) typerefs[i] = new SingleTypeReference(typeParams[i].name, 0);
|
||||
if (job.typeParams.length > 0) {
|
||||
typerefs = new TypeReference[job.typeParams.length];
|
||||
for (int i = 0; i < job.typeParams.length; i++) typerefs[i] = new SingleTypeReference(job.typeParams[i].name, 0);
|
||||
}
|
||||
|
||||
long p = source.sourceStart;
|
||||
p = (p << 32) | source.sourceEnd;
|
||||
long p = job.getPos();
|
||||
|
||||
TypeReference parentArgument = typerefs == null ? generateTypeReference(tdParent, p) : generateParameterizedTypeReference(tdParent, typerefs, p);
|
||||
TypeReference parentArgument = typerefs == null ? generateTypeReference(job.parentType, p) : generateParameterizedTypeReference(job.parentType, typerefs, p);
|
||||
out.arguments = new Argument[] {new Argument(INSTANCE_VARIABLE_NAME, 0, parentArgument, Modifier.FINAL), builderArgument};
|
||||
|
||||
// Add type params if there are any.
|
||||
if (typeParams.length > 0) out.typeParameters = copyTypeParams(typeParams, source);
|
||||
if (job.typeParams.length > 0) out.typeParameters = copyTypeParams(job.typeParams, job.source);
|
||||
|
||||
List<Statement> body = new ArrayList<Statement>();
|
||||
|
||||
// Call the builder's setter methods to fill the values from the instance.
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
MessageSend exec = createSetterCallWithInstanceValue(bfd, tdParent, source, setterPrefix);
|
||||
for (BuilderFieldData bfd : job.builderFields) {
|
||||
MessageSend exec = createSetterCallWithInstanceValue(bfd, job.parentType, job.source, setterPrefix);
|
||||
body.add(exec);
|
||||
}
|
||||
|
||||
out.statements = body.isEmpty() ? null : body.toArray(new Statement[0]);
|
||||
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -783,14 +817,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
return ms;
|
||||
}
|
||||
|
||||
private MethodDeclaration generateAbstractSelfMethod(CheckerFrameworkVersion cfv, EclipseNode tdParent, boolean override, String builderGenericName) {
|
||||
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) tdParent.top().get()).compilationResult);
|
||||
private MethodDeclaration generateAbstractSelfMethod(BuilderJob job, boolean override, String builderGenericName) {
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.selector = SELF_METHOD_NAME;
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
out.modifiers = ClassFileConstants.AccAbstract | ClassFileConstants.AccProtected | ExtraCompilerModifiers.AccSemicolonBody;
|
||||
Annotation overrideAnn = override ? makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, tdParent.get()) : null;
|
||||
Annotation rrAnn = cfv.generateReturnsReceiver() ? generateNamedAnnotation(tdParent.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER): null;
|
||||
Annotation sefAnn = cfv.generatePure() ? generateNamedAnnotation(tdParent.get(), CheckerFrameworkVersion.NAME__PURE): null;
|
||||
Annotation overrideAnn = override ? makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.parentType.get()) : null;
|
||||
Annotation rrAnn = job.checkerFramework.generateReturnsReceiver() ? generateNamedAnnotation(job.parentType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER): null;
|
||||
Annotation sefAnn = job.checkerFramework.generatePure() ? generateNamedAnnotation(job.parentType.get(), CheckerFrameworkVersion.NAME__PURE): null;
|
||||
if (overrideAnn != null && rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn, sefAnn};
|
||||
else if (overrideAnn != null && rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn};
|
||||
else if (overrideAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
|
||||
@@ -802,54 +836,52 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
return out;
|
||||
}
|
||||
|
||||
private MethodDeclaration generateSelfMethod(CheckerFrameworkVersion cfv, EclipseNode builderImplType, TypeParameter[] typeParams, long p) {
|
||||
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) builderImplType.top().get()).compilationResult);
|
||||
private MethodDeclaration generateSelfMethod(BuilderJob job) {
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.selector = SELF_METHOD_NAME;
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
out.modifiers = ClassFileConstants.AccProtected;
|
||||
Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, builderImplType.get());
|
||||
Annotation rrAnn = cfv.generateReturnsReceiver() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) : null;
|
||||
Annotation sefAnn = cfv.generatePure() ? generateNamedAnnotation(builderImplType.get(), CheckerFrameworkVersion.NAME__PURE) : null;
|
||||
Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.builderType.get());
|
||||
Annotation rrAnn = job.checkerFramework.generateReturnsReceiver() ? generateNamedAnnotation(job.builderType.get(), CheckerFrameworkVersion.NAME__RETURNS_RECEIVER) : null;
|
||||
Annotation sefAnn = job.checkerFramework.generatePure() ? generateNamedAnnotation(job.builderType.get(), CheckerFrameworkVersion.NAME__PURE) : null;
|
||||
if (rrAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn, sefAnn};
|
||||
else if (rrAnn != null) out.annotations = new Annotation[] {overrideAnn, rrAnn};
|
||||
else if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
|
||||
else out.annotations = new Annotation[] {overrideAnn};
|
||||
out.returnType = namePlusTypeParamsToTypeReference(builderImplType, typeParams, p);
|
||||
out.returnType = namePlusTypeParamsToTypeReference(job.builderType, job.typeParams, job.getPos());
|
||||
out.statements = new Statement[] {new ReturnStatement(new ThisReference(0, 0), 0, 0)};
|
||||
return out;
|
||||
}
|
||||
|
||||
private MethodDeclaration generateAbstractBuildMethod(CheckerFrameworkVersion cfv, EclipseNode builderType, String methodName, List<BuilderFieldData> builderFields, boolean override,
|
||||
String classGenericName, ASTNode source) {
|
||||
|
||||
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
|
||||
private MethodDeclaration generateAbstractBuildMethod(BuilderJob job, boolean override, String classGenericName) {
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
|
||||
out.modifiers = ClassFileConstants.AccPublic | ClassFileConstants.AccAbstract | ExtraCompilerModifiers.AccSemicolonBody;
|
||||
out.selector = methodName.toCharArray();
|
||||
out.selector = job.buildMethodName.toCharArray();
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
out.returnType = new SingleTypeReference(classGenericName.toCharArray(), 0);
|
||||
Annotation overrideAnn = override ? makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source) : null;
|
||||
Annotation sefAnn = cfv.generateSideEffectFree() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE): null;
|
||||
Annotation overrideAnn = override ? makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.source) : null;
|
||||
Annotation sefAnn = job.checkerFramework.generateSideEffectFree() ? generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE): null;
|
||||
if (overrideAnn != null && sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
|
||||
else if (overrideAnn != null) out.annotations = new Annotation[] {overrideAnn};
|
||||
else if (sefAnn != null) out.annotations = new Annotation[] {sefAnn};
|
||||
out.receiver = HandleBuilder.generateBuildReceiver(cfv, builderType, builderFields, source);
|
||||
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
|
||||
out.receiver = HandleBuilder.generateBuildReceiver(job);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
return out;
|
||||
}
|
||||
|
||||
private MethodDeclaration generateBuildMethod(CheckerFrameworkVersion cfv, EclipseNode builderType, String name, TypeReference returnType, List<BuilderFieldData> builderFields, ASTNode source) {
|
||||
MethodDeclaration out = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
|
||||
private MethodDeclaration generateBuildMethod(BuilderJob job, TypeReference returnType) {
|
||||
MethodDeclaration out = job.createNewMethodDeclaration();
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
List<Statement> statements = new ArrayList<Statement>();
|
||||
|
||||
out.modifiers = ClassFileConstants.AccPublic;
|
||||
out.selector = name.toCharArray();
|
||||
out.selector = job.buildMethodName.toCharArray();
|
||||
out.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
out.returnType = returnType;
|
||||
Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, source);
|
||||
Annotation sefAnn = cfv.generateSideEffectFree() ? generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE): null;
|
||||
Annotation overrideAnn = makeMarkerAnnotation(TypeConstants.JAVA_LANG_OVERRIDE, job.source);
|
||||
Annotation sefAnn = job.checkerFramework.generateSideEffectFree() ? generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE): null;
|
||||
if (sefAnn != null) out.annotations = new Annotation[] {overrideAnn, sefAnn};
|
||||
else out.annotations = new Annotation[] {overrideAnn};
|
||||
|
||||
@@ -859,43 +891,44 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
allocationStatement.arguments = new Expression[] {new ThisReference(0, 0)};
|
||||
statements.add(new ReturnStatement(allocationStatement, 0, 0));
|
||||
out.statements = statements.isEmpty() ? null : statements.toArray(new Statement[0]);
|
||||
out.receiver = HandleBuilder.generateBuildReceiver(cfv, builderType, builderFields, source);
|
||||
createRelevantNonNullAnnotation(builderType, out);
|
||||
out.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
|
||||
out.receiver = HandleBuilder.generateBuildReceiver(job);
|
||||
createRelevantNonNullAnnotation(job.builderType, out);
|
||||
out.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
return out;
|
||||
}
|
||||
|
||||
private MethodDeclaration generateCleanMethod(List<BuilderFieldData> builderFields, EclipseNode builderType, ASTNode source) {
|
||||
private MethodDeclaration generateCleanMethod(BuilderJob job) {
|
||||
List<Statement> statements = new ArrayList<Statement>();
|
||||
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
for (BuilderFieldData bfd : job.builderFields) {
|
||||
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
|
||||
bfd.singularData.getSingularizer().appendCleaningCode(bfd.singularData, builderType, statements);
|
||||
bfd.singularData.getSingularizer().appendCleaningCode(bfd.singularData, job.builderType, statements);
|
||||
}
|
||||
}
|
||||
|
||||
FieldReference thisUnclean = new FieldReference(CLEAN_FIELD_NAME, 0);
|
||||
thisUnclean.receiver = new ThisReference(0, 0);
|
||||
statements.add(new Assignment(thisUnclean, new FalseLiteral(0, 0), 0));
|
||||
MethodDeclaration decl = new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
|
||||
MethodDeclaration decl = job.createNewMethodDeclaration();
|
||||
//new MethodDeclaration(((CompilationUnitDeclaration) builderType.top().get()).compilationResult);
|
||||
decl.selector = CLEAN_METHOD_NAME;
|
||||
decl.modifiers = ClassFileConstants.AccPrivate;
|
||||
decl.bits |= ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
decl.returnType = TypeReference.baseTypeReference(TypeIds.T_void, 0);
|
||||
decl.statements = statements.toArray(new Statement[0]);
|
||||
decl.traverse(new SetGeneratedByVisitor(source), (ClassScope) null);
|
||||
decl.traverse(new SetGeneratedByVisitor(job.source), (ClassScope) null);
|
||||
return decl;
|
||||
}
|
||||
|
||||
private void generateBuilderFields(EclipseNode builderType, List<BuilderFieldData> builderFields, ASTNode source) {
|
||||
private void generateBuilderFields(BuilderJob job) {
|
||||
List<EclipseNode> existing = new ArrayList<EclipseNode>();
|
||||
for (EclipseNode child : builderType.down()) {
|
||||
for (EclipseNode child : job.builderType.down()) {
|
||||
if (child.getKind() == Kind.FIELD) existing.add(child);
|
||||
}
|
||||
|
||||
for (BuilderFieldData bfd : builderFields) {
|
||||
for (BuilderFieldData bfd : job.builderFields) {
|
||||
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
|
||||
bfd.createdFields.addAll(bfd.singularData.getSingularizer().generateFields(bfd.singularData, builderType));
|
||||
bfd.createdFields.addAll(bfd.singularData.getSingularizer().generateFields(bfd.singularData, job.builderType));
|
||||
} else {
|
||||
EclipseNode field = null, setFlag = null;
|
||||
for (EclipseNode exists : existing) {
|
||||
@@ -909,23 +942,23 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
fd.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
fd.modifiers = ClassFileConstants.AccPrivate;
|
||||
fd.type = copyType(bfd.type);
|
||||
fd.traverse(new SetGeneratedByVisitor(source), (MethodScope) null);
|
||||
field = injectFieldAndMarkGenerated(builderType, fd);
|
||||
fd.traverse(new SetGeneratedByVisitor(job.source), (MethodScope) null);
|
||||
field = injectFieldAndMarkGenerated(job.builderType, fd);
|
||||
}
|
||||
if (setFlag == null && bfd.nameOfSetFlag != null) {
|
||||
FieldDeclaration fd = new FieldDeclaration(bfd.nameOfSetFlag, 0, 0);
|
||||
fd.bits |= Eclipse.ECLIPSE_DO_NOT_TOUCH_FLAG;
|
||||
fd.modifiers = ClassFileConstants.AccPrivate;
|
||||
fd.type = TypeReference.baseTypeReference(TypeIds.T_boolean, 0);
|
||||
fd.traverse(new SetGeneratedByVisitor(source), (MethodScope) null);
|
||||
injectFieldAndMarkGenerated(builderType, fd);
|
||||
fd.traverse(new SetGeneratedByVisitor(job.source), (MethodScope) null);
|
||||
injectFieldAndMarkGenerated(job.builderType, fd);
|
||||
}
|
||||
bfd.createdFields.add(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void generateSetterMethodsForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, BuilderFieldData bfd, EclipseNode sourceNode, final String builderGenericName, String setterPrefix) {
|
||||
private void generateSetterMethodsForBuilder(BuilderJob job, BuilderFieldData bfd, final String builderGenericName, String setterPrefix) {
|
||||
boolean deprecate = isFieldDeprecated(bfd.originalFieldNode);
|
||||
|
||||
TypeReferenceMaker returnTypeMaker = new TypeReferenceMaker() {
|
||||
@@ -944,15 +977,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
};
|
||||
|
||||
if (bfd.singularData == null || bfd.singularData.getSingularizer() == null) {
|
||||
generateSimpleSetterMethodForBuilder(cfv, builderType, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, returnTypeMaker.make(), returnStatementMaker.make(), sourceNode, bfd.annotations, bfd.originalFieldNode, setterPrefix);
|
||||
generateSimpleSetterMethodForBuilder(job, deprecate, bfd.createdFields.get(0), bfd.name, bfd.nameOfSetFlag, returnTypeMaker.make(), returnStatementMaker.make(), bfd.annotations, bfd.originalFieldNode, setterPrefix);
|
||||
} else {
|
||||
bfd.singularData.getSingularizer().generateMethods(cfv, bfd.singularData, deprecate, builderType, true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
|
||||
bfd.singularData.getSingularizer().generateMethods(job.checkerFramework, bfd.singularData, deprecate, job.builderType, true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateSimpleSetterMethodForBuilder(CheckerFrameworkVersion cfv, EclipseNode builderType, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, TypeReference returnType, Statement returnStatement, EclipseNode sourceNode, Annotation[] annosOnParam, EclipseNode originalFieldNode, String setterPrefix) {
|
||||
TypeDeclaration td = (TypeDeclaration) builderType.get();
|
||||
ASTNode source = sourceNode.get();
|
||||
|
||||
private void generateSimpleSetterMethodForBuilder(BuilderJob job, boolean deprecate, EclipseNode fieldNode, char[] paramName, char[] nameOfSetFlag, TypeReference returnType, Statement returnStatement, Annotation[] annosOnParam, EclipseNode originalFieldNode, String setterPrefix) {
|
||||
TypeDeclaration td = (TypeDeclaration) job.builderType.get();
|
||||
AbstractMethodDeclaration[] existing = td.methods;
|
||||
if (existing == null) existing = EMPTY_METHODS;
|
||||
int len = existing.length;
|
||||
@@ -966,23 +998,14 @@ public class HandleSuperBuilder extends EclipseAnnotationHandler<SuperBuilder> {
|
||||
}
|
||||
|
||||
List<Annotation> methodAnnsList = Arrays.asList(EclipseHandlerUtil.findCopyableToSetterAnnotations(originalFieldNode));
|
||||
if (cfv.generateReturnsReceiver()) {
|
||||
if (job.checkerFramework.generateReturnsReceiver()) {
|
||||
methodAnnsList = new ArrayList<Annotation>(methodAnnsList);
|
||||
methodAnnsList.add(generateNamedAnnotation(source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER));
|
||||
methodAnnsList.add(generateNamedAnnotation(job.source, CheckerFrameworkVersion.NAME__RETURNS_RECEIVER));
|
||||
}
|
||||
MethodDeclaration setter = HandleSetter.createSetter(td, deprecate, fieldNode, setterName, paramName, nameOfSetFlag, returnType, returnStatement, ClassFileConstants.AccPublic,
|
||||
sourceNode, methodAnnsList, annosOnParam != null ? Arrays.asList(copyAnnotations(source, annosOnParam)) : Collections.<Annotation>emptyList());
|
||||
if (cfv.generateCalledMethods()) {
|
||||
char[][] nameNotCalled = fromQualifiedName(CheckerFrameworkVersion.NAME__NOT_CALLED);
|
||||
SingleMemberAnnotation ann = new SingleMemberAnnotation(new QualifiedTypeReference(nameNotCalled, poss(source, nameNotCalled.length)), source.sourceStart);
|
||||
ann.memberValue = new StringLiteral(setterName.toCharArray(), 0, 0, 0);
|
||||
|
||||
QualifiedTypeReference typeReference = (QualifiedTypeReference) generateTypeReference(builderType, 0);
|
||||
typeReference.annotations = new Annotation[typeReference.tokens.length][];
|
||||
typeReference.annotations[0] = new Annotation[] {ann};
|
||||
setter.receiver = new Receiver(new char[] { 't', 'h', 'i', 's' }, 0, typeReference, null, Modifier.FINAL);
|
||||
}
|
||||
injectMethod(builderType, setter);
|
||||
job.sourceNode, methodAnnsList, annosOnParam != null ? Arrays.asList(copyAnnotations(job.source, annosOnParam)) : Collections.<Annotation>emptyList());
|
||||
if (job.checkerFramework.generateCalledMethods()) setter.receiver = generateNotCalledReceiver(job, setterName);
|
||||
injectMethod(job.builderType, setter);
|
||||
}
|
||||
|
||||
private void addObtainVia(BuilderFieldData bfd, EclipseNode node) {
|
||||
|
||||
@@ -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);
|
||||
BuilderJob job = new BuilderJob();
|
||||
job.sourceNode = annotationNode;
|
||||
job.source = ast;
|
||||
job.checkerFramework = getCheckerFrameworkVersion(annotationNode);
|
||||
job.isStatic = true;
|
||||
|
||||
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();
|
||||
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));
|
||||
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);
|
||||
}
|
||||
recursiveSetGeneratedBy(newMethod, source.get(), builderType.getContext());
|
||||
if (source.up().getKind() == Kind.METHOD) {
|
||||
copyJavadocFromParam(originalFieldNode.up(), newMethod, paramName.toString());
|
||||
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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) { */ {
|
||||
|
||||
@@ -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);
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -2,12 +2,6 @@ class CheckerFrameworkBasic {
|
||||
private final int x;
|
||||
private final int y;
|
||||
private int z;
|
||||
@org.checkerframework.common.aliasing.qual.Unique
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBasic(final int x, final int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
@org.checkerframework.dataflow.qual.Pure
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public int getX() {
|
||||
@@ -23,7 +17,7 @@ class CheckerFrameworkBasic {
|
||||
public int getZ() {
|
||||
return this.z;
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBasic setZ(final int z) {
|
||||
this.z = z;
|
||||
@@ -64,6 +58,12 @@ class CheckerFrameworkBasic {
|
||||
public java.lang.String toString() {
|
||||
return "CheckerFrameworkBasic(x=" + this.getX() + ", y=" + this.getY() + ", z=" + this.getZ() + ")";
|
||||
}
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBasic(final int x, final int y, final int z) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
@org.checkerframework.dataflow.qual.SideEffectFree
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBasic withX(final int x) {
|
||||
|
||||
@@ -9,7 +9,6 @@ class CheckerFrameworkBuilder {
|
||||
private static int $default$x() {
|
||||
return 5;
|
||||
}
|
||||
@org.checkerframework.common.aliasing.qual.Unique
|
||||
@java.lang.SuppressWarnings("all")
|
||||
CheckerFrameworkBuilder(final int x, final int y, final int z, final List<String> names) {
|
||||
this.x = x;
|
||||
@@ -29,37 +28,36 @@ class CheckerFrameworkBuilder {
|
||||
private int z;
|
||||
@java.lang.SuppressWarnings("all")
|
||||
private java.util.ArrayList<String> names;
|
||||
@org.checkerframework.common.aliasing.qual.Unique
|
||||
@java.lang.SuppressWarnings("all")
|
||||
CheckerFrameworkBuilderBuilder() {
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder x(@org.checkerframework.checker.builder.qual.NotCalledMethods("x") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder this, final int x) {
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder x(CheckerFrameworkBuilder.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("x") CheckerFrameworkBuilderBuilder this, final int x) {
|
||||
this.x$value = x;
|
||||
x$set = true;
|
||||
return this;
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder y(@org.checkerframework.checker.builder.qual.NotCalledMethods("y") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder this, final int y) {
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder y(CheckerFrameworkBuilder.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("y") CheckerFrameworkBuilderBuilder this, final int y) {
|
||||
this.y = y;
|
||||
return this;
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder z(@org.checkerframework.checker.builder.qual.NotCalledMethods("z") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder this, final int z) {
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder z(CheckerFrameworkBuilder.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("z") CheckerFrameworkBuilderBuilder this, final int z) {
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder name(final String name) {
|
||||
if (this.names == null) this.names = new java.util.ArrayList<String>();
|
||||
this.names.add(name);
|
||||
return this;
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder names(final java.util.Collection<? extends String> names) {
|
||||
if (names == null) {
|
||||
@@ -69,7 +67,7 @@ class CheckerFrameworkBuilder {
|
||||
this.names.addAll(names);
|
||||
return this;
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder clearNames() {
|
||||
if (this.names != null) this.names.clear();
|
||||
@@ -77,7 +75,7 @@ class CheckerFrameworkBuilder {
|
||||
}
|
||||
@org.checkerframework.dataflow.qual.SideEffectFree
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkBuilder build(@org.checkerframework.checker.builder.qual.CalledMethods({"y", "z"}) CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder this) {
|
||||
public CheckerFrameworkBuilder build(CheckerFrameworkBuilder.@org.checkerframework.checker.objectconstruction.qual.CalledMethods({"y", "z"}) CheckerFrameworkBuilderBuilder this) {
|
||||
java.util.List<String> names;
|
||||
switch (this.names == null ? 0 : this.names.size()) {
|
||||
case 0:
|
||||
@@ -100,10 +98,10 @@ class CheckerFrameworkBuilder {
|
||||
return "CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder(x$value=" + this.x$value + ", y=" + this.y + ", z=" + this.z + ", names=" + this.names + ")";
|
||||
}
|
||||
}
|
||||
@org.checkerframework.common.aliasing.qual.Unique
|
||||
|
||||
@org.checkerframework.dataflow.qual.SideEffectFree
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public static CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder builder() {
|
||||
public static CheckerFrameworkBuilder.@org.checkerframework.common.aliasing.qual.Unique CheckerFrameworkBuilderBuilder builder() {
|
||||
return new CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder();
|
||||
}
|
||||
}
|
||||
@@ -22,40 +22,40 @@ class CheckerFrameworkSuperBuilder {
|
||||
private int z;
|
||||
@java.lang.SuppressWarnings("all")
|
||||
private java.util.ArrayList<String> names;
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@org.checkerframework.dataflow.qual.Pure
|
||||
@java.lang.SuppressWarnings("all")
|
||||
protected abstract B self();
|
||||
@org.checkerframework.dataflow.qual.SideEffectFree
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public abstract C build(@org.checkerframework.checker.builder.qual.CalledMethods({"y", "z"}) CheckerFrameworkSuperBuilder.Parent this);
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
public abstract C build(CheckerFrameworkSuperBuilder.Parent.@org.checkerframework.checker.objectconstruction.qual.CalledMethods({"y", "z"}) ParentBuilder<C, B> this);
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public B x(@org.checkerframework.checker.builder.qual.NotCalledMethods("x") CheckerFrameworkSuperBuilder.Parent.ParentBuilder<C, B> this, final int x) {
|
||||
public B x(CheckerFrameworkSuperBuilder.Parent.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("x") ParentBuilder<C, B> this, final int x) {
|
||||
this.x$value = x;
|
||||
x$set = true;
|
||||
return self();
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public B y(@org.checkerframework.checker.builder.qual.NotCalledMethods("y") CheckerFrameworkSuperBuilder.Parent.ParentBuilder<C, B> this, final int y) {
|
||||
public B y(CheckerFrameworkSuperBuilder.Parent.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("y") ParentBuilder<C, B> this, final int y) {
|
||||
this.y = y;
|
||||
return self();
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public B z(@org.checkerframework.checker.builder.qual.NotCalledMethods("z") CheckerFrameworkSuperBuilder.Parent.ParentBuilder<C, B> this, final int z) {
|
||||
public B z(CheckerFrameworkSuperBuilder.Parent.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("z") ParentBuilder<C, B> this, final int z) {
|
||||
this.z = z;
|
||||
return self();
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public B name(final String name) {
|
||||
if (this.names == null) this.names = new java.util.ArrayList<String>();
|
||||
this.names.add(name);
|
||||
return self();
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public B names(final java.util.Collection<? extends String> names) {
|
||||
if (names == null) {
|
||||
@@ -65,7 +65,7 @@ class CheckerFrameworkSuperBuilder {
|
||||
this.names.addAll(names);
|
||||
return self();
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public B clearNames() {
|
||||
if (this.names != null) this.names.clear();
|
||||
@@ -80,12 +80,11 @@ class CheckerFrameworkSuperBuilder {
|
||||
}
|
||||
@java.lang.SuppressWarnings("all")
|
||||
private static final class ParentBuilderImpl extends CheckerFrameworkSuperBuilder.Parent.ParentBuilder<CheckerFrameworkSuperBuilder.Parent, CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl> {
|
||||
@org.checkerframework.common.aliasing.qual.Unique
|
||||
@java.lang.SuppressWarnings("all")
|
||||
private ParentBuilderImpl() {
|
||||
}
|
||||
@java.lang.Override
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@org.checkerframework.dataflow.qual.Pure
|
||||
@java.lang.SuppressWarnings("all")
|
||||
protected CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl self() {
|
||||
@@ -94,7 +93,7 @@ class CheckerFrameworkSuperBuilder {
|
||||
@org.checkerframework.dataflow.qual.SideEffectFree
|
||||
@java.lang.Override
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkSuperBuilder.Parent build(@org.checkerframework.checker.builder.qual.CalledMethods({"y", "z"}) CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl this) {
|
||||
public CheckerFrameworkSuperBuilder.Parent build(CheckerFrameworkSuperBuilder.Parent.@org.checkerframework.checker.objectconstruction.qual.CalledMethods({"y", "z"}) ParentBuilderImpl this) {
|
||||
return new CheckerFrameworkSuperBuilder.Parent(this);
|
||||
}
|
||||
}
|
||||
@@ -140,24 +139,24 @@ class CheckerFrameworkSuperBuilder {
|
||||
@java.lang.SuppressWarnings("all")
|
||||
private int b;
|
||||
@java.lang.Override
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@org.checkerframework.dataflow.qual.Pure
|
||||
@java.lang.SuppressWarnings("all")
|
||||
protected abstract B self();
|
||||
@org.checkerframework.dataflow.qual.SideEffectFree
|
||||
@java.lang.Override
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public abstract C build(@org.checkerframework.checker.builder.qual.CalledMethods("b") CheckerFrameworkSuperBuilder.ZChild this);
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
public abstract C build(CheckerFrameworkSuperBuilder.ZChild.@org.checkerframework.checker.objectconstruction.qual.CalledMethods("b") ZChildBuilder<C, B> this);
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public B a(@org.checkerframework.checker.builder.qual.NotCalledMethods("a") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<C, B> this, final int a) {
|
||||
public B a(CheckerFrameworkSuperBuilder.ZChild.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("a") ZChildBuilder<C, B> this, final int a) {
|
||||
this.a$value = a;
|
||||
a$set = true;
|
||||
return self();
|
||||
}
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public B b(@org.checkerframework.checker.builder.qual.NotCalledMethods("b") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<C, B> this, final int b) {
|
||||
public B b(CheckerFrameworkSuperBuilder.ZChild.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("b") ZChildBuilder<C, B> this, final int b) {
|
||||
this.b = b;
|
||||
return self();
|
||||
}
|
||||
@@ -170,12 +169,11 @@ class CheckerFrameworkSuperBuilder {
|
||||
}
|
||||
@java.lang.SuppressWarnings("all")
|
||||
private static final class ZChildBuilderImpl extends CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<CheckerFrameworkSuperBuilder.ZChild, CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl> {
|
||||
@org.checkerframework.common.aliasing.qual.Unique
|
||||
@java.lang.SuppressWarnings("all")
|
||||
private ZChildBuilderImpl() {
|
||||
}
|
||||
@java.lang.Override
|
||||
@org.checkerframework.checker.builder.qual.ReturnsReceiver
|
||||
@org.checkerframework.common.returnsreceiver.qual.This
|
||||
@org.checkerframework.dataflow.qual.Pure
|
||||
@java.lang.SuppressWarnings("all")
|
||||
protected CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl self() {
|
||||
@@ -184,7 +182,7 @@ class CheckerFrameworkSuperBuilder {
|
||||
@org.checkerframework.dataflow.qual.SideEffectFree
|
||||
@java.lang.Override
|
||||
@java.lang.SuppressWarnings("all")
|
||||
public CheckerFrameworkSuperBuilder.ZChild build(@org.checkerframework.checker.builder.qual.CalledMethods("b") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl this) {
|
||||
public CheckerFrameworkSuperBuilder.ZChild build(CheckerFrameworkSuperBuilder.ZChild.@org.checkerframework.checker.objectconstruction.qual.CalledMethods("b") ZChildBuilderImpl this) {
|
||||
return new CheckerFrameworkSuperBuilder.ZChild(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.With;
|
||||
@Data @Accessors(chain = true) class CheckerFrameworkBasic {
|
||||
@Data @AllArgsConstructor @Accessors(chain = true) class CheckerFrameworkBasic {
|
||||
private final @With int x;
|
||||
private final int y;
|
||||
private int z;
|
||||
@@ -17,7 +18,7 @@ import lombok.With;
|
||||
public @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") int getZ() {
|
||||
return this.z;
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") CheckerFrameworkBasic setZ(final int z) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") CheckerFrameworkBasic setZ(final int z) {
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
@@ -51,9 +52,10 @@ import lombok.With;
|
||||
public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") java.lang.String toString() {
|
||||
return (((((("CheckerFrameworkBasic(x=" + this.getX()) + ", y=") + this.getY()) + ", z=") + this.getZ()) + ")");
|
||||
}
|
||||
public @org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all") CheckerFrameworkBasic(final int x, final int y) {
|
||||
public @java.lang.SuppressWarnings("all") CheckerFrameworkBasic(final int x, final int y, final int z) {
|
||||
super();
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,29 +8,29 @@ import lombok.Singular;
|
||||
private @java.lang.SuppressWarnings("all") int y;
|
||||
private @java.lang.SuppressWarnings("all") int z;
|
||||
private @java.lang.SuppressWarnings("all") java.util.ArrayList<String> names;
|
||||
@org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all") CheckerFrameworkBuilderBuilder() {
|
||||
@java.lang.SuppressWarnings("all") CheckerFrameworkBuilderBuilder() {
|
||||
super();
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder x(final @org.checkerframework.checker.builder.qual.NotCalledMethods("x") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder this, final int x) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder x(CheckerFrameworkBuilder.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("x") CheckerFrameworkBuilderBuilder this, final int x) {
|
||||
this.x$value = x;
|
||||
x$set = true;
|
||||
return this;
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder y(final @org.checkerframework.checker.builder.qual.NotCalledMethods("y") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder this, final int y) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder y(CheckerFrameworkBuilder.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("y") CheckerFrameworkBuilderBuilder this, final int y) {
|
||||
this.y = y;
|
||||
return this;
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder z(final @org.checkerframework.checker.builder.qual.NotCalledMethods("z") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder this, final int z) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder z(CheckerFrameworkBuilder.@org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("z") CheckerFrameworkBuilderBuilder this, final int z) {
|
||||
this.z = z;
|
||||
return this;
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder name(final String name) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder name(final String name) {
|
||||
if ((this.names == null))
|
||||
this.names = new java.util.ArrayList<String>();
|
||||
this.names.add(name);
|
||||
return this;
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder names(final java.util.Collection<? extends String> names) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder names(final java.util.Collection<? extends String> names) {
|
||||
if ((names == null))
|
||||
{
|
||||
throw new java.lang.NullPointerException("names cannot be null");
|
||||
@@ -40,12 +40,12 @@ import lombok.Singular;
|
||||
this.names.addAll(names);
|
||||
return this;
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder clearNames() {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder clearNames() {
|
||||
if ((this.names != null))
|
||||
this.names.clear();
|
||||
return this;
|
||||
}
|
||||
public @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder build(final @org.checkerframework.checker.builder.qual.CalledMethods({"y", "z"}) CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder this) {
|
||||
public @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder build(CheckerFrameworkBuilder.@org.checkerframework.checker.objectconstruction.qual.CalledMethods({"y", "z"}) CheckerFrameworkBuilderBuilder this) {
|
||||
java.util.List<String> names;
|
||||
switch (((this.names == null) ? 0 : this.names.size())) {
|
||||
case 0 :
|
||||
@@ -73,14 +73,14 @@ import lombok.Singular;
|
||||
private static @java.lang.SuppressWarnings("all") int $default$x() {
|
||||
return 5;
|
||||
}
|
||||
@org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder(final int x, final int y, final int z, final List<String> names) {
|
||||
@java.lang.SuppressWarnings("all") CheckerFrameworkBuilder(final int x, final int y, final int z, final List<String> names) {
|
||||
super();
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.names = names;
|
||||
}
|
||||
public static @org.checkerframework.common.aliasing.qual.Unique @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder builder() {
|
||||
public static @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkBuilder.@org.checkerframework.common.aliasing.qual.Unique CheckerFrameworkBuilderBuilder builder() {
|
||||
return new CheckerFrameworkBuilder.CheckerFrameworkBuilderBuilder();
|
||||
}
|
||||
}
|
||||
@@ -11,28 +11,28 @@ class CheckerFrameworkSuperBuilder {
|
||||
public ParentBuilder() {
|
||||
super();
|
||||
}
|
||||
protected abstract @org.checkerframework.checker.builder.qual.ReturnsReceiver @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") B self();
|
||||
public abstract @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") C build(final @org.checkerframework.checker.builder.qual.CalledMethods({"y", "z"}) CheckerFrameworkSuperBuilder.Parent.ParentBuilder this);
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") B x(final @org.checkerframework.checker.builder.qual.NotCalledMethods("x") CheckerFrameworkSuperBuilder.Parent.ParentBuilder this, final int x) {
|
||||
protected abstract @org.checkerframework.common.returnsreceiver.qual.This @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") B self();
|
||||
public abstract @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") C build(CheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.objectconstruction.qual.CalledMethods({"y", "z"}) ParentBuilder<C, B> this);
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B x(CheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("x") ParentBuilder<C, B> this, final int x) {
|
||||
this.x$value = x;
|
||||
x$set = true;
|
||||
return self();
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") B y(final @org.checkerframework.checker.builder.qual.NotCalledMethods("y") CheckerFrameworkSuperBuilder.Parent.ParentBuilder this, final int y) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B y(CheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("y") ParentBuilder<C, B> this, final int y) {
|
||||
this.y = y;
|
||||
return self();
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") B z(final @org.checkerframework.checker.builder.qual.NotCalledMethods("z") CheckerFrameworkSuperBuilder.Parent.ParentBuilder this, final int z) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B z(CheckerFrameworkSuperBuilder.Parent. @org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("z") ParentBuilder<C, B> this, final int z) {
|
||||
this.z = z;
|
||||
return self();
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") B name(final String name) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B name(final String name) {
|
||||
if ((this.names == null))
|
||||
this.names = new java.util.ArrayList<String>();
|
||||
this.names.add(name);
|
||||
return self();
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") B names(final java.util.Collection<? extends String> names) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B names(final java.util.Collection<? extends String> names) {
|
||||
if ((names == null))
|
||||
{
|
||||
throw new java.lang.NullPointerException("names cannot be null");
|
||||
@@ -42,7 +42,7 @@ class CheckerFrameworkSuperBuilder {
|
||||
this.names.addAll(names);
|
||||
return self();
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") B clearNames() {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B clearNames() {
|
||||
if ((this.names != null))
|
||||
this.names.clear();
|
||||
return self();
|
||||
@@ -55,10 +55,10 @@ class CheckerFrameworkSuperBuilder {
|
||||
private ParentBuilderImpl() {
|
||||
super();
|
||||
}
|
||||
protected @java.lang.Override @org.checkerframework.checker.builder.qual.ReturnsReceiver @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl self() {
|
||||
protected @java.lang.Override @org.checkerframework.common.returnsreceiver.qual.This @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl self() {
|
||||
return this;
|
||||
}
|
||||
public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent build(final @org.checkerframework.checker.builder.qual.CalledMethods({"y", "z"}) CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl this) {
|
||||
public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent build(CheckerFrameworkSuperBuilder.Parent.@org.checkerframework.checker.objectconstruction.qual.CalledMethods({"y", "z"}) ParentBuilderImpl this) {
|
||||
return new CheckerFrameworkSuperBuilder.Parent(this);
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ class CheckerFrameworkSuperBuilder {
|
||||
private static @java.lang.SuppressWarnings("all") int $default$x() {
|
||||
return 5;
|
||||
}
|
||||
protected @org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all") Parent(final CheckerFrameworkSuperBuilder.Parent.ParentBuilder<?, ?> b) {
|
||||
protected @java.lang.SuppressWarnings("all") Parent(final CheckerFrameworkSuperBuilder.Parent.ParentBuilder<?, ?> b) {
|
||||
super();
|
||||
if (b.x$set)
|
||||
this.x = b.x$value;
|
||||
@@ -90,7 +90,7 @@ class CheckerFrameworkSuperBuilder {
|
||||
}
|
||||
this.names = names;
|
||||
}
|
||||
public static @org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent.ParentBuilder<?, ?> builder() {
|
||||
public static @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.Parent. @org.checkerframework.common.aliasing.qual.Unique ParentBuilder<?, ?> builder() {
|
||||
return new CheckerFrameworkSuperBuilder.Parent.ParentBuilderImpl();
|
||||
}
|
||||
}
|
||||
@@ -102,14 +102,14 @@ class CheckerFrameworkSuperBuilder {
|
||||
public ZChildBuilder() {
|
||||
super();
|
||||
}
|
||||
protected abstract @java.lang.Override @org.checkerframework.checker.builder.qual.ReturnsReceiver @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") B self();
|
||||
public abstract @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") C build(final @org.checkerframework.checker.builder.qual.CalledMethods("b") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder this);
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") B a(final @org.checkerframework.checker.builder.qual.NotCalledMethods("a") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder this, final int a) {
|
||||
protected abstract @java.lang.Override @org.checkerframework.common.returnsreceiver.qual.This @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") B self();
|
||||
public abstract @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") C build(CheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.checker.objectconstruction.qual.CalledMethods("b") ZChildBuilder<C, B> this);
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B a(CheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("a") ZChildBuilder<C, B> this, final int a) {
|
||||
this.a$value = a;
|
||||
a$set = true;
|
||||
return self();
|
||||
}
|
||||
public @org.checkerframework.checker.builder.qual.ReturnsReceiver @java.lang.SuppressWarnings("all") B b(final @org.checkerframework.checker.builder.qual.NotCalledMethods("b") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder this, final int b) {
|
||||
public @org.checkerframework.common.returnsreceiver.qual.This @java.lang.SuppressWarnings("all") B b(CheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.checker.objectconstruction.qual.NotCalledMethods("b") ZChildBuilder<C, B> this, final int b) {
|
||||
this.b = b;
|
||||
return self();
|
||||
}
|
||||
@@ -121,10 +121,10 @@ class CheckerFrameworkSuperBuilder {
|
||||
private ZChildBuilderImpl() {
|
||||
super();
|
||||
}
|
||||
protected @java.lang.Override @org.checkerframework.checker.builder.qual.ReturnsReceiver @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl self() {
|
||||
protected @java.lang.Override @org.checkerframework.common.returnsreceiver.qual.This @org.checkerframework.dataflow.qual.Pure @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl self() {
|
||||
return this;
|
||||
}
|
||||
public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.ZChild build(final @org.checkerframework.checker.builder.qual.CalledMethods("b") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl this) {
|
||||
public @java.lang.Override @org.checkerframework.dataflow.qual.SideEffectFree @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.ZChild build(CheckerFrameworkSuperBuilder.ZChild.@org.checkerframework.checker.objectconstruction.qual.CalledMethods("b") ZChildBuilderImpl this) {
|
||||
return new CheckerFrameworkSuperBuilder.ZChild(this);
|
||||
}
|
||||
}
|
||||
@@ -133,7 +133,7 @@ class CheckerFrameworkSuperBuilder {
|
||||
private static @java.lang.SuppressWarnings("all") int $default$a() {
|
||||
return 1;
|
||||
}
|
||||
protected @org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all") ZChild(final CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<?, ?> b) {
|
||||
protected @java.lang.SuppressWarnings("all") ZChild(final CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<?, ?> b) {
|
||||
super(b);
|
||||
if (b.a$set)
|
||||
this.a = b.a$value;
|
||||
@@ -141,7 +141,7 @@ class CheckerFrameworkSuperBuilder {
|
||||
this.a = CheckerFrameworkSuperBuilder.ZChild.$default$a();
|
||||
this.b = b.b;
|
||||
}
|
||||
public static @org.checkerframework.common.aliasing.qual.Unique @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.ZChild.ZChildBuilder<?, ?> builder() {
|
||||
public static @java.lang.SuppressWarnings("all") CheckerFrameworkSuperBuilder.ZChild. @org.checkerframework.common.aliasing.qual.Unique ZChildBuilder<?, ?> builder() {
|
||||
return new CheckerFrameworkSuperBuilder.ZChild.ZChildBuilderImpl();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
//CONF: checkerframework = 4.0
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
import lombok.With;
|
||||
|
||||
@Data @Accessors(chain = true)
|
||||
@Data @AllArgsConstructor @Accessors(chain = true)
|
||||
class CheckerFrameworkBasic {
|
||||
@With private final int x;
|
||||
private final int y;
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
6 package org.checkerframework.common.aliasing.qual does not exist
|
||||
8 package org.checkerframework.dataflow.qual does not exist
|
||||
9 package org.checkerframework.dataflow.qual does not exist
|
||||
10 package org.checkerframework.dataflow.qual does not exist
|
||||
@@ -1 +0,0 @@
|
||||
6 package org.checkerframework.common.aliasing.qual does not exist
|
||||
@@ -1,3 +0,0 @@
|
||||
6 package org.checkerframework.dataflow.qual does not exist
|
||||
-1 package org.checkerframework.checker.builder.qual does not exist
|
||||
14 package org.checkerframework.dataflow.qual does not exist
|
||||
@@ -1 +0,0 @@
|
||||
6 org.checkerframework.common cannot be resolved to a type
|
||||
@@ -1 +0,0 @@
|
||||
6 org.checkerframework cannot be resolved to a type
|
||||
@@ -1 +0,0 @@
|
||||
6 org.checkerframework.common cannot be resolved to a type
|
||||
@@ -1,10 +0,0 @@
|
||||
5 package org.checkerframework.common.aliasing.qual does not exist
|
||||
11 package org.checkerframework.dataflow.qual does not exist
|
||||
16 package org.checkerframework.dataflow.qual does not exist
|
||||
21 package org.checkerframework.dataflow.qual does not exist
|
||||
26 package org.checkerframework.checker.builder.qual does not exist
|
||||
32 package org.checkerframework.dataflow.qual does not exist
|
||||
45 package org.checkerframework.dataflow.qual does not exist
|
||||
50 package org.checkerframework.dataflow.qual does not exist
|
||||
61 package org.checkerframework.dataflow.qual does not exist
|
||||
67 package org.checkerframework.dataflow.qual does not exist
|
||||
Reference in new issue
Block a user