/*
* Copyright 2015 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.inferred.freebuilder.processor;
import static com.google.common.truth.Truth.assertThat;
import static org.inferred.freebuilder.processor.util.ClassTypeImpl.newTopLevelClass;
import static org.inferred.freebuilder.processor.util.PrimitiveTypeImpl.INT;
import static org.inferred.freebuilder.processor.util.feature.SourceLevel.JAVA_7;
import static org.inferred.freebuilder.processor.util.feature.SourceLevel.JAVA_8;
import com.google.common.base.Joiner;
import com.google.googlejavaformat.java.Formatter;
import com.google.googlejavaformat.java.FormatterException;
import org.inferred.freebuilder.processor.Metadata.Property;
import org.inferred.freebuilder.processor.util.QualifiedName;
import org.inferred.freebuilder.processor.util.SourceBuilder;
import org.inferred.freebuilder.processor.util.SourceStringBuilder;
import org.inferred.freebuilder.processor.util.feature.Feature;
import org.inferred.freebuilder.processor.util.feature.GuavaLibrary;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import javax.lang.model.type.TypeMirror;
@RunWith(JUnit4.class)
public class RequiredPropertiesSourceTest {
@Test
public void testJ6() {
Metadata metadata = createMetadata(true);
assertThat(generateSource(metadata, GuavaLibrary.AVAILABLE)).isEqualTo(Joiner.on('\n').join(
"/** Auto-generated superclass of {@link Person.Builder}, "
+ "derived from the API of {@link Person}. */",
"@Generated(\"org.inferred.freebuilder.processor.CodeGenerator\")",
"abstract class Person_Builder {",
"",
" /** Creates a new builder using {@code value} as a template. */",
" public static Person.Builder from(Person value) {",
" return new Person.Builder().mergeFrom(value);",
" }",
"",
" private static final Joiner COMMA_JOINER = Joiner.on(\", \").skipNulls();",
"",
" private enum Property {",
" NAME(\"name\"),",
" AGE(\"age\"),",
" ;",
"",
" private final String name;",
"",
" private Property(String name) {",
" this.name = name;",
" }",
"",
" @Override",
" public String toString() {",
" return name;",
" }",
" }",
"",
" private String name;",
" private int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties =",
" EnumSet.allOf(Person_Builder.Property.class);",
"",
" /**",
" * Sets the value to be returned by {@link Person#getName()}.",
" *",
" * @return this {@code Builder} object",
" * @throws NullPointerException if {@code name} is null",
" */",
" public Person.Builder setName(String name) {",
" this.name = Preconditions.checkNotNull(name);",
" _unsetProperties.remove(Person_Builder.Property.NAME);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getName()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public String getName() {",
" Preconditions.checkState(",
" !_unsetProperties.contains(Person_Builder.Property.NAME), \"name not set\");",
" return name;",
" }",
"",
" /**",
" * Sets the value to be returned by {@link Person#getAge()}.",
" *",
" * @return this {@code Builder} object",
" */",
" public Person.Builder setAge(int age) {",
" this.age = age;",
" _unsetProperties.remove(Person_Builder.Property.AGE);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getAge()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public int getAge() {",
" Preconditions.checkState(",
" !_unsetProperties.contains(Person_Builder.Property.AGE), \"age not set\");",
" return age;",
" }",
"",
" /** Sets all property values using the given {@code Person} as a template. */",
" public Person.Builder mergeFrom(Person value) {",
" Person_Builder _defaults = new Person.Builder();",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !value.getName().equals(_defaults.getName())) {",
" setName(value.getName());",
" }",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || value.getAge() != _defaults.getAge()) {",
" setAge(value.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Copies values from the given {@code Builder}. "
+ "Does not affect any properties not set on the",
" * input.",
" */",
" public Person.Builder mergeFrom(Person.Builder template) {",
" // Upcast to access private fields; otherwise, oddly, we get an access violation.",
" Person_Builder base = (Person_Builder) template;",
" Person_Builder _defaults = new Person.Builder();",
" if (!base._unsetProperties.contains(Person_Builder.Property.NAME)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !template.getName().equals(_defaults.getName()))) {",
" setName(template.getName());",
" }",
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || template.getAge() != _defaults.getAge())) {",
" setAge(template.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /** Resets the state of this builder. */",
" public Person.Builder clear() {",
" Person_Builder _defaults = new Person.Builder();",
" name = _defaults.name;",
" age = _defaults.age;",
" _unsetProperties.clear();",
" _unsetProperties.addAll(_defaults._unsetProperties);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
" */",
" public Person build() {",
" Preconditions.checkState(_unsetProperties.isEmpty(),"
+ " \"Not set: %s\", _unsetProperties);",
" return new Person_Builder.Value(this);",
" }",
"",
" /**",
" * Returns a newly-created partial {@link Person} for use in unit tests. "
+ "State checking will not",
" * be performed. Unset properties will throw an {@link UnsupportedOperationException} "
+ "when",
" * accessed via the partial object.",
" *",
" * <p>Partials should only ever be used in tests. "
+ "They permit writing robust test cases that won't",
" * fail if this type gains more application-level constraints "
+ "(e.g. new required fields) in",
" * future. If you require partially complete values in production code, "
+ "consider using a Builder.",
" */",
" @VisibleForTesting()",
" public Person buildPartial() {",
" return new Person_Builder.Partial(this);",
" }",
"",
" private static final class Value extends Person {",
" private final String name;",
" private final int age;",
"",
" private Value(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" }",
"",
" @Override",
" public String getName() {",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Value)) {",
" return false;",
" }",
" Person_Builder.Value other = (Person_Builder.Value) obj;",
" if (!name.equals(other.name)) {",
" return false;",
" }",
" if (age != other.age) {",
" return false;",
" }",
" return true;",
" }",
"",
" @Override",
" public int hashCode() {",
" return Arrays.hashCode(new Object[] {name, age});",
" }",
"",
" @Override",
" public String toString() {",
" return \"Person{\" + \"name=\" + name + \", \" + \"age=\" + age + \"}\";",
" }",
" }",
"",
" private static final class Partial extends Person {",
" private final String name;",
" private final int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties;",
"",
" Partial(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" this._unsetProperties = builder._unsetProperties.clone();",
" }",
"",
" @Override",
" public String getName() {",
" if (_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" throw new UnsupportedOperationException(\"name not set\");",
" }",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" if (_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" throw new UnsupportedOperationException(\"age not set\");",
" }",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Partial)) {",
" return false;",
" }",
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
" if (name != other.name && (name == null || !name.equals(other.name))) {",
" return false;",
" }",
" if (age != other.age) {",
" return false;",
" }",
" return _unsetProperties.equals(other._unsetProperties);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Arrays.hashCode(new Object[] {name, age, _unsetProperties});",
" }",
"",
" @Override",
" public String toString() {",
" return \"partial Person{\"",
" + COMMA_JOINER.join(",
" (!_unsetProperties.contains(Person_Builder.Property.NAME) "
+ "? \"name=\" + name : null),",
" (!_unsetProperties.contains(Person_Builder.Property.AGE) "
+ "? \"age=\" + age : null))",
" + \"}\";",
" }",
" }",
"}\n"));
}
@Test
public void testJ7() {
Metadata metadata = createMetadata(true);
String source = generateSource(metadata, JAVA_7, GuavaLibrary.AVAILABLE);
assertThat(source).isEqualTo(Joiner.on('\n').join(
"/** Auto-generated superclass of {@link Person.Builder}, "
+ "derived from the API of {@link Person}. */",
"@Generated(\"org.inferred.freebuilder.processor.CodeGenerator\")",
"abstract class Person_Builder {",
"",
" /** Creates a new builder using {@code value} as a template. */",
" public static Person.Builder from(Person value) {",
" return new Person.Builder().mergeFrom(value);",
" }",
"",
" private static final Joiner COMMA_JOINER = Joiner.on(\", \").skipNulls();",
"",
" private enum Property {",
" NAME(\"name\"),",
" AGE(\"age\"),",
" ;",
"",
" private final String name;",
"",
" private Property(String name) {",
" this.name = name;",
" }",
"",
" @Override",
" public String toString() {",
" return name;",
" }",
" }",
"",
" private String name;",
" private int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties =",
" EnumSet.allOf(Person_Builder.Property.class);",
"",
" /**",
" * Sets the value to be returned by {@link Person#getName()}.",
" *",
" * @return this {@code Builder} object",
" * @throws NullPointerException if {@code name} is null",
" */",
" public Person.Builder setName(String name) {",
" this.name = Preconditions.checkNotNull(name);",
" _unsetProperties.remove(Person_Builder.Property.NAME);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getName()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public String getName() {",
" Preconditions.checkState(",
" !_unsetProperties.contains(Person_Builder.Property.NAME), \"name not set\");",
" return name;",
" }",
"",
" /**",
" * Sets the value to be returned by {@link Person#getAge()}.",
" *",
" * @return this {@code Builder} object",
" */",
" public Person.Builder setAge(int age) {",
" this.age = age;",
" _unsetProperties.remove(Person_Builder.Property.AGE);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getAge()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public int getAge() {",
" Preconditions.checkState(",
" !_unsetProperties.contains(Person_Builder.Property.AGE), \"age not set\");",
" return age;",
" }",
"",
" /** Sets all property values using the given {@code Person} as a template. */",
" public Person.Builder mergeFrom(Person value) {",
" Person_Builder _defaults = new Person.Builder();",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !Objects.equals(value.getName(), _defaults.getName())) {",
" setName(value.getName());",
" }",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || !Objects.equals(value.getAge(), _defaults.getAge())) {",
" setAge(value.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Copies values from the given {@code Builder}. "
+ "Does not affect any properties not set on the",
" * input.",
" */",
" public Person.Builder mergeFrom(Person.Builder template) {",
" // Upcast to access private fields; otherwise, oddly, we get an access violation.",
" Person_Builder base = (Person_Builder) template;",
" Person_Builder _defaults = new Person.Builder();",
" if (!base._unsetProperties.contains(Person_Builder.Property.NAME)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !Objects.equals(template.getName(), _defaults.getName()))) {",
" setName(template.getName());",
" }",
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || !Objects.equals(template.getAge(), _defaults.getAge()))) {",
" setAge(template.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /** Resets the state of this builder. */",
" public Person.Builder clear() {",
" Person_Builder _defaults = new Person.Builder();",
" name = _defaults.name;",
" age = _defaults.age;",
" _unsetProperties.clear();",
" _unsetProperties.addAll(_defaults._unsetProperties);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
" */",
" public Person build() {",
" Preconditions.checkState(_unsetProperties.isEmpty(),"
+ " \"Not set: %s\", _unsetProperties);",
" return new Person_Builder.Value(this);",
" }",
"",
" /**",
" * Returns a newly-created partial {@link Person} for use in unit tests. "
+ "State checking will not",
" * be performed. Unset properties will throw an {@link UnsupportedOperationException} "
+ "when",
" * accessed via the partial object.",
" *",
" * <p>Partials should only ever be used in tests. "
+ "They permit writing robust test cases that won't",
" * fail if this type gains more application-level constraints "
+ "(e.g. new required fields) in",
" * future. If you require partially complete values in production code, "
+ "consider using a Builder.",
" */",
" @VisibleForTesting()",
" public Person buildPartial() {",
" return new Person_Builder.Partial(this);",
" }",
"",
" private static final class Value extends Person {",
" private final String name;",
" private final int age;",
"",
" private Value(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" }",
"",
" @Override",
" public String getName() {",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Value)) {",
" return false;",
" }",
" Person_Builder.Value other = (Person_Builder.Value) obj;",
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Objects.hash(name, age);",
" }",
"",
" @Override",
" public String toString() {",
" return \"Person{\" + \"name=\" + name + \", \" + \"age=\" + age + \"}\";",
" }",
" }",
"",
" private static final class Partial extends Person {",
" private final String name;",
" private final int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties;",
"",
" Partial(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" this._unsetProperties = builder._unsetProperties.clone();",
" }",
"",
" @Override",
" public String getName() {",
" if (_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" throw new UnsupportedOperationException(\"name not set\");",
" }",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" if (_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" throw new UnsupportedOperationException(\"age not set\");",
" }",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Partial)) {",
" return false;",
" }",
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
" return Objects.equals(name, other.name)",
" && Objects.equals(age, other.age)",
" && Objects.equals(_unsetProperties, other._unsetProperties);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Objects.hash(name, age, _unsetProperties);",
" }",
"",
" @Override",
" public String toString() {",
" return \"partial Person{\"",
" + COMMA_JOINER.join(",
" (!_unsetProperties.contains(Person_Builder.Property.NAME) "
+ "? \"name=\" + name : null),",
" (!_unsetProperties.contains(Person_Builder.Property.AGE) "
+ "? \"age=\" + age : null))",
" + \"}\";",
" }",
" }",
"}\n"));
}
@Test
public void testJ6_noGuava() {
Metadata metadata = createMetadata(true);
assertThat(generateSource(metadata)).isEqualTo(Joiner.on('\n').join(
"/** Auto-generated superclass of {@link Person.Builder}, "
+ "derived from the API of {@link Person}. */",
"@Generated(\"org.inferred.freebuilder.processor.CodeGenerator\")",
"abstract class Person_Builder {",
"",
" /** Creates a new builder using {@code value} as a template. */",
" public static Person.Builder from(Person value) {",
" return new Person.Builder().mergeFrom(value);",
" }",
"",
" private enum Property {",
" NAME(\"name\"),",
" AGE(\"age\"),",
" ;",
"",
" private final String name;",
"",
" private Property(String name) {",
" this.name = name;",
" }",
"",
" @Override",
" public String toString() {",
" return name;",
" }",
" }",
"",
" private String name;",
" private int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties =",
" EnumSet.allOf(Person_Builder.Property.class);",
"",
" /**",
" * Sets the value to be returned by {@link Person#getName()}.",
" *",
" * @return this {@code Builder} object",
" * @throws NullPointerException if {@code name} is null",
" */",
" public Person.Builder setName(String name) {",
" if (name == null) {",
" throw new NullPointerException();",
" }",
" this.name = name;",
" _unsetProperties.remove(Person_Builder.Property.NAME);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getName()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public String getName() {",
" if (_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" throw new IllegalStateException(\"name not set\");",
" }",
" return name;",
" }",
"",
" /**",
" * Sets the value to be returned by {@link Person#getAge()}.",
" *",
" * @return this {@code Builder} object",
" */",
" public Person.Builder setAge(int age) {",
" this.age = age;",
" _unsetProperties.remove(Person_Builder.Property.AGE);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getAge()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public int getAge() {",
" if (_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" throw new IllegalStateException(\"age not set\");",
" }",
" return age;",
" }",
"",
" /** Sets all property values using the given {@code Person} as a template. */",
" public Person.Builder mergeFrom(Person value) {",
" Person_Builder _defaults = new Person.Builder();",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !value.getName().equals(_defaults.getName())) {",
" setName(value.getName());",
" }",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || value.getAge() != _defaults.getAge()) {",
" setAge(value.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Copies values from the given {@code Builder}."
+ " Does not affect any properties not set on the",
" * input.",
" */",
" public Person.Builder mergeFrom(Person.Builder template) {",
" // Upcast to access private fields; otherwise, oddly, we get an access violation.",
" Person_Builder base = (Person_Builder) template;",
" Person_Builder _defaults = new Person.Builder();",
" if (!base._unsetProperties.contains(Person_Builder.Property.NAME)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !template.getName().equals(_defaults.getName()))) {",
" setName(template.getName());",
" }",
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || template.getAge() != _defaults.getAge())) {",
" setAge(template.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /** Resets the state of this builder. */",
" public Person.Builder clear() {",
" Person_Builder _defaults = new Person.Builder();",
" name = _defaults.name;",
" age = _defaults.age;",
" _unsetProperties.clear();",
" _unsetProperties.addAll(_defaults._unsetProperties);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
" */",
" public Person build() {",
" if (!_unsetProperties.isEmpty()) {",
" throw new IllegalStateException(\"Not set: \" + _unsetProperties);",
" }",
" return new Person_Builder.Value(this);",
" }",
"",
" /**",
" * Returns a newly-created partial {@link Person} for use in unit tests. "
+ "State checking will not",
" * be performed. Unset properties will throw an {@link UnsupportedOperationException} "
+ "when",
" * accessed via the partial object.",
" *",
" * <p>Partials should only ever be used in tests. "
+ "They permit writing robust test cases that won't",
" * fail if this type gains more application-level constraints "
+ "(e.g. new required fields) in",
" * future. If you require partially complete values in production code, "
+ "consider using a Builder.",
" */",
" public Person buildPartial() {",
" return new Person_Builder.Partial(this);",
" }",
"",
" private static final class Value extends Person {",
" private final String name;",
" private final int age;",
"",
" private Value(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" }",
"",
" @Override",
" public String getName() {",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Value)) {",
" return false;",
" }",
" Person_Builder.Value other = (Person_Builder.Value) obj;",
" if (!name.equals(other.name)) {",
" return false;",
" }",
" if (age != other.age) {",
" return false;",
" }",
" return true;",
" }",
"",
" @Override",
" public int hashCode() {",
" return Arrays.hashCode(new Object[] {name, age});",
" }",
"",
" @Override",
" public String toString() {",
" return \"Person{\" + \"name=\" + name + \", \" + \"age=\" + age + \"}\";",
" }",
" }",
"",
" private static final class Partial extends Person {",
" private final String name;",
" private final int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties;",
"",
" Partial(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" this._unsetProperties = builder._unsetProperties.clone();",
" }",
"",
" @Override",
" public String getName() {",
" if (_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" throw new UnsupportedOperationException(\"name not set\");",
" }",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" if (_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" throw new UnsupportedOperationException(\"age not set\");",
" }",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Partial)) {",
" return false;",
" }",
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
" if (name != other.name && (name == null || !name.equals(other.name))) {",
" return false;",
" }",
" if (age != other.age) {",
" return false;",
" }",
" return _unsetProperties.equals(other._unsetProperties);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Arrays.hashCode(new Object[] {name, age, _unsetProperties});",
" }",
"",
" @Override",
" public String toString() {",
" StringBuilder result = new StringBuilder(\"partial Person{\");",
" String separator = \"\";",
" if (!_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" result.append(\"name=\").append(name);",
" separator = \", \";",
" }",
" if (!_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" result.append(separator);",
" result.append(\"age=\").append(age);",
" }",
" result.append(\"}\");",
" return result.toString();",
" }",
" }",
"}\n"));
}
@Test
public void testJ7_noGuava() {
Metadata metadata = createMetadata(true);
assertThat(generateSource(metadata, JAVA_7)).isEqualTo(Joiner.on('\n').join(
"/** Auto-generated superclass of {@link Person.Builder}, "
+ "derived from the API of {@link Person}. */",
"@Generated(\"org.inferred.freebuilder.processor.CodeGenerator\")",
"abstract class Person_Builder {",
"",
" /** Creates a new builder using {@code value} as a template. */",
" public static Person.Builder from(Person value) {",
" return new Person.Builder().mergeFrom(value);",
" }",
"",
" private enum Property {",
" NAME(\"name\"),",
" AGE(\"age\"),",
" ;",
"",
" private final String name;",
"",
" private Property(String name) {",
" this.name = name;",
" }",
"",
" @Override",
" public String toString() {",
" return name;",
" }",
" }",
"",
" private String name;",
" private int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties =",
" EnumSet.allOf(Person_Builder.Property.class);",
"",
" /**",
" * Sets the value to be returned by {@link Person#getName()}.",
" *",
" * @return this {@code Builder} object",
" * @throws NullPointerException if {@code name} is null",
" */",
" public Person.Builder setName(String name) {",
" this.name = Objects.requireNonNull(name);",
" _unsetProperties.remove(Person_Builder.Property.NAME);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getName()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public String getName() {",
" if (_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" throw new IllegalStateException(\"name not set\");",
" }",
" return name;",
" }",
"",
" /**",
" * Sets the value to be returned by {@link Person#getAge()}.",
" *",
" * @return this {@code Builder} object",
" */",
" public Person.Builder setAge(int age) {",
" this.age = age;",
" _unsetProperties.remove(Person_Builder.Property.AGE);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getAge()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public int getAge() {",
" if (_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" throw new IllegalStateException(\"age not set\");",
" }",
" return age;",
" }",
"",
" /** Sets all property values using the given {@code Person} as a template. */",
" public Person.Builder mergeFrom(Person value) {",
" Person_Builder _defaults = new Person.Builder();",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !Objects.equals(value.getName(), _defaults.getName())) {",
" setName(value.getName());",
" }",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || !Objects.equals(value.getAge(), _defaults.getAge())) {",
" setAge(value.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Copies values from the given {@code Builder}. "
+ "Does not affect any properties not set on the",
" * input.",
" */",
" public Person.Builder mergeFrom(Person.Builder template) {",
" // Upcast to access private fields; otherwise, oddly, we get an access violation.",
" Person_Builder base = (Person_Builder) template;",
" Person_Builder _defaults = new Person.Builder();",
" if (!base._unsetProperties.contains(Person_Builder.Property.NAME)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !Objects.equals(template.getName(), _defaults.getName()))) {",
" setName(template.getName());",
" }",
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || !Objects.equals(template.getAge(), _defaults.getAge()))) {",
" setAge(template.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /** Resets the state of this builder. */",
" public Person.Builder clear() {",
" Person_Builder _defaults = new Person.Builder();",
" name = _defaults.name;",
" age = _defaults.age;",
" _unsetProperties.clear();",
" _unsetProperties.addAll(_defaults._unsetProperties);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
" */",
" public Person build() {",
" if (!_unsetProperties.isEmpty()) {",
" throw new IllegalStateException(\"Not set: \" + _unsetProperties);",
" }",
" return new Person_Builder.Value(this);",
" }",
"",
" /**",
" * Returns a newly-created partial {@link Person} for use in unit tests. "
+ "State checking will not",
" * be performed. Unset properties will throw an {@link UnsupportedOperationException} "
+ "when",
" * accessed via the partial object.",
" *",
" * <p>Partials should only ever be used in tests. "
+ "They permit writing robust test cases that won't",
" * fail if this type gains more application-level constraints "
+ "(e.g. new required fields) in",
" * future. If you require partially complete values in production code, "
+ "consider using a Builder.",
" */",
" public Person buildPartial() {",
" return new Person_Builder.Partial(this);",
" }",
"",
" private static final class Value extends Person {",
" private final String name;",
" private final int age;",
"",
" private Value(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" }",
"",
" @Override",
" public String getName() {",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Value)) {",
" return false;",
" }",
" Person_Builder.Value other = (Person_Builder.Value) obj;",
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Objects.hash(name, age);",
" }",
"",
" @Override",
" public String toString() {",
" return \"Person{\" + \"name=\" + name + \", \" + \"age=\" + age + \"}\";",
" }",
" }",
"",
" private static final class Partial extends Person {",
" private final String name;",
" private final int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties;",
"",
" Partial(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" this._unsetProperties = builder._unsetProperties.clone();",
" }",
"",
" @Override",
" public String getName() {",
" if (_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" throw new UnsupportedOperationException(\"name not set\");",
" }",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" if (_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" throw new UnsupportedOperationException(\"age not set\");",
" }",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Partial)) {",
" return false;",
" }",
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
" return Objects.equals(name, other.name)",
" && Objects.equals(age, other.age)",
" && Objects.equals(_unsetProperties, other._unsetProperties);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Objects.hash(name, age, _unsetProperties);",
" }",
"",
" @Override",
" public String toString() {",
" StringBuilder result = new StringBuilder(\"partial Person{\");",
" String separator = \"\";",
" if (!_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" result.append(\"name=\").append(name);",
" separator = \", \";",
" }",
" if (!_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" result.append(separator);",
" result.append(\"age=\").append(age);",
" }",
" result.append(\"}\");",
" return result.toString();",
" }",
" }",
"}\n"));
}
@Test
public void testJ8() {
Metadata metadata = createMetadata(true);
String source = generateSource(metadata, JAVA_8, GuavaLibrary.AVAILABLE);
assertThat(source).isEqualTo(Joiner.on('\n').join(
"/** Auto-generated superclass of {@link Person.Builder}, "
+ "derived from the API of {@link Person}. */",
"abstract class Person_Builder {",
"",
" /** Creates a new builder using {@code value} as a template. */",
" public static Person.Builder from(Person value) {",
" return new Person.Builder().mergeFrom(value);",
" }",
"",
" private static final Joiner COMMA_JOINER = Joiner.on(\", \").skipNulls();",
"",
" private enum Property {",
" NAME(\"name\"),",
" AGE(\"age\"),",
" ;",
"",
" private final String name;",
"",
" private Property(String name) {",
" this.name = name;",
" }",
"",
" @Override",
" public String toString() {",
" return name;",
" }",
" }",
"",
" private String name;",
" private int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties =",
" EnumSet.allOf(Person_Builder.Property.class);",
"",
" /**",
" * Sets the value to be returned by {@link Person#getName()}.",
" *",
" * @return this {@code Builder} object",
" * @throws NullPointerException if {@code name} is null",
" */",
" public Person.Builder setName(String name) {",
" this.name = Preconditions.checkNotNull(name);",
" _unsetProperties.remove(Person_Builder.Property.NAME);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Replaces the value to be returned by {@link Person#getName()} "
+ "by applying {@code mapper} to it",
" * and using the result.",
" *",
" * @return this {@code Builder} object",
" * @throws NullPointerException if {@code mapper} is null or returns null",
" * @throws IllegalStateException if the field has not been set",
" */",
" public Person.Builder mapName(UnaryOperator<String> mapper) {",
" Preconditions.checkNotNull(mapper);",
" return setName(mapper.apply(getName()));",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getName()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public String getName() {",
" Preconditions.checkState(",
" !_unsetProperties.contains(Person_Builder.Property.NAME), \"name not set\");",
" return name;",
" }",
"",
" /**",
" * Sets the value to be returned by {@link Person#getAge()}.",
" *",
" * @return this {@code Builder} object",
" */",
" public Person.Builder setAge(int age) {",
" this.age = age;",
" _unsetProperties.remove(Person_Builder.Property.AGE);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Replaces the value to be returned by {@link Person#getAge()} "
+ "by applying {@code mapper} to it",
" * and using the result.",
" *",
" * @return this {@code Builder} object",
" * @throws NullPointerException if {@code mapper} is null or returns null",
" * @throws IllegalStateException if the field has not been set",
" */",
" public Person.Builder mapAge(UnaryOperator<Integer> mapper) {",
" Preconditions.checkNotNull(mapper);",
" return setAge(mapper.apply(getAge()));",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#getAge()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public int getAge() {",
" Preconditions.checkState(",
" !_unsetProperties.contains(Person_Builder.Property.AGE), \"age not set\");",
" return age;",
" }",
"",
" /** Sets all property values using the given {@code Person} as a template. */",
" public Person.Builder mergeFrom(Person value) {",
" Person_Builder _defaults = new Person.Builder();",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !Objects.equals(value.getName(), _defaults.getName())) {",
" setName(value.getName());",
" }",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || !Objects.equals(value.getAge(), _defaults.getAge())) {",
" setAge(value.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Copies values from the given {@code Builder}. "
+ "Does not affect any properties not set on the",
" * input.",
" */",
" public Person.Builder mergeFrom(Person.Builder template) {",
" // Upcast to access private fields; otherwise, oddly, we get an access violation.",
" Person_Builder base = (Person_Builder) template;",
" Person_Builder _defaults = new Person.Builder();",
" if (!base._unsetProperties.contains(Person_Builder.Property.NAME)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !Objects.equals(template.getName(), _defaults.getName()))) {",
" setName(template.getName());",
" }",
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || !Objects.equals(template.getAge(), _defaults.getAge()))) {",
" setAge(template.getAge());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /** Resets the state of this builder. */",
" public Person.Builder clear() {",
" Person_Builder _defaults = new Person.Builder();",
" name = _defaults.name;",
" age = _defaults.age;",
" _unsetProperties.clear();",
" _unsetProperties.addAll(_defaults._unsetProperties);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
" */",
" public Person build() {",
" Preconditions.checkState(_unsetProperties.isEmpty(),"
+ " \"Not set: %s\", _unsetProperties);",
" return new Person_Builder.Value(this);",
" }",
"",
" /**",
" * Returns a newly-created partial {@link Person} for use in unit tests. "
+ "State checking will not",
" * be performed. Unset properties will throw an {@link UnsupportedOperationException} "
+ "when",
" * accessed via the partial object.",
" *",
" * <p>Partials should only ever be used in tests. "
+ "They permit writing robust test cases that won't",
" * fail if this type gains more application-level constraints "
+ "(e.g. new required fields) in",
" * future. If you require partially complete values in production code, "
+ "consider using a Builder.",
" */",
" @VisibleForTesting()",
" public Person buildPartial() {",
" return new Person_Builder.Partial(this);",
" }",
"",
" private static final class Value extends Person {",
" private final String name;",
" private final int age;",
"",
" private Value(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" }",
"",
" @Override",
" public String getName() {",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Value)) {",
" return false;",
" }",
" Person_Builder.Value other = (Person_Builder.Value) obj;",
" return Objects.equals(name, other.name) && Objects.equals(age, other.age);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Objects.hash(name, age);",
" }",
"",
" @Override",
" public String toString() {",
" return \"Person{\" + \"name=\" + name + \", \" + \"age=\" + age + \"}\";",
" }",
" }",
"",
" private static final class Partial extends Person {",
" private final String name;",
" private final int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties;",
"",
" Partial(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" this._unsetProperties = builder._unsetProperties.clone();",
" }",
"",
" @Override",
" public String getName() {",
" if (_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" throw new UnsupportedOperationException(\"name not set\");",
" }",
" return name;",
" }",
"",
" @Override",
" public int getAge() {",
" if (_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" throw new UnsupportedOperationException(\"age not set\");",
" }",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Partial)) {",
" return false;",
" }",
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
" return Objects.equals(name, other.name)",
" && Objects.equals(age, other.age)",
" && Objects.equals(_unsetProperties, other._unsetProperties);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Objects.hash(name, age, _unsetProperties);",
" }",
"",
" @Override",
" public String toString() {",
" return \"partial Person{\"",
" + COMMA_JOINER.join(",
" (!_unsetProperties.contains(Person_Builder.Property.NAME) "
+ "? \"name=\" + name : null),",
" (!_unsetProperties.contains(Person_Builder.Property.AGE) "
+ "? \"age=\" + age : null))",
" + \"}\";",
" }",
" }",
"}\n"));
}
@Test
public void testPrefixless() {
Metadata metadata = createMetadata(false);
assertThat(generateSource(metadata, GuavaLibrary.AVAILABLE)).isEqualTo(Joiner.on('\n').join(
"/** Auto-generated superclass of {@link Person.Builder}, "
+ "derived from the API of {@link Person}. */",
"@Generated(\"org.inferred.freebuilder.processor.CodeGenerator\")",
"abstract class Person_Builder {",
"",
" /** Creates a new builder using {@code value} as a template. */",
" public static Person.Builder from(Person value) {",
" return new Person.Builder().mergeFrom(value);",
" }",
"",
" private static final Joiner COMMA_JOINER = Joiner.on(\", \").skipNulls();",
"",
" private enum Property {",
" NAME(\"name\"),",
" AGE(\"age\"),",
" ;",
"",
" private final String name;",
"",
" private Property(String name) {",
" this.name = name;",
" }",
"",
" @Override",
" public String toString() {",
" return name;",
" }",
" }",
"",
" private String name;",
" private int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties =",
" EnumSet.allOf(Person_Builder.Property.class);",
"",
" /**",
" * Sets the value to be returned by {@link Person#name()}.",
" *",
" * @return this {@code Builder} object",
" * @throws NullPointerException if {@code name} is null",
" */",
" public Person.Builder name(String name) {",
" this.name = Preconditions.checkNotNull(name);",
" _unsetProperties.remove(Person_Builder.Property.NAME);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#name()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public String name() {",
" Preconditions.checkState(",
" !_unsetProperties.contains(Person_Builder.Property.NAME), \"name not set\");",
" return name;",
" }",
"",
" /**",
" * Sets the value to be returned by {@link Person#age()}.",
" *",
" * @return this {@code Builder} object",
" */",
" public Person.Builder age(int age) {",
" this.age = age;",
" _unsetProperties.remove(Person_Builder.Property.AGE);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns the value that will be returned by {@link Person#age()}.",
" *",
" * @throws IllegalStateException if the field has not been set",
" */",
" public int age() {",
" Preconditions.checkState(",
" !_unsetProperties.contains(Person_Builder.Property.AGE), \"age not set\");",
" return age;",
" }",
"",
" /** Sets all property values using the given {@code Person} as a template. */",
" public Person.Builder mergeFrom(Person value) {",
" Person_Builder _defaults = new Person.Builder();",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !value.name().equals(_defaults.name())) {",
" name(value.name());",
" }",
" if (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || value.age() != _defaults.age()) {",
" age(value.age());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Copies values from the given {@code Builder}. "
+ "Does not affect any properties not set on the",
" * input.",
" */",
" public Person.Builder mergeFrom(Person.Builder template) {",
" // Upcast to access private fields; otherwise, oddly, we get an access violation.",
" Person_Builder base = (Person_Builder) template;",
" Person_Builder _defaults = new Person.Builder();",
" if (!base._unsetProperties.contains(Person_Builder.Property.NAME)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.NAME)",
" || !template.name().equals(_defaults.name()))) {",
" name(template.name());",
" }",
" if (!base._unsetProperties.contains(Person_Builder.Property.AGE)",
" && (_defaults._unsetProperties.contains(Person_Builder.Property.AGE)",
" || template.age() != _defaults.age())) {",
" age(template.age());",
" }",
" return (Person.Builder) this;",
" }",
"",
" /** Resets the state of this builder. */",
" public Person.Builder clear() {",
" Person_Builder _defaults = new Person.Builder();",
" name = _defaults.name;",
" age = _defaults.age;",
" _unsetProperties.clear();",
" _unsetProperties.addAll(_defaults._unsetProperties);",
" return (Person.Builder) this;",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
" */",
" public Person build() {",
" Preconditions.checkState(_unsetProperties.isEmpty(),"
+ " \"Not set: %s\", _unsetProperties);",
" return new Person_Builder.Value(this);",
" }",
"",
" /**",
" * Returns a newly-created partial {@link Person} for use in unit tests. "
+ "State checking will not",
" * be performed. Unset properties will throw an {@link UnsupportedOperationException} "
+ "when",
" * accessed via the partial object.",
" *",
" * <p>Partials should only ever be used in tests. "
+ "They permit writing robust test cases that won't",
" * fail if this type gains more application-level constraints "
+ "(e.g. new required fields) in",
" * future. If you require partially complete values in production code, "
+ "consider using a Builder.",
" */",
" @VisibleForTesting()",
" public Person buildPartial() {",
" return new Person_Builder.Partial(this);",
" }",
"",
" private static final class Value extends Person {",
" private final String name;",
" private final int age;",
"",
" private Value(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" }",
"",
" @Override",
" public String name() {",
" return name;",
" }",
"",
" @Override",
" public int age() {",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Value)) {",
" return false;",
" }",
" Person_Builder.Value other = (Person_Builder.Value) obj;",
" if (!name.equals(other.name)) {",
" return false;",
" }",
" if (age != other.age) {",
" return false;",
" }",
" return true;",
" }",
"",
" @Override",
" public int hashCode() {",
" return Arrays.hashCode(new Object[] {name, age});",
" }",
"",
" @Override",
" public String toString() {",
" return \"Person{\" + \"name=\" + name + \", \" + \"age=\" + age + \"}\";",
" }",
" }",
"",
" private static final class Partial extends Person {",
" private final String name;",
" private final int age;",
" private final EnumSet<Person_Builder.Property> _unsetProperties;",
"",
" Partial(Person_Builder builder) {",
" this.name = builder.name;",
" this.age = builder.age;",
" this._unsetProperties = builder._unsetProperties.clone();",
" }",
"",
" @Override",
" public String name() {",
" if (_unsetProperties.contains(Person_Builder.Property.NAME)) {",
" throw new UnsupportedOperationException(\"name not set\");",
" }",
" return name;",
" }",
"",
" @Override",
" public int age() {",
" if (_unsetProperties.contains(Person_Builder.Property.AGE)) {",
" throw new UnsupportedOperationException(\"age not set\");",
" }",
" return age;",
" }",
"",
" @Override",
" public boolean equals(Object obj) {",
" if (!(obj instanceof Person_Builder.Partial)) {",
" return false;",
" }",
" Person_Builder.Partial other = (Person_Builder.Partial) obj;",
" if (name != other.name && (name == null || !name.equals(other.name))) {",
" return false;",
" }",
" if (age != other.age) {",
" return false;",
" }",
" return _unsetProperties.equals(other._unsetProperties);",
" }",
"",
" @Override",
" public int hashCode() {",
" return Arrays.hashCode(new Object[] {name, age, _unsetProperties});",
" }",
"",
" @Override",
" public String toString() {",
" return \"partial Person{\"",
" + COMMA_JOINER.join(",
" (!_unsetProperties.contains(Person_Builder.Property.NAME) "
+ "? \"name=\" + name : null),",
" (!_unsetProperties.contains(Person_Builder.Property.AGE) "
+ "? \"age=\" + age : null))",
" + \"}\";",
" }",
" }",
"}\n"));
}
private static String generateSource(Metadata metadata, Feature<?>... features) {
SourceBuilder sourceBuilder = SourceStringBuilder.simple(features);
new CodeGenerator().writeBuilderSource(sourceBuilder, metadata);
try {
return new Formatter().formatSource(sourceBuilder.toString());
} catch (FormatterException e) {
throw new RuntimeException(e);
}
}
private static Metadata createMetadata(boolean bean) {
QualifiedName person = QualifiedName.of("com.example", "Person");
TypeMirror string = newTopLevelClass("java.lang.String");
QualifiedName generatedBuilder = QualifiedName.of("com.example", "Person_Builder");
Property name = new Property.Builder()
.setAllCapsName("NAME")
.setBoxedType(string)
.setCapitalizedName("Name")
.setFullyCheckedCast(true)
.setGetterName(bean ? "getName" : "name")
.setName("name")
.setType(string)
.setUsingBeanConvention(bean)
.build();
Property age = new Property.Builder()
.setAllCapsName("AGE")
.setBoxedType(newTopLevelClass("java.lang.Integer"))
.setCapitalizedName("Age")
.setFullyCheckedCast(true)
.setGetterName(bean ? "getAge" : "age")
.setName("age")
.setType(INT)
.setUsingBeanConvention(bean)
.build();
Metadata metadata = new Metadata.Builder()
.setBuilder(person.nestedType("Builder").withParameters())
.setBuilderFactory(BuilderFactory.NO_ARGS_CONSTRUCTOR)
.setBuilderSerializable(false)
.setGeneratedBuilder(generatedBuilder.withParameters())
.setInterfaceType(false)
.setPartialType(generatedBuilder.nestedType("Partial").withParameters())
.addProperties(name, age)
.setPropertyEnum(generatedBuilder.nestedType("Property").withParameters())
.setType(person.withParameters())
.setValueType(generatedBuilder.nestedType("Value").withParameters())
.build();
return metadata.toBuilder()
.clearProperties()
.addProperties(name.toBuilder()
.setCodeGenerator(new DefaultPropertyFactory.CodeGenerator(metadata, name, false))
.build())
.addProperties(age.toBuilder()
.setCodeGenerator(new DefaultPropertyFactory.CodeGenerator(metadata, age, false))
.build())
.build();
}
}