use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleConstructor method createConstructor.
@SuppressWarnings("deprecation")
public static JCMethodDecl createConstructor(AccessLevel level, List<JCAnnotation> onConstructor, JavacNode typeNode, List<JavacNode> fieldsToParam, boolean forceDefaults, JavacNode source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
boolean isEnum = (((JCClassDecl) typeNode.get()).mods.flags & Flags.ENUM) != 0;
if (isEnum)
level = AccessLevel.PRIVATE;
boolean addConstructorProperties;
List<JavacNode> fieldsToDefault = fieldsNeedingBuilderDefaults(typeNode, fieldsToParam);
List<JavacNode> fieldsToExplicit = forceDefaults ? fieldsNeedingExplicitDefaults(typeNode, fieldsToParam) : List.<JavacNode>nil();
if (fieldsToParam.isEmpty()) {
addConstructorProperties = false;
} else {
Boolean v = typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_ADD_CONSTRUCTOR_PROPERTIES);
addConstructorProperties = v != null ? v.booleanValue() : Boolean.FALSE.equals(typeNode.getAst().readConfiguration(ConfigurationKeys.ANY_CONSTRUCTOR_SUPPRESS_CONSTRUCTOR_PROPERTIES));
}
ListBuffer<JCStatement> nullChecks = new ListBuffer<JCStatement>();
ListBuffer<JCStatement> assigns = new ListBuffer<JCStatement>();
ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
for (JavacNode fieldNode : fieldsToParam) {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
Name fieldName = removePrefixFromField(fieldNode);
Name rawName = field.name;
List<JCAnnotation> copyableAnnotations = findCopyableAnnotations(fieldNode);
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
JCExpression pType = cloneType(fieldNode.getTreeMaker(), field.vartype, source);
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, copyableAnnotations), fieldName, pType, null);
params.append(param);
if (hasNonNullAnnotations(fieldNode)) {
JCStatement nullCheck = generateNullCheck(maker, param, source);
if (nullCheck != null)
nullChecks.append(nullCheck);
}
JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), rawName);
JCExpression assign = maker.Assign(thisX, maker.Ident(fieldName));
assigns.append(maker.Exec(assign));
}
for (JavacNode fieldNode : fieldsToExplicit) {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
Name rawName = field.name;
JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), rawName);
JCExpression assign = maker.Assign(thisX, getDefaultExpr(maker, field.vartype));
assigns.append(maker.Exec(assign));
}
for (JavacNode fieldNode : fieldsToDefault) {
JCVariableDecl field = (JCVariableDecl) fieldNode.get();
Name rawName = field.name;
Name fieldName = removePrefixFromField(fieldNode);
Name nameOfDefaultProvider = typeNode.toName("$default$" + fieldName);
JCFieldAccess thisX = maker.Select(maker.Ident(fieldNode.toName("this")), rawName);
JCExpression assign = maker.Assign(thisX, maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(((JCClassDecl) typeNode.get()).name), nameOfDefaultProvider), List.<JCExpression>nil()));
assigns.append(maker.Exec(assign));
}
JCModifiers mods = maker.Modifiers(toJavacModifier(level), List.<JCAnnotation>nil());
if (addConstructorProperties && !isLocalType(typeNode) && LombokOptionsFactory.getDelombokOptions(typeNode.getContext()).getFormatPreferences().generateConstructorProperties()) {
addConstructorProperties(mods, typeNode, fieldsToParam);
}
if (onConstructor != null)
mods.annotations = mods.annotations.appendList(copyAnnotations(onConstructor));
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);
}
use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleBuilder method generateBuildMethod.
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(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 : job.builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
bfd.singularData.getSingularizer().appendBuildCode(bfd.singularData, job.builderType, job.sourceNode, statements, bfd.builderFieldName, "this");
}
}
ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
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, job.sourceNode), 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));
} else {
args.append(maker.Select(maker.Ident(thisName), bfd.builderFieldName));
}
}
if (addCleaning) {
statements.append(maker.Exec(maker.Assign(maker.Select(maker.Ident(job.toName("this")), job.toName(CLEAN_FIELD_NAME)), maker.Literal(CTC_BOOLEAN, 1))));
}
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) job.builderType.get()).typarams) {
typeParams.append(maker.Ident(tp.name));
}
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));
} else {
statements.append(maker.Return(call));
}
}
JCBlock body = maker.Block(0, statements.toList());
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;
}
use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleBuilder method generateBuilderFields.
public void generateBuilderFields(BuilderJob job) {
int len = job.builderFields.size();
java.util.List<JavacNode> existing = new ArrayList<JavacNode>();
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 = job.builderFields.get(i);
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
java.util.List<JavacNode> generateSingularFields = bfd.singularData.getSingularizer().generateFields(bfd.singularData, job.builderType, job.sourceNode);
for (JavacNode field : generateSingularFields) {
generated.add((JCVariableDecl) field.get());
}
bfd.createdFields.addAll(generateSingularFields);
} else {
JavacNode field = null, setFlag = null;
for (JavacNode exists : existing) {
Name n = ((JCVariableDecl) exists.get()).name;
if (n.equals(bfd.builderFieldName))
field = exists;
if (n.equals(bfd.nameOfSetFlag))
setFlag = exists;
}
JavacTreeMaker maker = job.getTreeMaker();
if (field == null) {
JCModifiers mods = maker.Modifiers(Flags.PRIVATE);
JCVariableDecl newField = maker.VarDef(mods, bfd.builderFieldName, cloneType(maker, bfd.type, job.sourceNode), 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(job.builderType, newField);
generated.add(newField);
}
bfd.createdFields.add(field);
}
}
for (JCVariableDecl gen : generated) recursiveSetGeneratedBy(gen, job.sourceNode);
}
use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleBuilder method generateReceiver.
static JCVariableDecl generateReceiver(BuilderJob job) {
if (!job.checkerFramework.generateCalledMethods())
return null;
ArrayList<String> mandatories = new ArrayList<String>();
for (BuilderFieldData bfd : job.builderFields) {
if (bfd.singularData == null && bfd.nameOfSetFlag == null)
mandatories.add(bfd.name.toString());
}
JCExpression arg;
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(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;
}
use of lombok.javac.JavacTreeMaker in project lombok by rzwitserloot.
the class HandleBuilder method makeBuilderClass.
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, job.getBuilderClassName(), job.copyTypeParams(), null, List.<JCExpression>nil(), List.<JCTree>nil());
recursiveSetGeneratedBy(builder, job.sourceNode);
return injectType(job.parentType, builder);
}
Aggregations