Commit Graph

455 Commits

Author SHA1 Message Date
Sam Brannen
4de2aadf72 Merge branch '6.1.x' 2024-07-10 16:22:17 +02:00
Sam Brannen
83ca2c0cff Support MethodHandle function invocation with varargs array in SpEL
Prior to this commit, the Spring Expression Language (SpEL) could not
invoke a varargs MethodHandle function with an array containing the
variable arguments, although that is supported for a varargs Method
function. Attempting to do so resulted in the array being supplied as a
single argument to the MethodHandle.

This commit addresses this by updating the
executeFunctionViaMethodHandle(...) method in FunctionReference as
follows when the user supplies the varargs already packaged in an array.

- Creates a new array large enough to hold the non-varargs arguments
  and the unpackaged varargs arguments.

- Adds the non-varargs arguments to the beginning of that array and
  adds the unpackaged varargs arguments to the end of that array.

- Invokes the MethodHandle with the new arguments array.

Closes gh-33191
2024-07-10 16:16:41 +02:00
Sam Brannen
bb64e22266 Merge branch '6.1.x' 2024-07-10 13:51:44 +02:00
Sam Brannen
a0f5c16627 Support MethodHandle function invocation with zero varargs in SpEL
Prior to this commit, the Spring Expression Language (SpEL) could not
invoke a varargs MethodHandle function with zero variable arguments,
even though the variable arguments are not required. Attempting to do
so resulted in a SpelEvaluationException with an
INCORRECT_NUMBER_OF_ARGUMENTS_TO_FUNCTION message.

This commit addresses this by updating the
executeFunctionViaMethodHandle(...) method in FunctionReference so that
it properly checks the required number of arguments for both varargs
and non-varargs MethodHandle invocations.

This commit also improves the error message for varargs invocations
with too few arguments. For example, if the MethodHandle requires at
least 1 argument plus a variable number of additional arguments and 0
arguments were supplied, the error message now states:

"Incorrect number of arguments for function 'myFunc': 0 supplied but function takes 1 or more"

Instead of:

"Incorrect number of arguments for function 'myFunc': 0 supplied but function takes 2"

Closes gh-33190
2024-07-10 13:39:48 +02:00
Sam Brannen
ee6402eeca Merge branch '6.1.x' 2024-07-10 12:04:26 +02:00
Sam Brannen
c55c64427c Support single String argument for varargs invocations in SpEL
Prior to this commit, the Spring Expression Language (SpEL) incorrectly
split single String arguments by comma for Object... varargs method and
constructor invocations.

This commit addresses this by checking if the single argument type is
already "assignable" to the varargs component type instead of "equal"
to the varargs component type.

Closes gh-33013
2024-07-10 11:51:55 +02:00
Sam Brannen
54c07eddcc Merge branch '6.1.x' 2024-05-28 10:26:56 +02:00
Sam Brannen
e9de426eb5 Support compilation of map indexing with primitive in SpEL
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
2024-05-28 10:19:15 +02:00
Sam Brannen
8871d67298 Merge branch '6.1.x' 2024-05-27 17:13:01 +02:00
Sam Brannen
cda577d1aa Support compilation of array and list indexing with Integer in SpEL
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
2024-05-27 17:06:48 +02:00
Sam Brannen
d625b3de27 Document SpEL IndexAccessor support in the reference manual
Closes gh-32735
2024-05-15 11:47:42 +02:00
Sam Brannen
fc07946e60 Polishing 2024-05-14 15:03:25 +02:00
Sam Brannen
8fe4493a7d Revise compilation support in SpEL for varargs array subtypes
This commit first reverts changes to SpelNodeImpl from the previous
commit in order to reduce the scope of the overall change set.

This commit then implements a different approach to support type-safe
checks for array subtype compatibility.

In order to support backward compatibility, this commit also
reintroduces generateCodeForArguments(MethodVisitor, CodeFlow, Member,
SpelNodeImpl[]) in deprecated form.

See gh-32804
2024-05-14 14:09:35 +02:00
Mikaël Francoeur
12727a2c4f Support compilation of varargs invocations in SpEL for array subtypes
This commit introduces support for compiling SpEL expressions that
contain varargs invocations where the supplied array is a subtype of
the declared varargs array type.

See gh-32804
2024-05-14 14:09:35 +02:00
Sam Brannen
29bb7b907c Polish SpelCompilationCoverageTests
See gh-32804

