Browse Source

Add support for AnnotatedType in MethodParameter.hasNullableAnnotation

This commit adds support for detecting annotated types.

See gh-28797
pull/34134/head
Sébastien Deleuze 1 year ago
parent
commit
b3586560c1
  1. 18
      spring-core/src/main/java/org/springframework/core/MethodParameter.java
  2. 30
      spring-core/src/test/java/org/springframework/core/MethodParameterTests.java

18
spring-core/src/main/java/org/springframework/core/MethodParameter.java

@ -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"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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.annotation.Annotation;
import java.lang.reflect.AnnotatedElement; import java.lang.reflect.AnnotatedElement;
import java.lang.reflect.AnnotatedType;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Executable; import java.lang.reflect.Executable;
import java.lang.reflect.Field; import java.lang.reflect.Field;
@ -388,8 +389,8 @@ public class MethodParameter {
/** /**
* Return whether this method indicates a parameter which is not required: * 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 * 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 * of a parameter-level {@code Nullable} annotation (such as from JSpecify,
* or the FindBugs set of annotations), or a language-level nullable type * JSR-305 or Jakarta set of annotations), or a language-level nullable type
* declaration or {@code Continuation} parameter in Kotlin. * declaration or {@code Continuation} parameter in Kotlin.
* @since 4.3 * @since 4.3
*/ */
@ -402,8 +403,8 @@ public class MethodParameter {
/** /**
* Check whether this method parameter is annotated with any variant of a * Check whether this method parameter is annotated with any variant of a
* {@code Nullable} annotation, for example, {@code jakarta.annotation.Nullable} or * {@code Nullable} annotation, for example, {@code org.springframework.lang.Nullable},
* {@code edu.umd.cs.findbugs.annotations.Nullable}. * {@code org.jspecify.annotations.Nullable} or {@code jakarta.annotation.Nullable}.
*/ */
private boolean hasNullableAnnotation() { private boolean hasNullableAnnotation() {
for (Annotation ann : getParameterAnnotations()) { for (Annotation ann : getParameterAnnotations()) {
@ -411,6 +412,13 @@ public class MethodParameter {
return true; return true;
} }
} }
for (AnnotatedType annotatedType : this.executable.getAnnotatedParameterTypes()) {
for (Annotation ann : annotatedType.getAnnotations()) {
if ("Nullable".equals(ann.annotationType().getSimpleName())) {
return true;
}
}
}
return false; return false;
} }

30
spring-core/src/test/java/org/springframework/core/MethodParameterTests.java

@ -49,6 +49,10 @@ class MethodParameterTests {
private MethodParameter intReturnType; private MethodParameter intReturnType;
private MethodParameter jspecifyNullableParameter;
private MethodParameter springNullableParameter;
@BeforeEach @BeforeEach
void setup() throws NoSuchMethodException { void setup() throws NoSuchMethodException {
@ -56,6 +60,10 @@ class MethodParameterTests {
stringParameter = new MethodParameter(method, 0); stringParameter = new MethodParameter(method, 0);
longParameter = new MethodParameter(method, 1); longParameter = new MethodParameter(method, 1);
intReturnType = 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 @Test
void nullableWithSpringAnnotation() { void jspecifyNullableParameter() {
MethodParameter m = MethodParameter.forExecutable(method, 1); assertThat(jspecifyNullableParameter.isOptional()).isTrue();
assertThat(m.isOptional()).isTrue();
} }
@Test @Test
void nullableWithJSpecifyAnnotation() { void springNullableParameter() {
MethodParameter m = MethodParameter.forExecutable(method, 0); assertThat(springNullableParameter.isOptional()).isTrue();
assertThat(m.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; 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") @SuppressWarnings("unused")
private static class NestedClass { private static class NestedClass {

Loading…
Cancel
Save