Add support for AnnotatedType in MethodParameter.hasNullableAnnotation
This commit adds support for detecting annotated types. See gh-28797
This commit is contained in:
@@ -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.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.core;
|
||||
|
||||
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;
|
||||
@@ -388,8 +389,8 @@ public class MethodParameter {
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@@ -402,8 +403,8 @@ public class MethodParameter {
|
||||
|
||||
/**
|
||||
* 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()) {
|
||||
@@ -411,6 +412,13 @@ public class MethodParameter {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (AnnotatedType annotatedType : this.executable.getAnnotatedParameterTypes()) {
|
||||
for (Annotation ann : annotatedType.getAnnotations()) {
|
||||
if ("Nullable".equals(ann.annotationType().getSimpleName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,10 @@ class MethodParameterTests {
|
||||
|
||||
private MethodParameter intReturnType;
|
||||
|
||||
private MethodParameter jspecifyNullableParameter;
|
||||
|
||||
private MethodParameter springNullableParameter;
|
||||
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws NoSuchMethodException {
|
||||
@@ -56,6 +60,10 @@ class MethodParameterTests {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -238,21 +246,29 @@ class MethodParameterTests {
|
||||
}
|
||||
|
||||
@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 {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user