Co-authored-by: Mikaël Francoeur <mikael.francoeur@ticketmaster.com>
2024-05-14 14:09:34 +02:00
Sam Brannen
bdc4ecd599 Merge branch '6.1.x'
# Conflicts:
#	spring-expression/src/test/java/org/springframework/expression/spel/SpelCompilationCoverageTests.java
2024-05-03 17:12:40 +03:00
Sam Brannen
aebc48ee8d Revise contribution
See gh-32704
2024-05-03 17:04:11 +03:00
Mikaël Francoeur
f51be0a17e Support varargs invocations in SpEL for varargs array subtype
Closes gh-32704
2024-05-03 17:04:11 +03:00
Sam Brannen
153d1bc923 Support Collection target types in custom IndexAccessors
Prior to this commit, an IndexAccessor could not provide support for a
Collection target type, since the built-in support for indexing into a
Collection in SpEL's Indexer took precedence.

This commit allows an IndexAccessor to support custom Collection target
types by separating the built-in List and Collection support and
applying the built-in Collection support after custom index accessors
have been applied.

Closes gh-32736
2024-05-01 16:12:04 +03:00
Sam Brannen
4e6591e1a9 Polishing 2024-05-01 16:12:04 +03:00
Sam Brannen
35c183d634 Introduce ReflectiveIndexAccessor in SpEL
This commit introduces ReflectiveIndexAccessor for the Spring
Expression Language (SpEL) which is somewhat analogous to the
ReflectivePropertyAccessor implementation of PropertyAccessor.

ReflectiveIndexAccessor is a flexible IndexAccessor implementation that
uses reflection to read from and optionally write to an indexed
structure of a target object. ReflectiveIndexAccessor also implements
CompilableIndexAccessor in order to support compilation to bytecode for
read access.

For example, the following creates a read-write IndexAccessor for a
FruitMap type that is indexed by Color, including built-in support for
compilation to bytecode for read access.

IndexAccessor indexAccessor = new ReflectiveIndexAccessor(
    FruitMap.class, Color.class, "getFruit", "setFruit");

Closes gh-32714
2024-04-30 16:26:11 +03:00
Sam Brannen
9b85c93b6b Polishing 2024-04-29 16:17:38 +03:00
Sam Brannen
fc3dddac9c Polishing 2024-04-28 11:43:14 +03:00
Sam Brannen
27d2200058 Introduce CompilableIndexAccessor SPI in SpEL
This commit introduces a new CompilableIndexAccessor SPI for the Spring
Expression Language (SpEL) which allows an IndexAccessor to support
compilation to bytecode for operations that read an index.

This analogous to the CompilablePropertyAccessor SPI.

This commit also includes a prototype for a general purpose
ReflectiveIndexAccessor in the tests.

Closes gh-32613
2024-04-26 12:19:10 +03:00
Sam Brannen
14689256c4 Support String index type in custom IndexAccessor
Closes gh-32706
2024-04-25 12:17:13 +03:00
Sam Brannen
a3d3bc0a1f Polishing 2024-04-25 12:14:23 +03:00
Sam Brannen
aaf33100d9 Add IndexAccessor support to SpEL's SimpleEvaluationContext
Closes gh-32702
2024-04-24 16:19:39 +03:00
Sam Brannen
ca6d987c56 Support compilation of array and list indexing with Integer in SpEL
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.

Closes gh-32694
2024-04-23 11:36:48 +03:00
Sam Brannen
9eab7bb11d Introduce null-safe indexing test for custom IndexAccessor 2024-04-19 14:29:43 +02:00
Sam Brannen
1c9cff668c Honor IndexAccessor#canWrite() and cache accessors
See gh-26409
See gh-26478
2024-04-10 15:54:34 +02:00
Sam Brannen
22bfe7da5a Introduce proper error handling for IndexAccessor support in SpEL
See gh-26409
See gh-26478
2024-04-10 15:54:34 +02:00
Sam Brannen
5c6b82a947 Change IndexAccessor#read()'s return type to TypedValue
Prior to this commit, the read() method in the IndexAccessor SPI
declared a return type of ValueRef which introduced a package cycle.

This commit addresses this by aligning with the PropertyAccess SPI and
returning TypedValue from IndexAccessor's read() method. This commit
also reworks the internals of Indexer based on a new, local
IndexAccessorValueRef implementation.

