Specify generic type nullness in spring-expression
See gh-34140
This commit is contained in:
@@ -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 {
|
||||
* @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 {
|
||||
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);
|
||||
|
||||
@@ -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 {
|
||||
* @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 {
|
||||
* @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 {
|
||||
* 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();
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@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 {
|
||||
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 {
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
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 {
|
||||
|
||||
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();
|
||||
|
||||
@@ -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 {
|
||||
* @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 {
|
||||
* @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 {
|
||||
* @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 {
|
||||
* @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 {
|
||||
* @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 {
|
||||
// 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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
|
||||
@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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
|
||||
@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);
|
||||
|
||||
Reference in New Issue
Block a user