Skip to content

Commit

Permalink
Include '?' for null-safe navigation in SpEL AST representations
Browse files Browse the repository at this point in the history
Prior to this commit, if a Spring Expression Language (SpEL) expression
contained property, field, or method references using the null-safe
navigation operator (?.), the generated AST String representation
incorrectly omitted the '?' characters.

For example, 'myProperty?.myMethod()' had a generated AST string
representation of 'myProperty.myMethod()'.

This commit addresses this by introducing isNullSafe() in
MethodReference and reworking the logic in
CompoundExpression.toStringAST().

Closes spring-projectsgh-31326
  • Loading branch information
sbrannen committed Sep 27, 2023
1 parent 0d22569 commit 6300fb3
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@

/**
* Represents a DOT separated expression sequence, such as
* {@code property1.property2.methodOne()}.
* {@code property1.property2.methodOne()} or
* {@code property1?.property2?.methodOne()} when the null-safe navigation
* operator is used.
*
* <p>May also contain array/collection/map indexers, such as
* {@code property1[0].property2['key']}.
Expand Down Expand Up @@ -122,6 +124,10 @@ public String toStringAST() {
// Don't append a '.' if the next child is an Indexer.
// For example, we want 'myVar[0]' instead of 'myVar.[0]'.
if (!(nextChild instanceof Indexer)) {
if ((nextChild instanceof MethodReference methodRef && methodRef.isNullSafe()) ||
(nextChild instanceof PropertyOrFieldReference pofRef && pofRef.isNullSafe())) {
sb.append('?');
}
sb.append('.');
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
*
* @author Andy Clement
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.0
*/
public class MethodReference extends SpelNodeImpl {
Expand All @@ -72,6 +73,14 @@ public MethodReference(boolean nullSafe, String methodName, int startPos, int en
}


/**
* Does this node represent a null-safe method reference?
* @since 6.0.13
*/
public final boolean isNullSafe() {
return this.nullSafe;
}

/**
* Get the name of the referenced method.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class Miscellaneous {
void compoundExpressions() {
parseCheck("property1.property2.methodOne()");
parseCheck("property1[0].property2['key'].methodOne()");
parseCheck("property1?.methodOne()?.property2?.methodTwo()");
}

@Test
Expand Down

0 comments on commit 6300fb3

Please sign in to comment.