See gh-26409
See gh-26478
2024-04-10 15:54:34 +02:00
Sam Brannen
d91277095a Initial review and polish of IndexAccessor support in SpEL
See gh-26409
See gh-26478
2024-04-10 15:54:34 +02:00
ljmn3211
50a0000ed7 Introduce IndexAccessor SPI to customize the SpEL Indexer
See gh-26409
See gh-26478
2024-04-10 15:14:50 +02:00
Sam Brannen
218a148898 Document null-safe index operator in SpEL
See gh-29847
2024-03-23 14:56:01 +01:00
Sam Brannen
38c473fd05 Support compilation of null-safe index operations in SpEL
See gh-29847
2024-03-23 13:48:20 +01:00
Sam Brannen
d2bd0d5716 Retain null-safe syntax in AST representation of SpEL indexers
Prior to this commit, SpEL's CompoundExpression omitted the null-safe
syntax in AST string representations of indexing operations.

To address this, this commit implements isNullSafe() in Indexer.

See gh-29847
2024-03-23 12:46:03 +01:00
Sam Brannen
4d433174eb Revise null-safe index operator support in SpEL
See gh-29847
2024-03-23 12:46:03 +01:00
Grigory Stepanov
9f4d46fe33 Introduce null-safe index operator in SpEL
See gh-29847
2024-03-23 12:38:10 +01:00
Sam Brannen
2a1abb5553 Simplify compilation of array indexing in SpEL's Indexer 2024-03-23 12:35:25 +01:00
Sam Brannen
88bc3f270e Merge branch '6.1.x' 2024-03-22 17:18:38 +01:00
Sam Brannen
52b8c71dcd Retain null-safe syntax in AST representation of selection & projection
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
2024-03-22 17:05:48 +01:00
Sam Brannen
7f40b49f4d Improve names of classes generated by the SpEL compiler
Prior to this commit, the SpEL compiler generated classes in a package
named "spel" with names following the pattern "Ex#", where # was an
index starting with 2.

This resulted in class names such as:

- spel.Ex2
- spel.Ex3

This commit improves the names of classes created by the SpEL compiler
by generating classes in a package named
"org.springframework.expression.spel.generated" with names following
the pattern "CompiledExpression#####", where ##### is a 0-padded
counter starting with 00001.

This results in class names such as:

- org.springframework.expression.spel.generated.CompiledExpression00001
- org.springframework.expression.spel.generated.CompiledExpression00002

This commit also moves the saveGeneratedClassFile() method from
SpelCompilationCoverageTests to SpelCompiler and enhances it to:

- Save classes in a "build/generated-classes" directory.
- Convert package names to directories.
- Create missing parent directories.
- Use logging instead of System.out.println().

Running a test with saveGeneratedClassFile() enabled now logs something
similar to the following.

DEBUG o.s.e.s.s.SpelCompiler - Saving compiled SpEL expression [(#root.empty ? 0 : #root.size)] to [/Users/<username>/spring-framework/spring-expression/build/generated-classes/org/springframework/expression/spel/generated/CompiledExpression00001.class]

Closes gh-32497
2024-03-20 12:34:01 +01:00
Sam Brannen
4c246b7c96 Consistently use canonical annotation names in string representations 2024-03-10 15:54:53 +01:00
Stéphane Nicoll
e53ed3e3c6 Merge branch '6.1.x' 2024-03-09 16:03:04 +01:00
Stéphane Nicoll
4983a802a7 Polish "Fix Javadoc"
See gh-32403
2024-03-09 16:02:01 +01:00
Maksim Sasnouski
abdccffa39 Fix Javadoc
This commit fixes various Javadoc issues across the code base.

See gh-32403
2024-03-09 16:02:00 +01:00
Sam Brannen
65d77624d1 Support SpEL compilation for public methods in private subtypes
Commit c79436f832 ensured that methods are invoked via a public
interface or public superclass when compiling Spring Expression
Language (SpEL) expressions involving method references or property
access (see MethodReference, PropertyOrFieldReference, and
collaborating support classes). However, compilation of expressions
that access properties by indexing into an object by property name is
still not properly supported in all scenarios.

To address those remaining use cases, this commit ensures that methods
are invoked via a public interface or public superclass when accessing
a property by indexing into an object by the property name – for
example, `person['name']` instead of `person.name`.

In addition, SpEL's Indexer now properly relies on the
CompilablePropertyAccessor abstraction instead of hard-coding support
for only OptimalPropertyAccessor. This greatly reduces the complexity
of the Indexer and simultaneously allows the Indexer to potentially
support other CompilablePropertyAccessor implementations.

Closes gh-29857
2024-03-09 14:01:00 +01:00
Sam Brannen
107f47cfcf Add tests for status quo for SpEL compiler 2024-03-09 13:46:39 +01:00
Sam Brannen
3577e3b758 Polish SpEL internals and tests 2024-03-08 17:49:58 +01:00