Prior to this commit, the Spring Expression Language (SpEL) failed to
compile an expression that indexed into a Map using a primitive literal
(boolean, int, long, float, or double).
This commit adds support for compilation of such expressions by
ensuring that primitive literals are boxed into their corresponding
wrapper types in the compiled bytecode.
Closes gh-32903
Prior to this commit, the Spring Expression Language (SpEL) failed to
compile an expression that indexed into any array or list using an
Integer.
This commit adds support for compilation of such expressions by
ensuring that an Integer is unboxed into an int in the compiled
bytecode.
See gh-32694
Closes gh-32908
Prior to this commit, SpEL's CompoundExpression omitted the null-safe
syntax in AST string representations of the selection and projection
operators.
To address this, this commit implements isNullSafe() in Projection and
Selection.
Closes gh-32515
Prior to this commit, MethodReference and PropertyOrFieldReference
already defined local isNullSafe() methods, but we need identical
methods in Selection, Projection, and Indexer, and we may potentially
need null-safe support for additional operators in the future.
To address the common need for an is-null-safe check, this commit
introduces an isNullSafe() method in SpelNodeImpl with a default
implementation that returns false.
Closes gh-32516
Prior to this commit, if a Spring Expression Language (SpEL) expression
referenced the root context object via the #root or #this variable, we
inserted a checkcast in the generated byte code that cast the object to
its concrete type. However if the root context object's type was
non-public, that resulted in an IllegalAccessError when the compiled
byte code was executed.
VariableReference.getValueInternal() already contains a solution for
global variables which inserts a checkcast to Object in the generated
byte code instead of to the object's concrete non-public type.
This commit therefore applies the same logic to #root (or #this when
used to reference the root context object) that is already applied to
global variables.
Closes gh-32356
Although EvaluationContext defines the API for setting and looking up
variables, the internals of the Spring Expression Language (SpEL)
actually provide explicit support for registering functions as
variables.
This is self-evident in the two registerFunction() variants in
StandardEvaluationContext; however, functions can also be registered as
variables when using the SimpleEvaluationContext.
Since custom functions are also viable in use cases involving the
SimpleEvaluationContext, this commit documents that functions may be
registered in a SimpleEvaluationContext via setVariable().
This commit also explicitly documents the "function as a variable"
behavior in the class-level Javadoc for both StandardEvaluationContext
and SimpleEvaluationContext, as well as in the reference manual.
Closes gh-32258
To improve consistency and avoid confusion regarding primitive types
and their wrapper types, this commit ensures that we always use class
literals for primitive types.
For example, instead of using the `Void.TYPE` constant, we now
consistently use `void.class`.
Prior to this commit, SpEL's Indexer incorrectly requested conversion
to wrappers instead of primitives when setting an element in a
primitive array.
This commit addresses this by requesting primitive conversion -- for
example, conversion to `int.class` instead of `Integer.class` when
setting a value in an `int[]` array.
For greater clarity, this commit also switches from using `TYPE`
constants in wrapper classes to primitive class literals -- for
example, from `Integer.TYPE` to `int.class`.
Closes gh-32147