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
This commit is contained in:
parent
8124491249
commit
ca6d987c56
|
|
@ -416,13 +416,13 @@ public class Indexer extends SpelNodeImpl {
|
|||
default -> AALOAD;
|
||||
};
|
||||
|
||||
generateIndexCode(index, mv, cf);
|
||||
generateIndexCode(index, int.class, mv, cf);
|
||||
mv.visitInsn(insn);
|
||||
}
|
||||
|
||||
else if (this.indexedType == IndexedType.LIST) {
|
||||
mv.visitTypeInsn(CHECKCAST, "java/util/List");
|
||||
generateIndexCode(index, mv, cf);
|
||||
generateIndexCode(index, int.class, mv, cf);
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "get", "(I)Ljava/lang/Object;", true);
|
||||
}
|
||||
|
||||
|
|
@ -473,6 +473,11 @@ public class Indexer extends SpelNodeImpl {
|
|||
cf.exitCompilationScope();
|
||||
}
|
||||
|
||||
private void generateIndexCode(SpelNodeImpl indexNode, Class<?> indexType, MethodVisitor mv, CodeFlow cf) {
|
||||
String indexDesc = CodeFlow.toDescriptor(indexType);
|
||||
generateCodeForArgument(mv, cf, indexNode, indexDesc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toStringAST() {
|
||||
return "[" + getChild(0).toStringAST() + "]";
|
||||
|
|
|
|||
|
|
@ -706,6 +706,32 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
|||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/String");
|
||||
}
|
||||
|
||||
@Test // gh-32694
|
||||
void indexIntoArrayUsingIntegerWrapper() {
|
||||
context.setVariable("array", new int[] {1, 2, 3, 4});
|
||||
context.setVariable("index", 2);
|
||||
|
||||
expression = parser.parseExpression("#array[#index]");
|
||||
|
||||
assertThat(expression.getValue(context)).isEqualTo(3);
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(context)).isEqualTo(3);
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("I");
|
||||
}
|
||||
|
||||
@Test // gh-32694
|
||||
void indexIntoListUsingIntegerWrapper() {
|
||||
context.setVariable("list", List.of(1, 2, 3, 4));
|
||||
context.setVariable("index", 2);
|
||||
|
||||
expression = parser.parseExpression("#list[#index]");
|
||||
|
||||
assertThat(expression.getValue(context)).isEqualTo(3);
|
||||
assertCanCompile(expression);
|
||||
assertThat(expression.getValue(context)).isEqualTo(3);
|
||||
assertThat(getAst().getExitDescriptor()).isEqualTo("Ljava/lang/Object");
|
||||
}
|
||||
|
||||
private String stringify(Object object) {
|
||||
Stream<? extends Object> stream;
|
||||
if (object instanceof Collection<?> collection) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue