Skip to content

Commit 5ad853e

Browse files
committed
Do not precede indexed access with a dot in SpEL AST representation
Prior to this commit, if a Spring Expression Language (SpEL) expression contained indexed access to an object, the generated AST String representation incorrectly included a dot ('.') before the index access. For example, 'property[0]' had a generated AST string representation of 'property.[0]'. This commit addresses this by reworking the logic in CompoundExpression.toStringAST(). Closes gh-30610
1 parent dfbed61 commit 5ad853e

File tree

2 files changed

+22
-5
lines changed

2 files changed

+22
-5
lines changed

spring-expression/src/main/java/org/springframework/expression/spel/ast/CompoundExpression.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.springframework.expression.spel.ast;
1818

19-
import java.util.StringJoiner;
2019
import java.util.function.Supplier;
2120

2221
import org.springframework.asm.MethodVisitor;
@@ -25,10 +24,14 @@
2524
import org.springframework.expression.spel.CodeFlow;
2625
import org.springframework.expression.spel.ExpressionState;
2726
import org.springframework.expression.spel.SpelEvaluationException;
27+
import org.springframework.expression.spel.SpelNode;
2828

2929
/**
3030
* Represents a DOT separated expression sequence, such as
31-
* {@code 'property1.property2.methodOne()'}.
31+
* {@code property1.property2.methodOne()}.
32+
*
33+
* <p>May also contain array/collection/map indexers, such as
34+
* {@code property1[0].property2['key']}.
3235
*
3336
* @author Andy Clement
3437
* @author Sam Brannen
@@ -111,11 +114,19 @@ public boolean isWritable(ExpressionState state) throws EvaluationException {
111114

112115
@Override
113116
public String toStringAST() {
114-
StringJoiner sj = new StringJoiner(".");
117+
StringBuilder sb = new StringBuilder();
115118
for (int i = 0; i < getChildCount(); i++) {
116-
sj.add(getChild(i).toStringAST());
119+
sb.append(getChild(i).toStringAST());
120+
if (i < getChildCount() - 1) {
121+
SpelNode nextChild = getChild(i + 1);
122+
// Don't append a '.' if the next child is an Indexer.
123+
// For example, we want 'myVar[0]' instead of 'myVar.[0]'.
124+
if (!(nextChild instanceof Indexer)) {
125+
sb.append('.');
126+
}
127+
}
117128
}
118-
return sj.toString();
129+
return sb.toString();
119130
}
120131

121132
@Override

spring-expression/src/test/java/org/springframework/expression/spel/ParsingTests.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ class ParsingTests {
4343
@Nested
4444
class Miscellaneous {
4545

46+
@Test
47+
void compoundExpressions() {
48+
parseCheck("property1.property2.methodOne()");
49+
parseCheck("property1[0].property2['key'].methodOne()");
50+
}
51+
4652
@Test
4753
void supportedCharactersInIdentifiers() {
4854
parseCheck("#var='value'");

0 commit comments

Comments
 (0)