Skip to content

Commit f87a37f

Browse files
committed
Fix SpEL compilation for non trivial elvis operand
Issue: SPR-17214
1 parent 48c660f commit f87a37f

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -79,10 +79,12 @@ public boolean isCompilable() {
7979
public void generateCode(MethodVisitor mv, CodeFlow cf) {
8080
// exit type descriptor can be null if both components are literal expressions
8181
computeExitTypeDescriptor();
82+
cf.enterCompilationScope();
8283
this.children[0].generateCode(mv, cf);
8384
String lastDesc = cf.lastDescriptor();
8485
Assert.state(lastDesc != null, "No last descriptor");
8586
CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0));
87+
cf.exitCompilationScope();
8688
Label elseTarget = new Label();
8789
Label endOfIf = new Label();
8890
mv.visitInsn(DUP);
@@ -95,12 +97,14 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
9597
mv.visitJumpInsn(IFEQ, endOfIf); // if not empty, drop through to elseTarget
9698
mv.visitLabel(elseTarget);
9799
mv.visitInsn(POP);
100+
cf.enterCompilationScope();
98101
this.children[1].generateCode(mv, cf);
99102
if (!CodeFlow.isPrimitive(this.exitTypeDescriptor)) {
100103
lastDesc = cf.lastDescriptor();
101104
Assert.state(lastDesc != null, "No last descriptor");
102105
CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0));
103106
}
107+
cf.exitCompilationScope();
104108
mv.visitLabel(endOfIf);
105109
cf.pushDescriptor(this.exitTypeDescriptor);
106110
}

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

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4898,6 +4898,71 @@ public void elvisOperator_SPR15192() {
48984898
assertIsCompiled(exp);
48994899
}
49004900

4901+
4902+
@Test
4903+
public void elvisOperator_SPR17214() throws Exception {
4904+
SpelParserConfiguration spc = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
4905+
SpelExpressionParser sep = new SpelExpressionParser(spc);
4906+
4907+
RecordHolder rh = null;
4908+
4909+
expression = sep.parseExpression("record.get('abc')?:record.put('abc',expression.someLong?.longValue())");
4910+
rh = new RecordHolder();
4911+
assertNull(expression.getValue(rh));
4912+
assertEquals(3L,expression.getValue(rh));
4913+
assertCanCompile(expression);
4914+
rh = new RecordHolder();
4915+
assertNull(expression.getValue(rh));
4916+
assertEquals(3L,expression.getValue(rh));
4917+
4918+
expression = sep.parseExpression("record.get('abc')?:record.put('abc',3L.longValue())");
4919+
rh = new RecordHolder();
4920+
assertNull(expression.getValue(rh));
4921+
assertEquals(3L,expression.getValue(rh));
4922+
assertCanCompile(expression);
4923+
rh = new RecordHolder();
4924+
assertNull(expression.getValue(rh));
4925+
assertEquals(3L,expression.getValue(rh));
4926+
4927+
expression = sep.parseExpression("record.get('abc')?:record.put('abc',3L.longValue())");
4928+
rh = new RecordHolder();
4929+
assertNull(expression.getValue(rh));
4930+
assertEquals(3L,expression.getValue(rh));
4931+
assertCanCompile(expression);
4932+
rh = new RecordHolder();
4933+
assertNull(expression.getValue(rh));
4934+
assertEquals(3L,expression.getValue(rh));
4935+
4936+
expression = sep.parseExpression("record.get('abc')==null?record.put('abc',expression.someLong?.longValue()):null");
4937+
rh = new RecordHolder();
4938+
rh.expression.someLong=6L;
4939+
assertNull(expression.getValue(rh));
4940+
assertEquals(6L,rh.get("abc"));
4941+
assertNull(expression.getValue(rh));
4942+
assertCanCompile(expression);
4943+
rh = new RecordHolder();
4944+
rh.expression.someLong=6L;
4945+
assertNull(expression.getValue(rh));
4946+
assertEquals(6L,rh.get("abc"));
4947+
assertNull(expression.getValue(rh));
4948+
}
4949+
4950+
public static class RecordHolder {
4951+
public void add(String key, Long value) {
4952+
record.put(key, value);
4953+
}
4954+
public long get(String key) {
4955+
return record.get(key);
4956+
}
4957+
public Map<String,Long> record = new HashMap<>();
4958+
public LongHolder expression = new LongHolder();
4959+
4960+
}
4961+
4962+
public static class LongHolder {
4963+
public Long someLong = 3L;
4964+
}
4965+
49014966
@Test
49024967
public void ternaryOperator_SPR15192() {
49034968
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);

0 commit comments

Comments
 (0)