diff --git a/value/src/main/java/com/google/auto/value/processor/BuilderSpec.java b/value/src/main/java/com/google/auto/value/processor/BuilderSpec.java index 46f17cf05b..9b372af014 100644 --- a/value/src/main/java/com/google/auto/value/processor/BuilderSpec.java +++ b/value/src/main/java/com/google/auto/value/processor/BuilderSpec.java @@ -163,13 +163,19 @@ ImmutableSet toBuilderMethods( return builderMethods; } + /** + * Returns the types that are referenced by abstract methods in the builder, either as + * parameters or as return types. + */ Set referencedTypes() { Set types = new TypeMirrorSet(); for (ExecutableElement method : ElementFilter.methodsIn(builderTypeElement.getEnclosedElements())) { - types.add(method.getReturnType()); - for (VariableElement parameter : method.getParameters()) { - types.add(parameter.asType()); + if (method.getModifiers().contains(Modifier.ABSTRACT)) { + types.add(method.getReturnType()); + for (VariableElement parameter : method.getParameters()) { + types.add(parameter.asType()); + } } } return types; diff --git a/value/src/main/java/com/google/auto/value/processor/autovalue.vm b/value/src/main/java/com/google/auto/value/processor/autovalue.vm index 3a679fc33c..7b9ea92fd0 100644 --- a/value/src/main/java/com/google/auto/value/processor/autovalue.vm +++ b/value/src/main/java/com/google/auto/value/processor/autovalue.vm @@ -40,7 +40,11 @@ ${gwtCompatibleAnnotation} ${p.nullableAnnotation}$p.type $p #if ($foreach.hasNext) , #end #end ) { #foreach ($p in $props) - #if (!$p.kind.primitive && !$p.nullable && $builderTypeName == "") + #if (!$p.kind.primitive && !$p.nullable && ($builderTypeName == "" || !$isFinal)) + ## We don't need a null check if the type is primitive or @Nullable. We also don't need it + ## if there is a builder, since the build() method will check for us. However, if there is a + ## builder but there are also extensions (!$isFinal) then we can't omit the null check because + ## the constructor is called from the extension code. if ($p == null) { throw new NullPointerException("Null $p.name"); diff --git a/value/src/test/java/com/google/auto/value/processor/CompilationTest.java b/value/src/test/java/com/google/auto/value/processor/CompilationTest.java index 162f1cf3c6..c5285dd999 100644 --- a/value/src/test/java/com/google/auto/value/processor/CompilationTest.java +++ b/value/src/test/java/com/google/auto/value/processor/CompilationTest.java @@ -590,6 +590,7 @@ public void correctBuilder() throws Exception { "import com.google.common.base.Optional;", "import com.google.common.collect.ImmutableList;", "", + "import java.util.ArrayList;", "import java.util.List;", "import javax.annotation.Nullable;", "", @@ -607,21 +608,26 @@ public void correctBuilder() throws Exception { " public abstract Builder toBuilder();", "", " @AutoValue.Builder", - " public interface Builder {", - " Builder anInt(int x);", - " Builder aByteArray(byte[] x);", - " Builder aNullableIntArray(@Nullable int[] x);", - " Builder aList(List x);", - " Builder anImmutableList(List x);", - " ImmutableList.Builder anImmutableListBuilder();", - " Builder anOptionalString(Optional s);", - " Builder anOptionalString(String s);", + " public abstract static class Builder {", + " public abstract Builder anInt(int x);", + " public abstract Builder aByteArray(byte[] x);", + " public abstract Builder aNullableIntArray(@Nullable int[] x);", + " public abstract Builder aList(List x);", + " public abstract Builder anImmutableList(List x);", + " public abstract ImmutableList.Builder anImmutableListBuilder();", + " public abstract Builder anOptionalString(Optional s);", + " public abstract Builder anOptionalString(String s);", + "", + " public Builder aList(ArrayList x) {", + // ArrayList should not be imported in the generated class. + " return aList((List) x);", + " }", "", - " Optional anInt();", - " List aList();", - " ImmutableList anImmutableList();", + " public abstract Optional anInt();", + " public abstract List aList();", + " public abstract ImmutableList anImmutableList();", "", - " Baz build();", + " public abstract Baz build();", " }", "", " public static Builder builder() {", @@ -742,7 +748,7 @@ public void correctBuilder() throws Exception { " return new Builder(this);", " }", "", - " static final class Builder implements Baz.Builder {", + " static final class Builder extends Baz.Builder {", " private Integer anInt;", " private byte[] aByteArray;", " private int[] aNullableIntArray;", diff --git a/value/userguide/vertical_nav.md b/value/userguide/vertical_nav.md deleted file mode 100644 index 2e087fdd5c..0000000000 --- a/value/userguide/vertical_nav.md +++ /dev/null @@ -1,14 +0,0 @@ -**AutoValue User Guide** - -* [Introduction](index.md) - * [How do I...?](howto.md) - * [Generated example](generated-example.md) -* [AutoValue with builders](builders.md) - * [How do I...?](builders-howto.md) - * [Generated example](generated-builder-example.md) -* [Extensions](extensions.md) -* [Troubleshooting](trouble.md) -* [Best practices](practices.md) -* [Why AutoValue?](why.md) -* [Performance notes](performance.md) -* [Design FAQ](design-faq.md)