Refine null-safety in the spring-expression module

Closes gh-34156
This commit is contained in:
Sébastien Deleuze 2024-12-26 14:59:50 +01:00
parent 4747ab67e6
commit be11e73d2c
5 changed files with 8 additions and 9 deletions

View File

@ -153,7 +153,7 @@ public class ExpressionException extends RuntimeException {
* that caused the failure. * that caused the failure.
* @since 4.0 * @since 4.0
*/ */
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Dataflow analysis limitation
public String getSimpleMessage() { public String getSimpleMessage() {
return super.getMessage(); return super.getMessage();
} }

View File

@ -174,7 +174,6 @@ public class FunctionReference extends SpelNodeImpl {
* @throws EvaluationException if there is any problem invoking the method * @throws EvaluationException if there is any problem invoking the method
* @since 6.1 * @since 6.1
*/ */
@SuppressWarnings("NullAway") // TODO Remove when NullAway 0.12.2 is released, see https://github.com/uber/NullAway/pull/1089
private TypedValue executeFunctionViaMethodHandle(ExpressionState state, MethodHandle methodHandle) throws EvaluationException { private TypedValue executeFunctionViaMethodHandle(ExpressionState state, MethodHandle methodHandle) throws EvaluationException {
Object[] functionArgs = getArguments(state); Object[] functionArgs = getArguments(state);
MethodType declaredParams = methodHandle.type(); MethodType declaredParams = methodHandle.type();

View File

@ -351,7 +351,7 @@ public abstract class Operator extends SpelNodeImpl {
* @param rightActualDescriptor the dynamic/runtime right object descriptor * @param rightActualDescriptor the dynamic/runtime right object descriptor
* @return a DescriptorComparison object indicating the type of compatibility, if any * @return a DescriptorComparison object indicating the type of compatibility, if any
*/ */
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Dataflow analysis limitation
public static DescriptorComparison checkNumericCompatibility( public static DescriptorComparison checkNumericCompatibility(
@Nullable String leftDeclaredDescriptor, @Nullable String rightDeclaredDescriptor, @Nullable String leftDeclaredDescriptor, @Nullable String rightDeclaredDescriptor,
@Nullable String leftActualDescriptor, @Nullable String rightActualDescriptor) { @Nullable String leftActualDescriptor, @Nullable String rightActualDescriptor) {

View File

@ -166,7 +166,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
// | (DEFAULT^ logicalOrExpression) // | (DEFAULT^ logicalOrExpression)
// | (QMARK^ expression COLON! expression) // | (QMARK^ expression COLON! expression)
// | (ELVIS^ expression))?; // | (ELVIS^ expression))?;
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Not null assertion performed in SpelNodeImpl constructor
private @Nullable SpelNodeImpl eatExpression() { private @Nullable SpelNodeImpl eatExpression() {
SpelNodeImpl expr = eatLogicalOrExpression(); SpelNodeImpl expr = eatLogicalOrExpression();
Token t = peekToken(); Token t = peekToken();
@ -273,7 +273,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
} }
//sumExpression: productExpression ( (PLUS^ | MINUS^) productExpression)*; //sumExpression: productExpression ( (PLUS^ | MINUS^) productExpression)*;
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Not null assertion performed in SpelNodeImpl constructor
private @Nullable SpelNodeImpl eatSumExpression() { private @Nullable SpelNodeImpl eatSumExpression() {
SpelNodeImpl expr = eatProductExpression(); SpelNodeImpl expr = eatProductExpression();
while (peekToken(TokenKind.PLUS, TokenKind.MINUS, TokenKind.INC)) { while (peekToken(TokenKind.PLUS, TokenKind.MINUS, TokenKind.INC)) {
@ -311,7 +311,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
} }
// powerExpr : unaryExpression (POWER^ unaryExpression)? (INC || DEC) ; // powerExpr : unaryExpression (POWER^ unaryExpression)? (INC || DEC) ;
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Not null assertion performed in SpelNodeImpl constructor
private @Nullable SpelNodeImpl eatPowerIncDecExpression() { private @Nullable SpelNodeImpl eatPowerIncDecExpression() {
SpelNodeImpl expr = eatUnaryExpression(); SpelNodeImpl expr = eatUnaryExpression();
if (peekToken(TokenKind.POWER)) { if (peekToken(TokenKind.POWER)) {
@ -331,7 +331,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
} }
// unaryExpression: (PLUS^ | MINUS^ | BANG^ | INC^ | DEC^) unaryExpression | primaryExpression ; // unaryExpression: (PLUS^ | MINUS^ | BANG^ | INC^ | DEC^) unaryExpression | primaryExpression ;
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Not null assertion performed in SpelNodeImpl constructor
private @Nullable SpelNodeImpl eatUnaryExpression() { private @Nullable SpelNodeImpl eatUnaryExpression() {
if (peekToken(TokenKind.NOT, TokenKind.PLUS, TokenKind.MINUS)) { if (peekToken(TokenKind.NOT, TokenKind.PLUS, TokenKind.MINUS)) {
Token t = takeToken(); Token t = takeToken();

View File

@ -154,7 +154,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
} }
@Override @Override
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Dataflow analysis limitation
public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException { public TypedValue read(EvaluationContext context, @Nullable Object target, String name) throws AccessException {
Assert.state(target != null, "Target must not be null"); Assert.state(target != null, "Target must not be null");
Class<?> type = (target instanceof Class<?> clazz ? clazz : target.getClass()); Class<?> type = (target instanceof Class<?> clazz ? clazz : target.getClass());
@ -507,7 +507,7 @@ public class ReflectivePropertyAccessor implements PropertyAccessor {
* <p>Note: An optimized accessor is currently only usable for read attempts. * <p>Note: An optimized accessor is currently only usable for read attempts.
* Do not call this method if you need a read-write accessor. * Do not call this method if you need a read-write accessor.
*/ */
@SuppressWarnings("NullAway") @SuppressWarnings("NullAway") // Dataflow analysis limitation
public PropertyAccessor createOptimalAccessor(EvaluationContext context, @Nullable Object target, String name) { public PropertyAccessor createOptimalAccessor(EvaluationContext context, @Nullable Object target, String name) {
// Don't be clever for arrays or a null target... // Don't be clever for arrays or a null target...
if (target == null) { if (target == null) {