Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -408,4 +408,26 @@ public void kotlinWithTypeParameters() {
assertThat(data.getV()).isEqualTo(2.0);
assertThat(data.getM()).isEqualTo(map);
}

@AutoBuilder(ofClass = KotlinDataWithNullableParameters.class)
interface KotlinDataWithNullableParametersBuilder<T> {
static <T> KotlinDataWithNullableParametersBuilder<T> builder() {
return new AutoBuilder_AutoBuilderKotlinTest_KotlinDataWithNullableParametersBuilder<T>();
}

KotlinDataWithNullableParametersBuilder<T> value(@org.jetbrains.annotations.Nullable T value);

KotlinDataWithNullableParameters<T> build();
}

@Test
public void kotlinWithNullableParameters() {
KotlinDataWithNullableParameters<String> x =
KotlinDataWithNullableParametersBuilder.<String>builder().value("hello").build();
assertThat(x.getValue()).isEqualTo("hello");

KotlinDataWithNullableParameters<String> nullX =
KotlinDataWithNullableParametersBuilder.<String>builder().value(null).build();
assertThat(nullX.getValue()).isNull();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,5 @@ data class KotlinDataWithTypeParameters<
>(val t: T? = null, val u: U, val v: V, val m: M) {
fun foo(w: W) {}
}

data class KotlinDataWithNullableParameters<T>(val value: T?)
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,8 @@ private String findCallMethodValue(AnnotationMirror autoBuilderAnnotation) {
}

@Override
Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod) {
Optional<String> nullableAnnotationForMethod(
ExecutableElement propertyMethod, AnnotatedTypeMirror propertyType) {
// TODO(b/183005059): implement
return Optional.empty();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,9 @@ private void defineVarsForType(
}

@Override
Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod) {
if (nullableAnnotationFor(propertyMethod, propertyMethod.getReturnType()).isPresent()) {
Optional<String> nullableAnnotationForMethod(
ExecutableElement propertyMethod, AnnotatedTypeMirror propertyType) {
if (nullableAnnotationFor(propertyMethod, propertyType).isPresent()) {
errorReporter()
.reportError(
propertyMethod, "[AutoOneOfNullable] @AutoOneOf properties cannot be @Nullable");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -514,8 +514,9 @@ private void defineVarsForType(
}

@Override
Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod) {
return nullableAnnotationFor(propertyMethod, propertyMethod.getReturnType());
Optional<String> nullableAnnotationForMethod(
ExecutableElement propertyMethod, AnnotatedTypeMirror propertyType) {
return nullableAnnotationFor(propertyMethod, propertyType);
}

static ImmutableSet<ExecutableElement> prefixedGettersIn(Iterable<ExecutableElement> methods) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -526,7 +526,8 @@ private void validateType(TypeElement type) {
* is nullable but the <i>method</i> isn't. The {@code @Nullable} annotation will instead appear
* when the return type of the method is spelled out in the implementation.
*/
abstract Optional<String> nullableAnnotationForMethod(ExecutableElement propertyMethod);
abstract Optional<String> nullableAnnotationForMethod(
ExecutableElement propertyMethod, AnnotatedTypeMirror propertyType);

/**
* Returns the ordered set of {@link Property} definitions for the given {@code @AutoValue} or
Expand Down Expand Up @@ -561,7 +562,8 @@ final ImmutableSet<Property> propertySet(
ImmutableList<AnnotationMirror> methodAnnotationMirrors =
annotatedPropertyMethods.get(propertyMethod);
ImmutableList<String> methodAnnotations = annotationStrings(methodAnnotationMirrors);
Optional<String> nullableAnnotation = nullableAnnotationForMethod(propertyMethod);
Optional<String> nullableAnnotation =
nullableAnnotationForMethod(propertyMethod, returnType);
Property p =
new GetterProperty(
propertyName,
Expand Down Expand Up @@ -727,6 +729,13 @@ private static boolean gettersAllPrefixed(Set<ExecutableElement> methods) {
* @param elementType the relevant type of the element: the return type for a method, or the
* parameter type for a parameter.
*/
static Optional<String> nullableAnnotationFor(Element element, AnnotatedTypeMirror elementType) {
if (isNullable(elementType)) {
return Optional.of("");
}
return nullableAnnotationFor(element, elementType.getType());
}

static Optional<String> nullableAnnotationFor(Element element, TypeMirror elementType) {
if (isNullable(elementType)) {
return Optional.of("");
Expand All @@ -752,8 +761,22 @@ private static boolean isNullableAnnotation(AnnotationMirror annotation) {
return annotation.getAnnotationType().asElement().getSimpleName().contentEquals("Nullable");
}

private static boolean isNullable(AnnotatedTypeMirror type) {
return isNullable(type.getType()) || nullableAnnotationIndex(type.annotations()).isPresent();
}

private static boolean isNullable(TypeMirror type) {
return nullableAnnotationIndex(type.getAnnotationMirrors()).isPresent();
if (nullableAnnotationIndex(type.getAnnotationMirrors()).isPresent()) {
return true;
}
if (type.getKind().equals(TypeKind.DECLARED)) {
DeclaredType declaredType = (DeclaredType) type;
TypeMirror enclosing = declaredType.getEnclosingType();
if (enclosing != null && enclosing.getKind().equals(TypeKind.DECLARED)) {
return isNullable(enclosing);
}
}
return false;
}

private static boolean isTypeVariableWithNullableBound(TypeMirror type) {
Expand Down Expand Up @@ -1282,14 +1305,27 @@ private ImmutableList<AnnotationMirror> propertyFieldAnnotations(

private static Set<String> getReturnTypeAnnotations(
ExecutableElement method, Predicate<TypeElement> typeFilter) {
return method.getReturnType().getAnnotationMirrors().stream()
return getAllAnnotationMirrors(method.getReturnType()).stream()
.map(a -> a.getAnnotationType().asElement())
.map(MoreElements::asType)
.filter(typeFilter)
.map(e -> e.getQualifiedName().toString())
.collect(toSet());
}

private static ImmutableList<AnnotationMirror> getAllAnnotationMirrors(TypeMirror type) {
ImmutableList.Builder<AnnotationMirror> builder = ImmutableList.builder();
builder.addAll(type.getAnnotationMirrors());
if (type.getKind().equals(TypeKind.DECLARED)) {
DeclaredType declaredType = (DeclaredType) type;
TypeMirror enclosing = declaredType.getEnclosingType();
if (enclosing != null && enclosing.getKind().equals(TypeKind.DECLARED)) {
builder.addAll(getAllAnnotationMirrors(enclosing));
}
}
return builder.build();
}

private boolean annotationAppliesToFields(TypeElement annotation) {
Target target = annotation.getAnnotation(Target.class);
return target == null || Arrays.asList(target.value()).contains(ElementType.FIELD);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,7 @@ public static class PropertySetter {
primitiveParameter = parameterType.getKind().isPrimitive();
this.parameterTypeString = parameterTypeString(setter, parameterType);
VariableElement parameterElement = Iterables.getOnlyElement(setter.getParameters());
Optional<String> maybeNullable =
nullableAnnotationFor(parameterElement, parameterType.getType());
Optional<String> maybeNullable = nullableAnnotationFor(parameterElement, parameterType);
this.nullableAnnotation = maybeNullable.orElse("");
}

Expand Down
Loading