Browse Source

Specify generic type nullness in spring-expression

See gh-34140
pull/34266/head
Sébastien Deleuze 11 months ago
parent
commit
4c988146bc
  1. 6
      spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java
  2. 10
      spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java
  3. 20
      spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java
  4. 16
      spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java
  5. 4
      spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java
  6. 4
      spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java

6
spring-expression/src/main/java/org/springframework/expression/spel/ast/ConstructorReference.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -124,7 +124,7 @@ public class ConstructorReference extends SpelNodeImpl { @@ -124,7 +124,7 @@ public class ConstructorReference extends SpelNodeImpl {
* @throws EvaluationException if there is a problem creating the object
*/
private TypedValue createNewInstance(ExpressionState state) throws EvaluationException {
Object[] arguments = new Object[getChildCount() - 1];
@Nullable Object[] arguments = new Object[getChildCount() - 1];
List<TypeDescriptor> argumentTypes = new ArrayList<>(getChildCount() - 1);
for (int i = 0; i < arguments.length; i++) {
TypedValue childValue = this.children[i + 1].getValueInternal(state);
@ -359,7 +359,7 @@ public class ConstructorReference extends SpelNodeImpl { @@ -359,7 +359,7 @@ public class ConstructorReference extends SpelNodeImpl {
private Object createReferenceTypeArray(ExpressionState state, TypeConverter typeConverter, SpelNodeImpl[] children,
Class<?> componentType) {
Object[] array = (Object[]) Array.newInstance(componentType, children.length);
@Nullable Object[] array = (Object[]) Array.newInstance(componentType, children.length);
TypeDescriptor targetType = TypeDescriptor.valueOf(componentType);
for (int i = 0; i < array.length; i++) {
Object value = children[i].getValue(state);

10
spring-expression/src/main/java/org/springframework/expression/spel/ast/FunctionReference.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -116,7 +116,7 @@ public class FunctionReference extends SpelNodeImpl { @@ -116,7 +116,7 @@ public class FunctionReference extends SpelNodeImpl {
* @throws EvaluationException if there is any problem invoking the method
*/
private TypedValue executeFunctionViaMethod(ExpressionState state, Method method) throws EvaluationException {
Object[] functionArgs = getArguments(state);
@Nullable Object[] functionArgs = getArguments(state);
if (!method.isVarArgs()) {
int declaredParamCount = method.getParameterCount();
@ -175,7 +175,7 @@ public class FunctionReference extends SpelNodeImpl { @@ -175,7 +175,7 @@ public class FunctionReference extends SpelNodeImpl {
* @since 6.1
*/
private TypedValue executeFunctionViaMethodHandle(ExpressionState state, MethodHandle methodHandle) throws EvaluationException {
Object[] functionArgs = getArguments(state);
@Nullable Object[] functionArgs = getArguments(state);
MethodType declaredParams = methodHandle.type();
int spelParamCount = functionArgs.length;
int declaredParamCount = declaredParams.parameterCount();
@ -280,9 +280,9 @@ public class FunctionReference extends SpelNodeImpl { @@ -280,9 +280,9 @@ public class FunctionReference extends SpelNodeImpl {
* Compute the arguments to the function, they are the children of this expression node.
* @return an array of argument values for the function call
*/
private Object[] getArguments(ExpressionState state) throws EvaluationException {
private @Nullable Object[] getArguments(ExpressionState state) throws EvaluationException {
// Compute arguments to the function
Object[] arguments = new Object[getChildCount()];
@Nullable Object[] arguments = new Object[getChildCount()];
for (int i = 0; i < arguments.length; i++) {
arguments[i] = this.children[i].getValueInternal(state).getValue();
}

20
spring-expression/src/main/java/org/springframework/expression/spel/ast/MethodReference.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -90,7 +90,7 @@ public class MethodReference extends SpelNodeImpl { @@ -90,7 +90,7 @@ public class MethodReference extends SpelNodeImpl {
@Override
protected ValueRef getValueRef(ExpressionState state) throws EvaluationException {
Object[] arguments = getArguments(state);
@Nullable Object[] arguments = getArguments(state);
if (state.getActiveContextObject().getValue() == null) {
throwIfNotNullSafe(getArgumentTypes(arguments));
return ValueRef.NullValueRef.INSTANCE;
@ -103,14 +103,14 @@ public class MethodReference extends SpelNodeImpl { @@ -103,14 +103,14 @@ public class MethodReference extends SpelNodeImpl {
EvaluationContext evaluationContext = state.getEvaluationContext();
Object value = state.getActiveContextObject().getValue();
TypeDescriptor targetType = state.getActiveContextObject().getTypeDescriptor();
Object[] arguments = getArguments(state);
@Nullable Object[] arguments = getArguments(state);
TypedValue result = getValueInternal(evaluationContext, value, targetType, arguments);
updateExitTypeDescriptor();
return result;
}
private TypedValue getValueInternal(EvaluationContext evaluationContext,
@Nullable Object value, @Nullable TypeDescriptor targetType, Object[] arguments) {
@Nullable Object value, @Nullable TypeDescriptor targetType, @Nullable Object[] arguments) {
List<TypeDescriptor> argumentTypes = getArgumentTypes(arguments);
if (value == null) {
@ -167,8 +167,8 @@ public class MethodReference extends SpelNodeImpl { @@ -167,8 +167,8 @@ public class MethodReference extends SpelNodeImpl {
}
}
private Object[] getArguments(ExpressionState state) {
Object[] arguments = new Object[getChildCount()];
private @Nullable Object[] getArguments(ExpressionState state) {
@Nullable Object[] arguments = new Object[getChildCount()];
for (int i = 0; i < arguments.length; i++) {
// Make the root object the active context again for evaluating the parameter expressions
try {
@ -182,8 +182,8 @@ public class MethodReference extends SpelNodeImpl { @@ -182,8 +182,8 @@ public class MethodReference extends SpelNodeImpl {
return arguments;
}
private List<TypeDescriptor> getArgumentTypes(Object... arguments) {
List<TypeDescriptor> descriptors = new ArrayList<>(arguments.length);
private List<TypeDescriptor> getArgumentTypes(@Nullable Object... arguments) {
List<@Nullable TypeDescriptor> descriptors = new ArrayList<>(arguments.length);
for (Object argument : arguments) {
descriptors.add(TypeDescriptor.forObject(argument));
}
@ -380,9 +380,9 @@ public class MethodReference extends SpelNodeImpl { @@ -380,9 +380,9 @@ public class MethodReference extends SpelNodeImpl {
private final @Nullable TypeDescriptor targetType;
private final Object[] arguments;
private final @Nullable Object[] arguments;
public MethodValueRef(ExpressionState state, Object[] arguments) {
public MethodValueRef(ExpressionState state, @Nullable Object[] arguments) {
this.evaluationContext = state.getEvaluationContext();
this.value = state.getActiveContextObject().getValue();
this.targetType = state.getActiveContextObject().getTypeDescriptor();

16
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectionHelper.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -250,7 +250,7 @@ public abstract class ReflectionHelper { @@ -250,7 +250,7 @@ public abstract class ReflectionHelper {
* @return {@code true} if some kind of conversion occurred on an argument
* @throws SpelEvaluationException if a problem occurs during conversion
*/
public static boolean convertAllArguments(TypeConverter converter, Object[] arguments, Method method)
public static boolean convertAllArguments(TypeConverter converter, @Nullable Object[] arguments, Method method)
throws SpelEvaluationException {
Integer varargsPosition = (method.isVarArgs() ? method.getParameterCount() - 1 : null);
@ -269,7 +269,8 @@ public abstract class ReflectionHelper { @@ -269,7 +269,8 @@ public abstract class ReflectionHelper {
* @return {@code true} if some kind of conversion occurred on an argument
* @throws EvaluationException if a problem occurs during conversion
*/
static boolean convertArguments(TypeConverter converter, Object[] arguments, Executable executable,
@SuppressWarnings("NullAway") // Dataflow analysis limitation
static boolean convertArguments(TypeConverter converter, @Nullable Object[] arguments, Executable executable,
@Nullable Integer varargsPosition) throws EvaluationException {
boolean conversionOccurred = false;
@ -359,7 +360,8 @@ public abstract class ReflectionHelper { @@ -359,7 +360,8 @@ public abstract class ReflectionHelper {
* @throws EvaluationException if a problem occurs during conversion
* @since 6.1
*/
public static boolean convertAllMethodHandleArguments(TypeConverter converter, Object[] arguments,
@SuppressWarnings("NullAway") // Dataflow analysis limitation
public static boolean convertAllMethodHandleArguments(TypeConverter converter, @Nullable Object[] arguments,
MethodHandle methodHandle, @Nullable Integer varargsPosition) throws EvaluationException {
boolean conversionOccurred = false;
@ -453,7 +455,7 @@ public abstract class ReflectionHelper { @@ -453,7 +455,7 @@ public abstract class ReflectionHelper {
* @param possibleArray an array object that may have the supplied value as the first element
* @return true if the supplied value is the first entry in the array
*/
private static boolean isFirstEntryInArray(Object value, @Nullable Object possibleArray) {
private static boolean isFirstEntryInArray(@Nullable Object value, @Nullable Object possibleArray) {
if (possibleArray == null) {
return false;
}
@ -477,7 +479,7 @@ public abstract class ReflectionHelper { @@ -477,7 +479,7 @@ public abstract class ReflectionHelper {
* @param args the arguments to be set up for the invocation
* @return a repackaged array of arguments where any varargs setup has been performed
*/
public static Object[] setupArgumentsForVarargsInvocation(Class<?>[] requiredParameterTypes, Object... args) {
public static @Nullable Object[] setupArgumentsForVarargsInvocation(Class<?>[] requiredParameterTypes, @Nullable Object... args) {
Assert.notEmpty(requiredParameterTypes, "Required parameter types array must not be empty");
int parameterCount = requiredParameterTypes.length;
@ -491,7 +493,7 @@ public abstract class ReflectionHelper { @@ -491,7 +493,7 @@ public abstract class ReflectionHelper {
// Check if repackaging is needed...
if (parameterCount != argumentCount || !lastRequiredParameterType.isInstance(lastArgument)) {
// Create an array for the leading arguments plus the varargs array argument.
Object[] newArgs = new Object[parameterCount];
@Nullable Object[] newArgs = new Object[parameterCount];
// Copy all leading arguments to the new array, omitting the varargs array argument.
System.arraycopy(args, 0, newArgs, 0, newArgs.length - 1);

4
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveConstructorExecutor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2025 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.
@ -52,7 +52,7 @@ public class ReflectiveConstructorExecutor implements ConstructorExecutor { @@ -52,7 +52,7 @@ public class ReflectiveConstructorExecutor implements ConstructorExecutor {
}
@Override
public TypedValue execute(EvaluationContext context, Object... arguments) throws AccessException {
public TypedValue execute(EvaluationContext context, @Nullable Object... arguments) throws AccessException {
try {
ReflectionHelper.convertArguments(
context.getTypeConverter(), arguments, this.ctor, this.varargsPosition);

4
spring-expression/src/main/java/org/springframework/expression/spel/support/ReflectiveMethodExecutor.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -102,7 +102,7 @@ public class ReflectiveMethodExecutor implements MethodExecutor { @@ -102,7 +102,7 @@ public class ReflectiveMethodExecutor implements MethodExecutor {
@Override
public TypedValue execute(EvaluationContext context, Object target, Object... arguments) throws AccessException {
public TypedValue execute(EvaluationContext context, Object target, @Nullable Object... arguments) throws AccessException {
try {
this.argumentConversionOccurred = ReflectionHelper.convertArguments(
context.getTypeConverter(), arguments, this.originalMethod, this.varargsPosition);

Loading…
Cancel
Save