use of com.sun.tools.javac.tree.JCTree.JCArrayTypeTree in project lombok by rzwitserloot.
the class HandleBuilder method handle.
@Override
public void handle(AnnotationValues<Builder> annotation, JCAnnotation ast, JavacNode annotationNode) {
Builder builderInstance = annotation.getInstance();
// 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();
java.util.List<Name> typeArgsForToBuilder = null;
if (builderMethodName == null)
builderMethodName = "builder";
if (buildMethodName == null)
buildMethodName = "build";
if (builderClassName == null)
builderClassName = "";
if (!checkName("builderMethodName", builderMethodName, annotationNode))
return;
if (!checkName("buildMethodName", buildMethodName, annotationNode))
return;
if (!builderClassName.isEmpty()) {
if (!checkName("builderClassName", builderClassName, annotationNode))
return;
}
@SuppressWarnings("deprecation") Class<? extends Annotation> oldExperimentalBuilder = lombok.experimental.Builder.class;
deleteAnnotationIfNeccessary(annotationNode, Builder.class, oldExperimentalBuilder);
JavacNode parent = annotationNode.up();
java.util.List<BuilderFieldData> builderFields = new ArrayList<BuilderFieldData>();
JCExpression returnType;
List<JCTypeParameter> typeParams = List.nil();
List<JCExpression> thrownExceptions = List.nil();
Name nameOfBuilderMethod;
JavacNode tdParent;
JavacNode fillParametersFrom = parent.get() instanceof JCMethodDecl ? parent : null;
boolean addCleaning = false;
boolean isStatic = true;
if (parent.get() instanceof JCClassDecl) {
tdParent = parent;
JCClassDecl td = (JCClassDecl) tdParent.get();
ListBuffer<JavacNode> allFields = new ListBuffer<JavacNode>();
@SuppressWarnings("deprecation") boolean valuePresent = (hasAnnotation(lombok.Value.class, parent) || hasAnnotation(lombok.experimental.Value.class, parent));
for (JavacNode fieldNode : HandleConstructor.findAllFields(tdParent)) {
JCVariableDecl fd = (JCVariableDecl) fieldNode.get();
// Value will only skip making a field final if it has an explicit @NonFinal annotation, so we check for that.
if (fd.init != null && valuePresent && !hasAnnotation(NonFinal.class, fieldNode))
continue;
BuilderFieldData bfd = new BuilderFieldData();
bfd.rawName = fd.name;
bfd.name = removePrefixFromField(fieldNode);
bfd.type = fd.vartype;
bfd.singularData = getSingularData(fieldNode);
addObtainVia(bfd, fieldNode);
builderFields.add(bfd);
allFields.append(fieldNode);
}
new HandleConstructor().generateConstructor(tdParent, AccessLevel.PACKAGE, List.<JCAnnotation>nil(), allFields.toList(), false, null, SkipIfConstructorExists.I_AM_BUILDER, annotationNode);
returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
typeParams = td.typarams;
thrownExceptions = List.nil();
nameOfBuilderMethod = null;
if (builderClassName.isEmpty())
builderClassName = td.name.toString() + "Builder";
} else if (fillParametersFrom != null && fillParametersFrom.getName().toString().equals("<init>")) {
JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
if (!jmd.typarams.isEmpty()) {
annotationNode.addError("@Builder is not supported on constructors with constructor type parameters.");
return;
}
tdParent = parent.up();
JCClassDecl td = (JCClassDecl) tdParent.get();
returnType = namePlusTypeParamsToTypeReference(tdParent.getTreeMaker(), td.name, td.typarams);
typeParams = td.typarams;
thrownExceptions = jmd.thrown;
nameOfBuilderMethod = null;
if (builderClassName.isEmpty())
builderClassName = td.name.toString() + "Builder";
} else if (fillParametersFrom != null) {
tdParent = parent.up();
JCClassDecl td = (JCClassDecl) tdParent.get();
JCMethodDecl jmd = (JCMethodDecl) fillParametersFrom.get();
isStatic = (jmd.mods.flags & Flags.STATIC) != 0;
JCExpression fullReturnType = jmd.restype;
returnType = fullReturnType;
typeParams = jmd.typarams;
thrownExceptions = jmd.thrown;
nameOfBuilderMethod = jmd.name;
if (returnType instanceof JCTypeApply) {
returnType = ((JCTypeApply) returnType).clazz;
}
if (builderClassName.isEmpty()) {
if (returnType instanceof JCFieldAccess) {
builderClassName = ((JCFieldAccess) returnType).name.toString() + "Builder";
} else if (returnType instanceof JCIdent) {
Name n = ((JCIdent) returnType).name;
for (JCTypeParameter tp : typeParams) {
if (tp.name.equals(n)) {
annotationNode.addError("@Builder requires specifying 'builderClassName' if used on methods with a type parameter as return type.");
return;
}
}
builderClassName = n.toString() + "Builder";
} else if (returnType instanceof JCPrimitiveTypeTree) {
builderClassName = returnType.toString() + "Builder";
if (Character.isLowerCase(builderClassName.charAt(0))) {
builderClassName = Character.toTitleCase(builderClassName.charAt(0)) + builderClassName.substring(1);
}
} else {
// This shouldn't happen.
System.err.println("Lombok bug ID#20140614-1651: javac HandleBuilder: return type to name conversion failed: " + returnType.getClass());
builderClassName = td.name.toString() + "Builder";
}
}
if (toBuilder) {
final String TO_BUILDER_NOT_SUPPORTED = "@Builder(toBuilder=true) is only supported if you return your own type.";
if (returnType instanceof JCArrayTypeTree) {
annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
return;
}
Name simpleName;
String pkg;
List<JCExpression> tpOnRet = List.nil();
if (fullReturnType instanceof JCTypeApply) {
tpOnRet = ((JCTypeApply) fullReturnType).arguments;
}
if (returnType instanceof JCIdent) {
simpleName = ((JCIdent) returnType).name;
pkg = null;
} else if (returnType instanceof JCFieldAccess) {
JCFieldAccess jcfa = (JCFieldAccess) returnType;
simpleName = jcfa.name;
pkg = unpack(jcfa.selected);
if (pkg.startsWith("ERR:")) {
String err = pkg.substring(4, pkg.indexOf("__ERR__"));
annotationNode.addError(err);
return;
}
} else {
annotationNode.addError("Expected a (parameterized) type here instead of a " + returnType.getClass().getName());
return;
}
if (pkg != null && !parent.getPackageDeclaration().equals(pkg)) {
annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
return;
}
if (!tdParent.getName().contentEquals(simpleName)) {
annotationNode.addError(TO_BUILDER_NOT_SUPPORTED);
return;
}
List<JCTypeParameter> tpOnMethod = jmd.typarams;
List<JCTypeParameter> tpOnType = ((JCClassDecl) tdParent.get()).typarams;
typeArgsForToBuilder = new ArrayList<Name>();
for (JCTypeParameter tp : tpOnMethod) {
int pos = -1;
int idx = -1;
for (JCExpression tOnRet : tpOnRet) {
idx++;
if (!(tOnRet instanceof JCIdent))
continue;
if (((JCIdent) tOnRet).name != tp.name)
continue;
pos = idx;
}
if (pos == -1 || tpOnType.size() <= pos) {
annotationNode.addError("@Builder(toBuilder=true) requires that each type parameter on the static method is part of the typeargs of the return value. Type parameter " + tp.name + " is not part of the return type.");
return;
}
typeArgsForToBuilder.add(tpOnType.get(pos).name);
}
}
} else {
annotationNode.addError("@Builder is only supported on types, constructors, and methods.");
return;
}
if (fillParametersFrom != null) {
for (JavacNode param : fillParametersFrom.down()) {
if (param.getKind() != Kind.ARGUMENT)
continue;
BuilderFieldData bfd = new BuilderFieldData();
JCVariableDecl raw = (JCVariableDecl) param.get();
bfd.name = raw.name;
bfd.rawName = raw.name;
bfd.type = raw.vartype;
bfd.singularData = getSingularData(param);
addObtainVia(bfd, param);
builderFields.add(bfd);
}
}
JavacNode builderType = findInnerClass(tdParent, builderClassName);
if (builderType == null) {
builderType = makeBuilderClass(isStatic, annotationNode, tdParent, builderClassName, typeParams, ast);
} else {
JCClassDecl builderTypeDeclaration = (JCClassDecl) builderType.get();
if (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)) {
annotationNode.addError("Existing Builder must be a non-static inner class.");
return;
}
sanityCheckForMethodGeneratingAnnotationsOnBuilderClass(builderType, annotationNode);
/* generate errors for @Singular BFDs that have one already defined node. */
{
for (BuilderFieldData bfd : builderFields) {
SingularData sd = bfd.singularData;
if (sd == null)
continue;
JavacSingularizer singularizer = sd.getSingularizer();
if (singularizer == null)
continue;
if (singularizer.checkForAlreadyExistingNodesAndGenerateError(builderType, sd)) {
bfd.singularData = null;
}
}
}
}
for (BuilderFieldData bfd : builderFields) {
if (bfd.singularData != null && bfd.singularData.getSingularizer() != null) {
if (bfd.singularData.getSingularizer().requiresCleaning()) {
addCleaning = true;
break;
}
}
if (bfd.obtainVia != null) {
if (bfd.obtainVia.field().isEmpty() == bfd.obtainVia.method().isEmpty()) {
bfd.obtainViaNode.addError("The syntax is either @ObtainVia(field = \"fieldName\") or @ObtainVia(method = \"methodName\").");
return;
}
if (bfd.obtainVia.method().isEmpty() && bfd.obtainVia.isStatic()) {
bfd.obtainViaNode.addError("@ObtainVia(isStatic = true) is not valid unless 'method' has been set.");
return;
}
}
}
generateBuilderFields(builderType, builderFields, ast);
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);
}
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);
}
for (BuilderFieldData bfd : builderFields) {
makeSetterMethodsForBuilder(builderType, bfd, annotationNode, fluent, chain);
}
if (methodExists(buildMethodName, builderType, -1) == MemberExistsResult.NOT_EXISTS) {
JCMethodDecl md = generateBuildMethod(isStatic, buildMethodName, nameOfBuilderMethod, returnType, builderFields, builderType, thrownExceptions, ast, addCleaning);
if (md != null)
injectMethod(builderType, md);
}
if (methodExists("toString", builderType, 0) == MemberExistsResult.NOT_EXISTS) {
java.util.List<JavacNode> fieldNodes = new ArrayList<JavacNode>();
for (BuilderFieldData bfd : builderFields) {
fieldNodes.addAll(bfd.createdFields);
}
JCMethodDecl md = HandleToString.createToString(builderType, fieldNodes, true, false, FieldAccess.ALWAYS_FIELD, ast);
if (md != null)
injectMethod(builderType, md);
}
if (addCleaning)
injectMethod(builderType, generateCleanMethod(builderFields, builderType, ast));
if (methodExists(builderMethodName, tdParent, -1) == MemberExistsResult.NOT_EXISTS) {
JCMethodDecl md = generateBuilderMethod(isStatic, builderMethodName, builderClassName, annotationNode, tdParent, typeParams);
recursiveSetGeneratedBy(md, ast, annotationNode.getContext());
if (md != null)
injectMethod(tdParent, md);
}
if (toBuilder) {
switch(methodExists(toBuilderMethodName, tdParent, 0)) {
case EXISTS_BY_USER:
annotationNode.addWarning("Not generating toBuilder() as it already exists.");
return;
case NOT_EXISTS:
List<JCTypeParameter> tps = typeParams;
if (typeArgsForToBuilder != null) {
ListBuffer<JCTypeParameter> lb = new ListBuffer<JCTypeParameter>();
JavacTreeMaker maker = tdParent.getTreeMaker();
for (Name n : typeArgsForToBuilder) {
lb.append(maker.TypeParameter(n, List.<JCExpression>nil()));
}
tps = lb.toList();
}
JCMethodDecl md = generateToBuilderMethod(toBuilderMethodName, builderClassName, tdParent, tps, builderFields, fluent, ast);
if (md != null)
injectMethod(tdParent, md);
}
}
recursiveSetGeneratedBy(builderType.get(), ast, annotationNode.getContext());
}
use of com.sun.tools.javac.tree.JCTree.JCArrayTypeTree in project lombok by rzwitserloot.
the class HandleEqualsAndHashCode method createHashCode.
public JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, JCTree source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
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());
/* final int PRIME = X; */
{
if (!fields.isEmpty() || callSuper) {
statements.append(maker.VarDef(maker.Modifiers(finalFlag), primeName, maker.TypeIdent(CTC_INT), maker.Literal(HandlerUtil.primeForHashcode())));
}
}
/* int result = 1; */
{
statements.append(maker.VarDef(maker.Modifiers(0), resultName, maker.TypeIdent(CTC_INT), maker.Literal(1)));
}
if (callSuper) {
JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("hashCode")), List.<JCExpression>nil());
statements.append(createResultCalculation(typeNode, callToSuper));
}
Name dollar = typeNode.toName("$");
for (JavacNode fieldNode : fields) {
JCExpression fType = getFieldType(fieldNode, fieldAccess);
JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, 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 = dollar.append(((JCVariableDecl) fieldNode.get()).name);
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 = dollar.append(((JCVariableDecl) fieldNode.get()).name);
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) {
/* java.util.Arrays.deepHashCode(this.fieldName) //use just hashCode() for primitive arrays. */
boolean multiDim = ((JCArrayTypeTree) fType).elemtype instanceof JCArrayTypeTree;
boolean primitiveArray = ((JCArrayTypeTree) fType).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 = dollar.append(((JCVariableDecl) fieldNode.get()).name);
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))));
}
}
/* 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, typeNode.getContext());
}
use of com.sun.tools.javac.tree.JCTree.JCArrayTypeTree in project lombok by rzwitserloot.
the class PrettyPrinter method visitNewArray.
@Override
public void visitNewArray(JCNewArray tree) {
JCTree elem = tree.elemtype;
int dims = 0;
if (elem != null) {
print("new ");
while (elem instanceof JCArrayTypeTree) {
dims++;
elem = ((JCArrayTypeTree) elem).elemtype;
}
print(elem);
for (JCExpression expr : tree.dims) {
print("[");
print(expr);
print("]");
}
}
for (int i = 0; i < dims; i++) print("[]");
if (tree.elems != null) {
if (elem != null)
print("[] ");
print("{");
print(tree.elems, ", ");
print("}");
}
}
use of com.sun.tools.javac.tree.JCTree.JCArrayTypeTree in project lombok by rzwitserloot.
the class JavacHandlerUtil method cloneType0.
private static JCExpression cloneType0(JavacTreeMaker maker, JCTree in) {
if (in == null)
return null;
if (in instanceof JCPrimitiveTypeTree)
return (JCExpression) in;
if (in instanceof JCIdent) {
return maker.Ident(((JCIdent) in).name);
}
if (in instanceof JCFieldAccess) {
JCFieldAccess fa = (JCFieldAccess) in;
return maker.Select(cloneType0(maker, fa.selected), fa.name);
}
if (in instanceof JCArrayTypeTree) {
JCArrayTypeTree att = (JCArrayTypeTree) in;
return maker.TypeArray(cloneType0(maker, att.elemtype));
}
if (in instanceof JCTypeApply) {
JCTypeApply ta = (JCTypeApply) in;
ListBuffer<JCExpression> lb = new ListBuffer<JCExpression>();
for (JCExpression typeArg : ta.arguments) {
lb.append(cloneType0(maker, typeArg));
}
return maker.TypeApply(cloneType0(maker, ta.clazz), lb.toList());
}
if (in instanceof JCWildcard) {
JCWildcard w = (JCWildcard) in;
JCExpression newInner = cloneType0(maker, w.inner);
TypeBoundKind newKind;
switch(w.getKind()) {
case SUPER_WILDCARD:
newKind = maker.TypeBoundKind(BoundKind.SUPER);
break;
case EXTENDS_WILDCARD:
newKind = maker.TypeBoundKind(BoundKind.EXTENDS);
break;
default:
case UNBOUNDED_WILDCARD:
newKind = maker.TypeBoundKind(BoundKind.UNBOUND);
break;
}
return maker.Wildcard(newKind, newInner);
}
// This is somewhat unsafe, but it's better than outright throwing an exception here. Returning null will just cause an exception down the pipeline.
return (JCExpression) in;
}
use of com.sun.tools.javac.tree.JCTree.JCArrayTypeTree in project lombok by rzwitserloot.
the class HandleToString method createToString.
static JCMethodDecl createToString(JavacNode typeNode, Collection<JavacNode> fields, boolean includeFieldNames, boolean callSuper, FieldAccess fieldAccess, JCTree source) {
JavacTreeMaker maker = typeNode.getTreeMaker();
JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
JCExpression returnType = genJavaLangTypeRef(typeNode, "String");
boolean first = true;
String typeName = getTypeName(typeNode);
String infix = ", ";
String suffix = ")";
String prefix;
if (callSuper) {
prefix = typeName + "(super=";
} else if (fields.isEmpty()) {
prefix = typeName + "()";
} else if (includeFieldNames) {
prefix = typeName + "(" + ((JCVariableDecl) fields.iterator().next().get()).name.toString() + "=";
} else {
prefix = typeName + "(";
}
JCExpression 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 (JavacNode fieldNode : fields) {
JCExpression expr;
JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess);
JCExpression fieldType = getFieldType(fieldNode, fieldAccess);
// The distinction between primitive and object will be useful if we ever add a 'hideNulls' option.
boolean fieldIsPrimitive = fieldType instanceof JCPrimitiveTypeTree;
boolean fieldIsPrimitiveArray = fieldType instanceof JCArrayTypeTree && ((JCArrayTypeTree) fieldType).elemtype instanceof JCPrimitiveTypeTree;
boolean fieldIsObjectArray = !fieldIsPrimitiveArray && fieldType instanceof JCArrayTypeTree;
@SuppressWarnings("unused") boolean fieldIsObject = !fieldIsPrimitive && !fieldIsPrimitiveArray && !fieldIsObjectArray;
if (fieldIsPrimitiveArray || fieldIsObjectArray) {
JCExpression tsMethod = chainDots(typeNode, "java", "util", "Arrays", fieldIsObjectArray ? "deepToString" : "toString");
expr = maker.Apply(List.<JCExpression>nil(), tsMethod, List.<JCExpression>of(fieldAccessor));
} else
expr = fieldAccessor;
if (first) {
current = maker.Binary(CTC_PLUS, current, expr);
first = false;
continue;
}
if (includeFieldNames) {
current = maker.Binary(CTC_PLUS, current, maker.Literal(infix + fieldNode.getName() + "="));
} 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));
return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("toString"), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
Aggregations