Skip to content

Commit ca6d987

Browse files
committed
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
1 parent 8124491 commit ca6d987

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

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

+7-2
Original file line numberDiff line numberDiff line change
@@ -416,13 +416,13 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
416416
default -> AALOAD;
417417
};
418418

419-
generateIndexCode(index, mv, cf);
419+
generateIndexCode(index, int.class, mv, cf);
420420
mv.visitInsn(insn);
421421
}
422422

423423
else if (this.indexedType == IndexedType.LIST) {
424424
mv.visitTypeInsn(CHECKCAST, "java/util/List");
425-
generateIndexCode(index, mv, cf);
425+
generateIndexCode(index, int.class, mv, cf);
426426
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
427427
}
428428

@@ -473,6 +473,11 @@ private void generateIndexCode(SpelNodeImpl index, MethodVisitor mv, CodeFlow cf
473473
cf.exitCompilationScope();
474474
}
475475

476+
private void generateIndexCode(SpelNodeImpl indexNode, Class<?> indexType, MethodVisitor mv, CodeFlow cf) {
477+
String indexDesc = CodeFlow.toDescriptor(indexType);
478+
generateCodeForArgument(mv, cf, indexNode, indexDesc);
479+
}
480+
476481
@Override
477482
public String toStringAST() {
478483
return "[" + getChild(0).toStringAST() + "]";

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

+26
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,32 @@ void indexIntoObject() {
706706
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
707707
}
708708

709+
@Test // gh-32694
710+
void indexIntoArrayUsingIntegerWrapper() {
711+
context.setVariable("array", new int[] {1, 2, 3, 4});
712+
context.setVariable("index", 2);
713+
714+
expression = parser.parseExpression("#array[#index]");
715+
716+
assertThat(expression.getValue(context)).isEqualTo(3);
717+
assertCanCompile(expression);
718+
assertThat(expression.getValue(context)).isEqualTo(3);
719+
assertThat(getAst().getExitDescriptor()).isEqualTo("I");
720+
}
721+
722+
@Test // gh-32694
723+
void indexIntoListUsingIntegerWrapper() {
724+
context.setVariable("list", List.of(1, 2, 3, 4));
725+
context.setVariable("index", 2);
726+
727+
expression = parser.parseExpression("#list[#index]");
728+
729+
assertThat(expression.getValue(context)).isEqualTo(3);
730+
assertCanCompile(expression);
731+
assertThat(expression.getValue(context)).isEqualTo(3);
732+
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
733+
}
734+
709735
private String stringify(Object object) {
710736
Stream<? extends Object> stream;
711737
if (object instanceof Collection<?> collection) {

0 commit comments

Comments
 (0)