Skip to content

Commit

Permalink
Apply @Nullable to fields in the generated class where appropriate.
Browse files Browse the repository at this point in the history
We already did this if it was a `TYPE_USE` `@Nullable` or if the corresponding property method was annotated with `@CopyAnnotations`. Now we do it in every other case as well.

RELNOTES=If an AutoValue property method is `@Nullable`, the corresponding field in the generated class will be too. This was already the case for `TYPE_USE` `@Nullable` or if the method had `@CopyAnnotations`, but now `@Nullable` will be copied in other cases too.
PiperOrigin-RevId: 559765107
  • Loading branch information
eamonnmcmanus authored and Google Java Core Libraries committed Aug 24, 2023
1 parent e67ab8b commit 4506804
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import static com.google.auto.common.AnnotationMirrors.getAnnotationValue;
import static com.google.auto.common.GeneratedAnnotations.generatedAnnotation;
import static com.google.auto.common.MoreElements.asType;
import static com.google.auto.common.MoreElements.getPackage;
import static com.google.auto.common.MoreElements.isAnnotationPresent;
import static com.google.auto.common.MoreStreams.toImmutableList;
Expand Down Expand Up @@ -1215,19 +1216,31 @@ final ImmutableListMultimap<ExecutableElement, AnnotationMirror> propertyFieldAn

private ImmutableList<AnnotationMirror> propertyFieldAnnotations(
TypeElement type, ExecutableElement method) {
// We need to exclude type annotations from the ones being output on the method, since
// they will be output as part of the field's type.
Set<String> returnTypeAnnotations =
getReturnTypeAnnotations(method, this::annotationAppliesToFields);
if (!hasAnnotationMirror(method, COPY_ANNOTATIONS_NAME)) {
return ImmutableList.of();
// If there's no @CopyAnnotations, we will still copy a @Nullable annotation, if (1) it is not
// a TYPE_USE annotation (those appear as part of the type in the generated code) and (2) it
// applies to fields. All known non-TYPE_USE @Nullable annotations do apply to fields, but we
// check just in case.
return method.getAnnotationMirrors().stream()
.filter(
a -> {
TypeElement annotationType = asType(a.getAnnotationType().asElement());
return isNullable(a)
&& !returnTypeAnnotations.contains(annotationType.getQualifiedName().toString())
&& annotationAppliesToFields(annotationType);
})
.collect(toImmutableList());
}
ImmutableSet<String> excludedAnnotations =
ImmutableSet.<String>builder()
.addAll(getExcludedAnnotationClassNames(method))
.add(Override.class.getCanonicalName())
.build();

// We need to exclude type annotations from the ones being output on the method, since
// they will be output as part of the field's type.
Set<String> returnTypeAnnotations =
getReturnTypeAnnotations(method, this::annotationAppliesToFields);
Set<String> nonFieldAnnotations =
method.getAnnotationMirrors().stream()
.map(a -> a.getAnnotationType().asElement())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1163,6 +1163,7 @@ public void correctBuilder() {
"final class AutoValue_Baz<T extends Number> extends Baz<T> {",
" private final int anInt;",
" private final byte[] aByteArray;",
" @Nullable",
" private final int[] aNullableIntArray;",
" private final List<T> aList;",
" private final ImmutableMap<T, String> anImmutableMap;",
Expand Down

0 comments on commit 4506804

Please sign in to comment.