Include '?' for null-safe navigation in SpEL AST representations
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 gh-31326
This commit is contained in:
parent
0d22569422
commit
6300fb37ad
|
@ -28,7 +28,9 @@ import org.springframework.expression.spel.SpelNode;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a DOT separated expression sequence, such as
|
* 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
|
* <p>May also contain array/collection/map indexers, such as
|
||||||
* {@code property1[0].property2['key']}.
|
* {@code property1[0].property2['key']}.
|
||||||
|
@ -122,6 +124,10 @@ public class CompoundExpression extends SpelNodeImpl {
|
||||||
// Don't append a '.' if the next child is an Indexer.
|
// Don't append a '.' if the next child is an Indexer.
|
||||||
// For example, we want 'myVar[0]' instead of 'myVar.[0]'.
|
// For example, we want 'myVar[0]' instead of 'myVar.[0]'.
|
||||||
if (!(nextChild instanceof Indexer)) {
|
if (!(nextChild instanceof Indexer)) {
|
||||||
|
if ((nextChild instanceof MethodReference methodRef && methodRef.isNullSafe()) ||
|
||||||
|
(nextChild instanceof PropertyOrFieldReference pofRef && pofRef.isNullSafe())) {
|
||||||
|
sb.append('?');
|
||||||
|
}
|
||||||
sb.append('.');
|
sb.append('.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ import org.springframework.util.ObjectUtils;
|
||||||
*
|
*
|
||||||
* @author Andy Clement
|
* @author Andy Clement
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Sam Brannen
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public class MethodReference extends SpelNodeImpl {
|
public class MethodReference extends SpelNodeImpl {
|
||||||
|
@ -72,6 +73,14 @@ public class MethodReference extends SpelNodeImpl {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Get the name of the referenced method.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -47,6 +47,7 @@ class ParsingTests {
|
||||||
void compoundExpressions() {
|
void compoundExpressions() {
|
||||||
parseCheck("property1.property2.methodOne()");
|
parseCheck("property1.property2.methodOne()");
|
||||||
parseCheck("property1[0].property2['key'].methodOne()");
|
parseCheck("property1[0].property2['key'].methodOne()");
|
||||||
|
parseCheck("property1?.methodOne()?.property2?.methodTwo()");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
Loading…
Reference in New Issue