Skip to content
This repository has been archived by the owner on Oct 16, 2024. It is now read-only.

Commit

Permalink
mergeFrom() super type builder works across the packages
Browse files Browse the repository at this point in the history
  • Loading branch information
ph4r05 committed Dec 8, 2016
1 parent aa6f182 commit 46afa50
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,6 @@ private ImmutableSet<ParameterizedType> superBuilders(TypeElement type) throws C
final Optional<AnnotationMirror> freeBuilderMirror =
findAnnotationMirror(superType, FreeBuilder.class);

// For now we support mergeFrom(superBuilder) only for builders from the same package
// Due to package local visibility of the Enum Property
if (!pkg.getQualifiedName().contentEquals(elements.getPackageOf(superType).getQualifiedName())){
continue;
}

if (freeBuilderMirror.isPresent()){
ParameterizedType pType = QualifiedName.of(superType).withParameters(superType.getTypeParameters());
toRet.add(pType);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,9 @@ public static String clearMethod(Property property) {
return "clear" + property.getCapitalizedName();
}

public static String isPropertySetMethod(Property property){
return "isProperty" + property.getCapitalizedName() + "Set";
}

private BuilderMethods() {}
}
29 changes: 19 additions & 10 deletions src/main/java/org/inferred/freebuilder/processor/CodeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static com.google.common.collect.Iterables.any;
import static com.google.common.collect.Iterables.getLast;
import static com.google.common.collect.Iterables.getOnlyElement;
import static org.inferred.freebuilder.processor.BuilderMethods.isPropertySetMethod;
import static org.inferred.freebuilder.processor.BuilderFactory.TypeInference.EXPLICIT_TYPES;
import static org.inferred.freebuilder.processor.Metadata.GET_CODE_GENERATOR;
import static org.inferred.freebuilder.processor.Metadata.UnderrideLevel.ABSENT;
Expand Down Expand Up @@ -81,7 +82,7 @@ void writeBuilderSource(SourceBuilder code, Metadata metadata) {
addMergeFromBuilderMethod(code, metadata);
addMergeFromSuperTypes(code, metadata);
addClearMethod(code, metadata);
addIsPropertyUnsetMethod(code, metadata);
addPropertiesSetMethods(code, metadata);
addBuildMethod(code, metadata);
addBuildPartialMethod(code, metadata);

Expand Down Expand Up @@ -274,18 +275,26 @@ private static void addClearMethod(SourceBuilder code, Metadata metadata) {
.addLine("}");
}

private static void addIsPropertyUnsetMethod(SourceBuilder code, Metadata metadata) {
private static void addPropertiesSetMethods(SourceBuilder code, Metadata metadata) {
if (!any(metadata.getProperties(), IS_REQUIRED)) {
return;

}
code.addLine("")
.addLine("/**")
.addLine(" * Returns true if the required property is not set.")
.addLine(" */")
.addLine("public boolean isPropertyUnset(%s property) {", metadata.getPropertyEnum())
.addLine(" return _unsetProperties.contains(property);")
.addLine("}");

for (Property property : metadata.getProperties()) {
if (!IS_REQUIRED.apply(property)){
continue;
}

code.addLine("")
.addLine("/**")
.addLine(" * Returns true if the required property corresponding to")
.addLine(" * %s is set. ", metadata.getType().javadocNoArgMethodLink(property.getGetterName()))
.addLine(" */")
.addLine("public boolean %s() {", isPropertySetMethod(property))
.addLine(" return _unsetProperties.contains(%s.%s);", metadata.getPropertyEnum(), property.getAllCapsName())
.addLine("}");
}
}

private static void addBuildPartialMethod(SourceBuilder code, Metadata metadata) {
Expand Down Expand Up @@ -313,7 +322,7 @@ private static void addBuildPartialMethod(SourceBuilder code, Metadata metadata)

private static void addPropertyEnum(Metadata metadata, SourceBuilder code) {
code.addLine("")
.addLine("enum %s {", metadata.getPropertyEnum().getSimpleName());
.addLine("private enum %s {", metadata.getPropertyEnum().getSimpleName());
for (Property property : metadata.getProperties()) {
if (property.getCodeGenerator().getType() == Type.REQUIRED) {
code.addLine(" %s(\"%s\"),", property.getAllCapsName(), property.getName());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import static org.inferred.freebuilder.processor.BuilderMethods.getter;
import static org.inferred.freebuilder.processor.BuilderMethods.mapper;
import static org.inferred.freebuilder.processor.BuilderMethods.setter;
import static org.inferred.freebuilder.processor.BuilderMethods.isPropertySetMethod;
import static org.inferred.freebuilder.processor.util.PreconditionExcerpts.checkNotNullInline;
import static org.inferred.freebuilder.processor.util.PreconditionExcerpts.checkNotNullPreamble;
import static org.inferred.freebuilder.processor.util.feature.FunctionPackage.FUNCTION_PACKAGE;
Expand Down Expand Up @@ -207,17 +208,23 @@ public void addMergeFromSuperBuilder(Block code, String builder) {
}

public void addMergeFromBuilder(Block code, String builder, boolean fromSuper) {
Excerpt base =
hasDefault ? null : Declarations.upcastToGeneratedBuilder(code, metadata, builder);
Excerpt base = hasDefault || fromSuper ?
null : Declarations.upcastToGeneratedBuilder(code, metadata, builder);
Excerpt defaults = Declarations.freshBuilder(code, metadata).orNull();
String unsetContains = fromSuper ? "isPropertyUnset" : "_unsetProperties.contains";
Block unsetContains = new Block(code);
if (fromSuper){
unsetContains.add("%s()", isPropertySetMethod(property));
base = new Block(code).add(builder);
} else {
unsetContains.add("_unsetProperties.contains(%s.%s)", metadata.getPropertyEnum(), property.getAllCapsName());
}
if (defaults != null) {
code.add("if (");
if (!hasDefault) {
code.add("!%s.%s(%s.%s) && ",
base, unsetContains, metadata.getPropertyEnum(), property.getAllCapsName())
.add("(%s.%s(%s.%s) ||",
defaults, unsetContains, metadata.getPropertyEnum(), property.getAllCapsName());
code.add("!%s.%s && ",
base, unsetContains)
.add("(%s.%s ||",
defaults, unsetContains);
}
if (isPrimitive) {
code.add("%1$s.%2$s() != %3$s.%2$s()", builder, getter(property), defaults);
Expand All @@ -229,8 +236,8 @@ public void addMergeFromBuilder(Block code, String builder, boolean fromSuper) {
}
code.add(") {%n");
} else if (!hasDefault) {
code.addLine("if (!%s.%s(%s.%s)) {",
base, unsetContains, metadata.getPropertyEnum(), property.getAllCapsName());
code.addLine("if (!%s.%s) {",
base, unsetContains);
}
code.addLine(" %s(%s.%s());", setter(property), builder, getter(property));
if (defaults != null || !hasDefault) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ public void addMergeFromBuilder(Block code, String builder) {

@Override
public void addMergeFromSuperBuilder(Block code, String builder) {
Excerpt base = Declarations.upcastToGeneratedBuilder(code, metadata, builder);
Excerpt base = new Block(code).add(builder);
code.addLine("%s(%s.%s());", addAllMethod(property), base, getter(property));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -887,6 +887,22 @@ public void testJ6_noGuava_oneDefaultProperty() {
" }",
"",
" /**",
" * Returns true if the required property corresponding to",
" * {@link Person#getName()} is set.",
" */",
" public boolean isPropertyNameSet() {",
" return _unsetProperties.contains(Person_Builder.Property.NAME);",
" }",
"",
" /**",
" * Returns true if the required property corresponding to",
" * {@link Person#getShoeSize()} is set.",
" */",
" public boolean isPropertyShoeSizeSet() {",
" return _unsetProperties.contains(Person_Builder.Property.SHOE_SIZE);",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,22 @@ public void testJ6() {
" }",
"",
" /**",
" * Returns true if the required property corresponding to",
" * {@link Person#getName()} is set.",
" */",
" public boolean isPropertyNameSet() {",
" return _unsetProperties.contains(Person_Builder.Property.NAME);",
" }",
"",
" /**",
" * Returns true if the required property corresponding to",
" * {@link Person#getAge()} is set.",
" */",
" public boolean isPropertyAgeSet() {",
" return _unsetProperties.contains(Person_Builder.Property.AGE);",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
Expand Down Expand Up @@ -448,6 +464,22 @@ public void testJ7() {
" }",
"",
" /**",
" * Returns true if the required property corresponding to",
" * {@link Person#getName()} is set.",
" */",
" public boolean isPropertyNameSet() {",
" return _unsetProperties.contains(Person_Builder.Property.NAME);",
" }",
"",
" /**",
" * Returns true if the required property corresponding to",
" * {@link Person#getAge()} is set.",
" */",
" public boolean isPropertyAgeSet() {",
" return _unsetProperties.contains(Person_Builder.Property.AGE);",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
Expand Down Expand Up @@ -733,6 +765,22 @@ public void testJ8() {
" }",
"",
" /**",
" * Returns true if the required property corresponding to",
" * {@link Person#getName()} is set.",
" */",
" public boolean isPropertyNameSet() {",
" return _unsetProperties.contains(Person_Builder.Property.NAME);",
" }",
"",
" /**",
" * Returns true if the required property corresponding to",
" * {@link Person#getAge()} is set.",
" */",
" public boolean isPropertyAgeSet() {",
" return _unsetProperties.contains(Person_Builder.Property.AGE);",
" }",
"",
" /**",
" * Returns a newly-created {@link Person} based on the contents of the {@code Builder}.",
" *",
" * @throws IllegalStateException if any field has not been set",
Expand Down

0 comments on commit 46afa50

Please sign in to comment.