Skip to content

Commit

Permalink
Add support for AnnotatedType in MethodParameter.hasNullableAnnotation
Browse files Browse the repository at this point in the history
This commit adds support for detecting annotated types.

See spring-projectsgh-28797
  • Loading branch information
sdeleuze committed Dec 19, 2024
1 parent 69e1671 commit 06f36f2
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -18,6 +18,7 @@

import java.lang.annotation.Annotation;
import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Field;
Expand Down Expand Up @@ -388,8 +389,8 @@ private MethodParameter nested(int nestingLevel, @Nullable Integer typeIndex) {
/**
* Return whether this method indicates a parameter which is not required:
* either in the form of Java 8's {@link java.util.Optional}, any variant
* of a parameter-level {@code Nullable} annotation (such as from JSR-305
* or the FindBugs set of annotations), or a language-level nullable type
* of a parameter-level {@code Nullable} annotation (such as from JSpecify,
* JSR-305 or Jakarta set of annotations), or a language-level nullable type
* declaration or {@code Continuation} parameter in Kotlin.
* @since 4.3
*/
Expand All @@ -402,15 +403,22 @@ public boolean isOptional() {

/**
* Check whether this method parameter is annotated with any variant of a
* {@code Nullable} annotation, for example, {@code jakarta.annotation.Nullable} or
* {@code edu.umd.cs.findbugs.annotations.Nullable}.
* {@code Nullable} annotation, for example, {@code org.springframework.lang.Nullable},
* {@code org.jspecify.annotations.Nullable} or {@code jakarta.annotation.Nullable}.
*/
private boolean hasNullableAnnotation() {
for (Annotation ann : getParameterAnnotations()) {
if ("Nullable".equals(ann.annotationType().getSimpleName())) {
return true;
}
}
for (AnnotatedType annotatedType : this.executable.getAnnotatedParameterTypes()) {
for (Annotation ann : annotatedType.getAnnotations()) {
if ("Nullable".equals(ann.annotationType().getSimpleName())) {
return true;
}
}
}
return false;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,21 @@ class MethodParameterTests {

private MethodParameter intReturnType;

private MethodParameter jspecifyNullableParameter;

private MethodParameter springNullableParameter;


@BeforeEach
void setup() throws NoSuchMethodException {
method = getClass().getMethod("method", String.class, long.class);
stringParameter = new MethodParameter(method, 0);
longParameter = new MethodParameter(method, 1);
intReturnType = new MethodParameter(method, -1);
Method jspecifyNullableMethod = getClass().getMethod("jspecifyNullableMethod", String.class);
jspecifyNullableParameter = new MethodParameter(jspecifyNullableMethod, 0);
Method springNullableMethod = getClass().getMethod("springNullableMethod", String.class);
springNullableParameter = new MethodParameter(springNullableMethod, 0);
}


Expand Down Expand Up @@ -238,21 +246,29 @@ void nestedWithTypeIndexReturnsNewInstance() throws Exception {
}

@Test
void nullableWithSpringAnnotation() {
MethodParameter m = MethodParameter.forExecutable(method, 1);
assertThat(m.isOptional()).isTrue();
void jspecifyNullableParameter() {
assertThat(jspecifyNullableParameter.isOptional()).isTrue();
}

@Test
void nullableWithJSpecifyAnnotation() {
MethodParameter m = MethodParameter.forExecutable(method, 0);
assertThat(m.isOptional()).isTrue();
void springNullableParameter() {
assertThat(springNullableParameter.isOptional()).isTrue();
}

public int method(@org.jspecify.annotations.Nullable String p1, @org.springframework.lang.Nullable long p2) {
public int method(String p1, long p2) {
return 42;
}

public @org.jspecify.annotations.Nullable String jspecifyNullableMethod(@org.jspecify.annotations.Nullable String parameter) {
return parameter;
}

@SuppressWarnings("deprecation")
@org.springframework.lang.Nullable
public String springNullableMethod(@org.springframework.lang.Nullable String parameter) {
return parameter;
}

@SuppressWarnings("unused")
private static class NestedClass {

Expand Down

0 comments on commit 06f36f2

Please sign in to comment.