Class ToStringGenerator
- java.lang.Object
-
- org.inferred.freebuilder.processor.ToStringGenerator
-
class ToStringGenerator extends java.lang.Object
-
-
Constructor Summary
Constructors Modifier Constructor Description privateToStringGenerator()
-
Method Summary
All Methods Static Methods Concrete Methods Modifier and Type Method Description static voidaddToString(SourceBuilder code, Datatype datatype, java.util.Map<Property,PropertyCodeGenerator> generatorsByProperty, boolean forPartial)Generates a toString method using concatenation or a StringBuilder.private static voidbodyWithBuilder(SourceBuilder code, Datatype datatype, java.util.Map<Property,PropertyCodeGenerator> generatorsByProperty, java.lang.String typename, java.util.function.Predicate<PropertyCodeGenerator> isOptional)Generates the body of a toString method that uses a StringBuilder.private static voidbodyWithBuilderAndSeparator(SourceBuilder code, Datatype datatype, java.util.Map<Property,PropertyCodeGenerator> generatorsByProperty, java.lang.String typename)Generates the body of a toString method that uses a StringBuilder and a separator variable.private static voidbodyWithConcatenation(SourceBuilder code, java.util.Map<Property,PropertyCodeGenerator> generatorsByProperty, java.lang.String typename)Generate the body of a toString method that uses plain concatenation.
-
-
-
Method Detail
-
addToString
public static void addToString(SourceBuilder code, Datatype datatype, java.util.Map<Property,PropertyCodeGenerator> generatorsByProperty, boolean forPartial)
Generates a toString method using concatenation or a StringBuilder.
-
bodyWithConcatenation
private static void bodyWithConcatenation(SourceBuilder code, java.util.Map<Property,PropertyCodeGenerator> generatorsByProperty, java.lang.String typename)
Generate the body of a toString method that uses plain concatenation.Conventionally, we join properties with comma separators. If all of the properties are always present, this can be done with a long block of unconditional code. We could use a StringBuilder for this, but in fact the Java compiler will do this for us under the hood if we use simple string concatenation, so we use the more readable approach.
-
bodyWithBuilder
private static void bodyWithBuilder(SourceBuilder code, Datatype datatype, java.util.Map<Property,PropertyCodeGenerator> generatorsByProperty, java.lang.String typename, java.util.function.Predicate<PropertyCodeGenerator> isOptional)
Generates the body of a toString method that uses a StringBuilder.Conventionally, we join properties with comma separators. If all of the properties are optional, we have no choice but to track the separators at runtime, but if any of them will always be present, we can actually do the hard work at compile time. Specifically, we can pick the first such and output it without a comma; any property before it will have a comma appended, and any property after it will have a comma prepended. This gives us the right number of commas in the right places in all circumstances.
As well as keeping track of whether we are prepending commas yet (initially false), we also keep track of whether we have just finished an if-then block for an optional property, or if we are in the middle of an append chain, and if so, whether we are in the middle of a string literal. This lets us output the fewest literals and statements, much as a mildly compulsive programmer would when writing the same code.
-
bodyWithBuilderAndSeparator
private static void bodyWithBuilderAndSeparator(SourceBuilder code, Datatype datatype, java.util.Map<Property,PropertyCodeGenerator> generatorsByProperty, java.lang.String typename)
Generates the body of a toString method that uses a StringBuilder and a separator variable.Conventionally, we join properties with comma separators. If all of the properties are optional, we have no choice but to track the separators at runtime, as apart from the first one, all properties will need to have a comma prepended. We could do this with a boolean, maybe called "separatorNeeded", or "firstValueOutput", but then we need either a ternary operator or an extra nested if block. More readable is to use an initially-empty "separator" string, which has a comma placed in it once the first value is written.
For extra tidiness, we note that the first if block need not try writing the separator (it is always empty), and the last one need not update it (it will not be used again).
-
-