use of com.sun.tools.javac.tree.JCTree.JCModifiers in project lombok by rzwitserloot.
the class HandleEqualsAndHashCode method createEquals.
public JCMethodDecl createEquals(JavacNode typeNode, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JavacNode source, List<JCAnnotation> onParam) {
JavacTreeMaker maker = typeNode.getTreeMaker();
Name oName = typeNode.toName("o");
Name otherName = typeNode.toName("other");
Name thisName = typeNode.toName("this");
List<JCAnnotation> annsOnParamOnMethod = List.nil();
JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
List<JCAnnotation> annsOnMethod = List.of(overrideAnnotation);
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(typeNode);
if (checkerFramework.generateSideEffectFree()) {
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
}
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, annsOnMethod);
JCExpression objectType;
if (annsOnParamOnMethod.isEmpty()) {
objectType = genJavaLangTypeRef(typeNode, "Object");
} else {
objectType = chainDots(typeNode, "java", "lang", "Object");
objectType = maker.AnnotatedType(annsOnParamOnMethod, objectType);
}
JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
JCVariableDecl param = maker.VarDef(maker.Modifiers(finalFlag | Flags.PARAMETER, onParam), oName, objectType, null);
JavacHandlerUtil.createRelevantNullableAnnotation(typeNode, param);
final List<JCVariableDecl> params = List.of(param);
/* if (o == this) return true; */
{
statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName), maker.Ident(thisName)), returnBool(maker, true), null));
}
/* if (!(o instanceof Outer.Inner.MyType)) return false; */
{
JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode, false))));
statements.append(maker.If(notInstanceOf, returnBool(maker, false), null));
}
/* Outer.Inner.MyType<?> other = (Outer.Inner.MyType<?>) o; */
{
if (!members.isEmpty() || needsCanEqual) {
final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true);
statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName))));
}
}
/* if (!other.canEqual((java.lang.Object) this)) return false; */
{
if (needsCanEqual) {
List<JCExpression> exprNil = List.nil();
JCExpression thisRef = maker.Ident(thisName);
JCExpression castThisRef = maker.TypeCast(genJavaLangTypeRef(typeNode, "Object"), thisRef);
JCExpression equalityCheck = maker.Apply(exprNil, maker.Select(maker.Ident(otherName), typeNode.toName("canEqual")), List.of(castThisRef));
statements.append(maker.If(maker.Unary(CTC_NOT, equalityCheck), returnBool(maker, false), null));
}
}
/* if (!super.equals(o)) return false; */
if (callSuper) {
JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(oName)));
JCUnary superNotEqual = maker.Unary(CTC_NOT, callToSuper);
statements.append(maker.If(superNotEqual, returnBool(maker, false), null));
}
for (Included<JavacNode, EqualsAndHashCode.Include> member : members) {
JavacNode memberNode = member.getNode();
boolean isMethod = memberNode.getKind() == Kind.METHOD;
JCExpression fType = unnotate(getFieldType(memberNode, fieldAccess));
JCExpression thisFieldAccessor = isMethod ? createMethodAccessor(maker, memberNode) : createFieldAccessor(maker, memberNode, fieldAccess);
JCExpression otherFieldAccessor = isMethod ? createMethodAccessor(maker, memberNode, maker.Ident(otherName)) : createFieldAccessor(maker, memberNode, fieldAccess, maker.Ident(otherName));
if (fType instanceof JCPrimitiveTypeTree) {
switch(((JCPrimitiveTypeTree) fType).getPrimitiveTypeKind()) {
case FLOAT:
/* if (Float.compare(this.fieldName, other.fieldName) != 0) return false; */
statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, false));
break;
case DOUBLE:
/* if (Double.compare(this.fieldName, other.fieldName) != 0) return false; */
statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, true));
break;
default:
/* if (this.fieldName != other.fieldName) return false; */
statements.append(maker.If(maker.Binary(CTC_NOT_EQUAL, thisFieldAccessor, otherFieldAccessor), returnBool(maker, false), null));
break;
}
} else if (fType instanceof JCArrayTypeTree) {
JCArrayTypeTree array = (JCArrayTypeTree) fType;
/* if (!java.util.Arrays.deepEquals(this.fieldName, other.fieldName)) return false; //use equals for primitive arrays. */
boolean multiDim = unnotate(array.elemtype) instanceof JCArrayTypeTree;
boolean primitiveArray = unnotate(array.elemtype) instanceof JCPrimitiveTypeTree;
boolean useDeepEquals = multiDim || !primitiveArray;
JCExpression eqMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals");
List<JCExpression> args = List.of(thisFieldAccessor, otherFieldAccessor);
statements.append(maker.If(maker.Unary(CTC_NOT, maker.Apply(List.<JCExpression>nil(), eqMethod, args)), returnBool(maker, false), null));
} else /* objects */
{
/* final java.lang.Object this$fieldName = this.fieldName; */
/* final java.lang.Object other$fieldName = other.fieldName; */
/* if (this$fieldName == null ? other$fieldName != null : !this$fieldName.equals(other$fieldName)) return false; */
Name thisDollarFieldName = memberNode.toName("this" + (isMethod ? "$$" : "$") + memberNode.getName());
Name otherDollarFieldName = memberNode.toName("other" + (isMethod ? "$$" : "$") + memberNode.getName());
statements.append(maker.VarDef(maker.Modifiers(finalFlag), thisDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), thisFieldAccessor));
statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), otherFieldAccessor));
JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(thisDollarFieldName), maker.Literal(CTC_BOT, null));
JCExpression otherNotEqualsNull = maker.Binary(CTC_NOT_EQUAL, maker.Ident(otherDollarFieldName), maker.Literal(CTC_BOT, null));
JCExpression thisEqualsThat = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(thisDollarFieldName), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(otherDollarFieldName)));
JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(CTC_NOT, thisEqualsThat));
statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null));
}
}
/* return true; */
{
statements.append(returnBool(maker, true));
}
JCBlock body = maker.Block(0, statements.toList());
return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source);
}
use of com.sun.tools.javac.tree.JCTree.JCModifiers in project lombok by rzwitserloot.
the class HandleEqualsAndHashCode method createHashCode.
public JCMethodDecl createHashCode(JavacNode typeNode, java.util.List<Included<JavacNode, EqualsAndHashCode.Include>> members, boolean callSuper, boolean cacheHashCode, FieldAccess fieldAccess, JavacNode source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
List<JCAnnotation> annsOnMethod = List.of(overrideAnnotation);
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(typeNode);
if (cacheHashCode && checkerFramework.generatePure()) {
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()));
} else if (checkerFramework.generateSideEffectFree()) {
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
}
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, annsOnMethod);
JCExpression returnType = maker.TypeIdent(CTC_INT);
ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
Name primeName = typeNode.toName(PRIME_NAME);
Name resultName = typeNode.toName(RESULT_NAME);
long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
boolean isEmpty = members.isEmpty();
/* if (this.$hashCodeCache != 0) return this.$hashCodeCache; */
{
if (cacheHashCode) {
JCIdent receiver = maker.Ident(typeNode.toName("this"));
JCFieldAccess cacheHashCodeFieldAccess = maker.Select(receiver, typeNode.toName(HASH_CODE_CACHE_NAME));
JCExpression cacheNotZero = maker.Binary(CTC_NOT_EQUAL, cacheHashCodeFieldAccess, maker.Literal(CTC_INT, 0));
statements.append(maker.If(cacheNotZero, maker.Return(cacheHashCodeFieldAccess), null));
}
}
/* final int PRIME = X; */
{
if (!isEmpty) {
statements.append(maker.VarDef(maker.Modifiers(finalFlag), primeName, maker.TypeIdent(CTC_INT), maker.Literal(HandlerUtil.primeForHashcode())));
}
}
/* int result = ... */
{
final JCExpression init;
if (callSuper) {
/* ... super.hashCode(); */
init = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("hashCode")), List.<JCExpression>nil());
} else {
/* ... 1; */
init = maker.Literal(1);
}
statements.append(maker.VarDef(maker.Modifiers(isEmpty && !cacheHashCode ? finalFlag : 0L), resultName, maker.TypeIdent(CTC_INT), init));
}
for (Included<JavacNode, EqualsAndHashCode.Include> member : members) {
JavacNode memberNode = member.getNode();
JCExpression fType = unnotate(getFieldType(memberNode, fieldAccess));
boolean isMethod = memberNode.getKind() == Kind.METHOD;
JCExpression fieldAccessor = isMethod ? createMethodAccessor(maker, memberNode) : createFieldAccessor(maker, memberNode, fieldAccess);
if (fType instanceof JCPrimitiveTypeTree) {
switch(((JCPrimitiveTypeTree) fType).getPrimitiveTypeKind()) {
case BOOLEAN:
/* this.fieldName ? X : Y */
statements.append(createResultCalculation(typeNode, maker.Parens(maker.Conditional(fieldAccessor, maker.Literal(HandlerUtil.primeForTrue()), maker.Literal(HandlerUtil.primeForFalse())))));
break;
case LONG:
{
Name dollarFieldName = memberNode.toName((isMethod ? "$$" : "$") + memberNode.getName());
statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, maker.TypeIdent(CTC_LONG), fieldAccessor));
statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName))));
}
break;
case FLOAT:
/* Float.floatToIntBits(this.fieldName) */
statements.append(createResultCalculation(typeNode, maker.Apply(List.<JCExpression>nil(), genJavaLangTypeRef(typeNode, "Float", "floatToIntBits"), List.of(fieldAccessor))));
break;
case DOUBLE:
{
/* longToIntForHashCode(Double.doubleToLongBits(this.fieldName)) */
Name dollarFieldName = memberNode.toName((isMethod ? "$$" : "$") + memberNode.getName());
JCExpression init = maker.Apply(List.<JCExpression>nil(), genJavaLangTypeRef(typeNode, "Double", "doubleToLongBits"), List.of(fieldAccessor));
statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, maker.TypeIdent(CTC_LONG), init));
statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName))));
}
break;
default:
case BYTE:
case SHORT:
case INT:
case CHAR:
/* just the field */
statements.append(createResultCalculation(typeNode, fieldAccessor));
break;
}
} else if (fType instanceof JCArrayTypeTree) {
JCArrayTypeTree array = (JCArrayTypeTree) fType;
/* java.util.Arrays.deepHashCode(this.fieldName) //use just hashCode() for primitive arrays. */
boolean multiDim = unnotate(array.elemtype) instanceof JCArrayTypeTree;
boolean primitiveArray = unnotate(array.elemtype) instanceof JCPrimitiveTypeTree;
boolean useDeepHC = multiDim || !primitiveArray;
JCExpression hcMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepHC ? "deepHashCode" : "hashCode");
statements.append(createResultCalculation(typeNode, maker.Apply(List.<JCExpression>nil(), hcMethod, List.of(fieldAccessor))));
} else /* objects */
{
/* final java.lang.Object $fieldName = this.fieldName; */
/* ($fieldName == null ? NULL_PRIME : $fieldName.hashCode()) */
Name dollarFieldName = memberNode.toName((isMethod ? "$$" : "$") + memberNode.getName());
statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, genJavaLangTypeRef(typeNode, "Object"), fieldAccessor));
JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(dollarFieldName), typeNode.toName("hashCode")), List.<JCExpression>nil());
JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(dollarFieldName), maker.Literal(CTC_BOT, null));
statements.append(createResultCalculation(typeNode, maker.Parens(maker.Conditional(thisEqualsNull, maker.Literal(HandlerUtil.primeForNull()), hcCall))));
}
}
/*
* if (result == 0) result = Integer.MIN_VALUE;
* this.$hashCodeCache = result;
*
*/
{
if (cacheHashCode) {
statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(resultName), maker.Literal(CTC_INT, 0)), maker.Exec(maker.Assign(maker.Ident(resultName), genJavaLangTypeRef(typeNode, "Integer", "MIN_VALUE"))), null));
JCFieldAccess cacheHashCodeFieldAccess = maker.Select(maker.Ident(typeNode.toName("this")), typeNode.toName(HASH_CODE_CACHE_NAME));
statements.append(maker.Exec(maker.Assign(cacheHashCodeFieldAccess, maker.Ident(resultName))));
}
}
/* return result; */
{
statements.append(maker.Return(maker.Ident(resultName)));
}
JCBlock body = maker.Block(0, statements.toList());
return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("hashCode"), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source);
}
use of com.sun.tools.javac.tree.JCTree.JCModifiers in project lombok by rzwitserloot.
the class HandleEqualsAndHashCode method createCanEqual.
public JCMethodDecl createCanEqual(JavacNode typeNode, JavacNode source, List<JCAnnotation> onParam) {
/* protected boolean canEqual(final java.lang.Object other) {
* return other instanceof Outer.Inner.MyType;
* }
*/
JavacTreeMaker maker = typeNode.getTreeMaker();
List<JCAnnotation> annsOnMethod = List.nil();
CheckerFrameworkVersion checkerFramework = getCheckerFrameworkVersion(typeNode);
if (checkerFramework.generatePure()) {
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__PURE), List.<JCExpression>nil()));
}
JCModifiers mods = maker.Modifiers(Flags.PROTECTED, annsOnMethod);
JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
Name canEqualName = typeNode.toName("canEqual");
JCExpression objectType = genJavaLangTypeRef(typeNode, "Object");
Name otherName = typeNode.toName("other");
long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, onParam), otherName, objectType, null);
createRelevantNullableAnnotation(typeNode, param);
List<JCVariableDecl> params = List.of(param);
JCBlock body = maker.Block(0, List.<JCStatement>of(maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode, false)))));
return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source);
}
use of com.sun.tools.javac.tree.JCTree.JCModifiers in project lombok by rzwitserloot.
the class HandleToString method createToString.
static JCMethodDecl createToString(JavacNode typeNode, Collection<Included<JavacNode, ToString.Include>> members, boolean includeNames, boolean callSuper, FieldAccess fieldAccess, JavacNode source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
List<JCAnnotation> annsOnMethod = List.of(overrideAnnotation);
if (getCheckerFrameworkVersion(typeNode).generateSideEffectFree())
annsOnMethod = annsOnMethod.prepend(maker.Annotation(genTypeRef(typeNode, CheckerFrameworkVersion.NAME__SIDE_EFFECT_FREE), List.<JCExpression>nil()));
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, annsOnMethod);
JCExpression returnType = genJavaLangTypeRef(typeNode, "String");
boolean first = true;
String typeName = getTypeName(typeNode);
boolean isEnum = typeNode.isEnumType();
String infix = ", ";
String suffix = ")";
String prefix;
if (callSuper) {
prefix = "(super=";
} else if (members.isEmpty()) {
prefix = isEnum ? "" : "()";
} else if (includeNames) {
Included<JavacNode, ToString.Include> firstMember = members.iterator().next();
String name = firstMember.getInc() == null ? "" : firstMember.getInc().name();
if (name.isEmpty())
name = firstMember.getNode().getName();
prefix = "(" + name + "=";
} else {
prefix = "(";
}
JCExpression current;
if (!isEnum) {
current = maker.Literal(typeName + prefix);
} else {
current = maker.Binary(CTC_PLUS, maker.Literal(typeName + "."), maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("this")), typeNode.toName("name")), List.<JCExpression>nil()));
if (!prefix.isEmpty())
current = maker.Binary(CTC_PLUS, current, maker.Literal(prefix));
}
if (callSuper) {
JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("toString")), List.<JCExpression>nil());
current = maker.Binary(CTC_PLUS, current, callToSuper);
first = false;
}
for (Included<JavacNode, ToString.Include> member : members) {
JCExpression expr;
JCExpression memberAccessor;
JavacNode memberNode = member.getNode();
if (memberNode.getKind() == Kind.METHOD) {
memberAccessor = createMethodAccessor(maker, memberNode);
} else {
memberAccessor = createFieldAccessor(maker, memberNode, fieldAccess);
}
JCExpression memberType = getFieldType(memberNode, fieldAccess);
// The distinction between primitive and object will be useful if we ever add a 'hideNulls' option.
@SuppressWarnings("unused") boolean fieldIsPrimitive = memberType instanceof JCPrimitiveTypeTree;
boolean fieldIsPrimitiveArray = memberType instanceof JCArrayTypeTree && ((JCArrayTypeTree) memberType).elemtype instanceof JCPrimitiveTypeTree;
boolean fieldIsObjectArray = !fieldIsPrimitiveArray && memberType instanceof JCArrayTypeTree;
if (fieldIsPrimitiveArray || fieldIsObjectArray) {
JCExpression tsMethod = chainDots(typeNode, "java", "util", "Arrays", fieldIsObjectArray ? "deepToString" : "toString");
expr = maker.Apply(List.<JCExpression>nil(), tsMethod, List.<JCExpression>of(memberAccessor));
} else
expr = memberAccessor;
if (first) {
current = maker.Binary(CTC_PLUS, current, expr);
first = false;
continue;
}
if (includeNames) {
String n = member.getInc() == null ? "" : member.getInc().name();
if (n.isEmpty())
n = memberNode.getName();
current = maker.Binary(CTC_PLUS, current, maker.Literal(infix + n + "="));
} else {
current = maker.Binary(CTC_PLUS, current, maker.Literal(infix));
}
current = maker.Binary(CTC_PLUS, current, expr);
}
if (!first)
current = maker.Binary(CTC_PLUS, current, maker.Literal(suffix));
JCStatement returnStatement = maker.Return(current);
JCBlock body = maker.Block(0, List.of(returnStatement));
JCMethodDecl methodDef = maker.MethodDef(mods, typeNode.toName("toString"), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null);
createRelevantNonNullAnnotation(typeNode, methodDef);
return recursiveSetGeneratedBy(methodDef, source);
}
use of com.sun.tools.javac.tree.JCTree.JCModifiers 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);
}
Aggregations