use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleSuperBuilder method generateBuilderImplClass.
/**
* Creates and returns the concrete builder implementation class and injects it into the annotated class.
*/
private JavacNode generateBuilderImplClass(SuperBuilderJob job) {
JavacTreeMaker maker = job.getTreeMaker();
JCModifiers mods = maker.Modifiers(Flags.STATIC | Flags.PRIVATE | Flags.FINAL);
// Extend the abstract builder.
JCExpression extending = namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderAbstractClassName), false, List.<JCTypeParameter>nil());
// Add builder-specific type params required for inheritable builders.
// 1. The return type for the build() method (named "C" in the abstract builder), which is the annotated class.
JCExpression annotatedClass = namePlusTypeParamsToTypeReference(maker, job.parentType, job.typeParams);
// 2. The return type for all setter methods (named "B" in the abstract builder), which is this builder class.
JCExpression builderImplClassExpression = namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderImplClassName), false, job.typeParams);
ListBuffer<JCExpression> typeParamsForBuilder = getTypeParamExpressions(job.typeParams, maker, job.sourceNode);
typeParamsForBuilder.append(annotatedClass);
typeParamsForBuilder.append(builderImplClassExpression);
extending = maker.TypeApply(extending, typeParamsForBuilder.toList());
JCClassDecl builder = maker.ClassDef(mods, job.toName(job.builderImplClassName), copyTypeParams(job.parentType, job.typeParams), extending, List.<JCExpression>nil(), List.<JCTree>nil());
recursiveSetGeneratedBy(builder, job.sourceNode);
return injectType(job.parentType, builder);
}
use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleSuperBuilder method generateBuilderMethod.
private JCMethodDecl generateBuilderMethod(SuperBuilderJob job) {
JavacTreeMaker maker = job.getTreeMaker();
JCExpression call = maker.NewClass(null, List.<JCExpression>nil(), namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderImplClassName), false, job.typeParams), List.<JCExpression>nil(), null);
JCStatement statement = maker.Return(call);
JCBlock body = maker.Block(0, List.<JCStatement>of(statement));
int modifiers = Flags.PUBLIC;
modifiers |= Flags.STATIC;
// Add any type params of the annotated class to the return type.
ListBuffer<JCExpression> typeParameterNames = new ListBuffer<JCExpression>();
typeParameterNames.appendList(typeParameterNames(maker, job.typeParams));
// Now add the <?, ?>.
JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParameterNames.append(wildcard);
typeParameterNames.append(wildcard);
// And return type annotations.
List<JCAnnotation> annsOnParamType = List.nil();
if (job.checkerFramework.generateUnique())
annsOnParamType = List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__UNIQUE), List.<JCExpression>nil()));
JCTypeApply returnType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, job.parentType, job.toName(job.builderAbstractClassName), false, List.<JCTypeParameter>nil(), annsOnParamType), typeParameterNames.toList());
List<JCAnnotation> annsOnMethod = job.checkerFramework.generateSideEffectFree() ? List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
JCMethodDecl methodDef = maker.MethodDef(maker.Modifiers(modifiers, annsOnMethod), job.toName(job.builderMethodName), returnType, copyTypeParams(job.sourceNode, job.typeParams), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
createRelevantNonNullAnnotation(job.parentType, methodDef);
return methodDef;
}
use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleSuperBuilder method generateSetterMethodsForBuilder.
private void generateSetterMethodsForBuilder(final SuperBuilderJob job, BuilderFieldData fieldNode, final String builderGenericName, String setterPrefix) {
boolean deprecate = isFieldDeprecated(fieldNode.originalFieldNode);
final JavacTreeMaker maker = job.getTreeMaker();
ExpressionMaker returnTypeMaker = new ExpressionMaker() {
@Override
public JCExpression make() {
return maker.Ident(job.toName(builderGenericName));
}
};
StatementMaker returnStatementMaker = new StatementMaker() {
@Override
public JCStatement make() {
return maker.Return(maker.Apply(List.<JCExpression>nil(), maker.Ident(job.toName(SELF_METHOD)), List.<JCExpression>nil()));
}
};
if (fieldNode.singularData == null || fieldNode.singularData.getSingularizer() == null) {
generateSimpleSetterMethodForBuilder(job, deprecate, fieldNode.createdFields.get(0), fieldNode.name, fieldNode.nameOfSetFlag, returnTypeMaker.make(), returnStatementMaker.make(), fieldNode.annotations, fieldNode.originalFieldNode, setterPrefix);
} else {
fieldNode.singularData.getSingularizer().generateMethods(job.checkerFramework, fieldNode.singularData, deprecate, job.builderType, job.sourceNode, true, returnTypeMaker, returnStatementMaker, AccessLevel.PUBLIC);
}
}
use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleSuperBuilder method generateBuilderBasedConstructor.
/**
* 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 callBuilderBasedSuperConstructor
* If {@code true}, the constructor will explicitly call a super
* constructor with the builder as argument. Requires
* {@code builderClassAsParameter != null}.
*/
private void generateBuilderBasedConstructor(SuperBuilderJob job, boolean callBuilderBasedSuperConstructor) {
JavacTreeMaker maker = job.getTreeMaker();
AccessLevel level = AccessLevel.PROTECTED;
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
Name builderVariableName = job.toName(BUILDER_VARIABLE_NAME);
for (BuilderFieldData bfd : job.builderFields) {
JCExpression rhs;
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, bfd.originalFieldNode, job.sourceNode, statements, bfd.builderFieldName, "b");
rhs = maker.Ident(bfd.singularData.getPluralName());
} else {
rhs = maker.Select(maker.Ident(builderVariableName), bfd.builderFieldName);
}
JCFieldAccess fieldInThis = maker.Select(maker.Ident(job.toName("this")), bfd.rawName);
JCStatement assign = maker.Exec(maker.Assign(fieldInThis, rhs));
// In case of @Builder.Default, set the value to the default if it was not set in the builder.
if (bfd.nameOfSetFlag != null) {
JCFieldAccess setField = maker.Select(maker.Ident(builderVariableName), bfd.nameOfSetFlag);
fieldInThis = maker.Select(maker.Ident(job.toName("this")), bfd.rawName);
JCExpression parentTypeRef = namePlusTypeParamsToTypeReference(maker, job.parentType, List.<JCTypeParameter>nil());
JCAssign assignDefault = maker.Assign(fieldInThis, maker.Apply(typeParameterNames(maker, ((JCClassDecl) job.parentType.get()).typarams), maker.Select(parentTypeRef, bfd.nameOfDefaultProvider), List.<JCExpression>nil()));
statements.append(maker.If(setField, assign, maker.Exec(assignDefault)));
} else {
statements.append(assign);
}
if (hasNonNullAnnotations(bfd.originalFieldNode)) {
JCStatement nullCheck = generateNullCheck(maker, bfd.originalFieldNode, job.sourceNode);
if (nullCheck != null)
statements.append(nullCheck);
}
}
List<JCAnnotation> annsOnMethod = job.checkerFramework.generateSideEffectFree() ? List.of(maker.Annotation(genTypeRef(job.parentType, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil())) : List.<JCAnnotation>nil();
JCModifiers mods = maker.Modifiers(toJavacModifier(level), annsOnMethod);
// Create a constructor that has just the builder as parameter.
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, job.getContext());
// First add all generics that are present on the parent type.
ListBuffer<JCExpression> typeParamsForBuilderParameter = getTypeParamExpressions(job.typeParams, maker, job.sourceNode);
// Now add the <?, ?>.
JCWildcard wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParamsForBuilderParameter.append(wildcard);
wildcard = maker.Wildcard(maker.TypeBoundKind(BoundKind.UNBOUND), null);
typeParamsForBuilderParameter.append(wildcard);
JCTypeApply paramType = maker.TypeApply(namePlusTypeParamsToTypeReference(maker, job.parentType, job.getBuilderClassName(), false, List.<JCTypeParameter>nil()), typeParamsForBuilderParameter.toList());
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags), builderVariableName, paramType, null);
params.append(param);
if (callBuilderBasedSuperConstructor) {
// The first statement must be the call to the super constructor.
JCMethodInvocation callToSuperConstructor = maker.Apply(List.<JCExpression>nil(), maker.Ident(job.toName("super")), List.<JCExpression>of(maker.Ident(builderVariableName)));
statements.prepend(maker.Exec(callToSuperConstructor));
}
JCMethodDecl constr = recursiveSetGeneratedBy(maker.MethodDef(mods, job.toName("<init>"), null, List.<JCTypeParameter>nil(), params.toList(), List.<JCExpression>nil(), maker.Block(0L, statements.toList()), null), job.sourceNode);
injectMethod(job.parentType, constr);
}
use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleSuperBuilder method generateAbstractSelfMethod.
private JCMethodDecl generateAbstractSelfMethod(SuperBuilderJob job, boolean override, String builderGenericName) {
JavacTreeMaker maker = job.getTreeMaker();
List<JCAnnotation> annotations = List.nil();
JCAnnotation overrideAnnotation = override ? maker.Annotation(genJavaLangTypeRef(job.builderType, "Override"), List.<JCExpression>nil()) : null;
JCAnnotation sefAnnotation = job.checkerFramework.generatePure() ? maker.Annotation(genTypeRef(job.builderType, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()) : null;
if (sefAnnotation != null)
annotations = annotations.prepend(sefAnnotation);
if (overrideAnnotation != null)
annotations = annotations.prepend(overrideAnnotation);
JCModifiers modifiers = maker.Modifiers(Flags.PROTECTED | Flags.ABSTRACT, annotations);
Name name = job.toName(SELF_METHOD);
JCExpression returnType = maker.Ident(job.toName(builderGenericName));
returnType = addCheckerFrameworkReturnsReceiver(returnType, maker, job.builderType, job.checkerFramework);
return maker.MethodDef(modifiers, name, returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null);
}
Aggregations