Fix SpEL compilation for non trivial elvis operand
Issue: SPR-17214
This commit is contained in:
parent
48c660fa41
commit
f87a37fd0d
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
|
@ -79,10 +79,12 @@ public class Elvis extends SpelNodeImpl {
|
|||
public void generateCode(MethodVisitor mv, CodeFlow cf) {
|
||||
// exit type descriptor can be null if both components are literal expressions
|
||||
computeExitTypeDescriptor();
|
||||
cf.enterCompilationScope();
|
||||
this.children[0].generateCode(mv, cf);
|
||||
String lastDesc = cf.lastDescriptor();
|
||||
Assert.state(lastDesc != null, "No last descriptor");
|
||||
CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0));
|
||||
cf.exitCompilationScope();
|
||||
Label elseTarget = new Label();
|
||||
Label endOfIf = new Label();
|
||||
mv.visitInsn(DUP);
|
||||
|
|
@ -95,12 +97,14 @@ public class Elvis extends SpelNodeImpl {
|
|||
mv.visitJumpInsn(IFEQ, endOfIf); // if not empty, drop through to elseTarget
|
||||
mv.visitLabel(elseTarget);
|
||||
mv.visitInsn(POP);
|
||||
cf.enterCompilationScope();
|
||||
this.children[1].generateCode(mv, cf);
|
||||
if (!CodeFlow.isPrimitive(this.exitTypeDescriptor)) {
|
||||
lastDesc = cf.lastDescriptor();
|
||||
Assert.state(lastDesc != null, "No last descriptor");
|
||||
CodeFlow.insertBoxIfNecessary(mv, lastDesc.charAt(0));
|
||||
}
|
||||
cf.exitCompilationScope();
|
||||
mv.visitLabel(endOfIf);
|
||||
cf.pushDescriptor(this.exitTypeDescriptor);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4898,6 +4898,71 @@ public class SpelCompilationCoverageTests extends AbstractExpressionTests {
|
|||
assertIsCompiled(exp);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void elvisOperator_SPR17214() throws Exception {
|
||||
SpelParserConfiguration spc = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
SpelExpressionParser sep = new SpelExpressionParser(spc);
|
||||
|
||||
RecordHolder rh = null;
|
||||
|
||||
expression = sep.parseExpression("record.get('abc')?:record.put('abc',expression.someLong?.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertNull(expression.getValue(rh));
|
||||
assertEquals(3L,expression.getValue(rh));
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertNull(expression.getValue(rh));
|
||||
assertEquals(3L,expression.getValue(rh));
|
||||
|
||||
expression = sep.parseExpression("record.get('abc')?:record.put('abc',3L.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertNull(expression.getValue(rh));
|
||||
assertEquals(3L,expression.getValue(rh));
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertNull(expression.getValue(rh));
|
||||
assertEquals(3L,expression.getValue(rh));
|
||||
|
||||
expression = sep.parseExpression("record.get('abc')?:record.put('abc',3L.longValue())");
|
||||
rh = new RecordHolder();
|
||||
assertNull(expression.getValue(rh));
|
||||
assertEquals(3L,expression.getValue(rh));
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
assertNull(expression.getValue(rh));
|
||||
assertEquals(3L,expression.getValue(rh));
|
||||
|
||||
expression = sep.parseExpression("record.get('abc')==null?record.put('abc',expression.someLong?.longValue()):null");
|
||||
rh = new RecordHolder();
|
||||
rh.expression.someLong=6L;
|
||||
assertNull(expression.getValue(rh));
|
||||
assertEquals(6L,rh.get("abc"));
|
||||
assertNull(expression.getValue(rh));
|
||||
assertCanCompile(expression);
|
||||
rh = new RecordHolder();
|
||||
rh.expression.someLong=6L;
|
||||
assertNull(expression.getValue(rh));
|
||||
assertEquals(6L,rh.get("abc"));
|
||||
assertNull(expression.getValue(rh));
|
||||
}
|
||||
|
||||
public static class RecordHolder {
|
||||
public void add(String key, Long value) {
|
||||
record.put(key, value);
|
||||
}
|
||||
public long get(String key) {
|
||||
return record.get(key);
|
||||
}
|
||||
public Map<String,Long> record = new HashMap<>();
|
||||
public LongHolder expression = new LongHolder();
|
||||
|
||||
}
|
||||
|
||||
public static class LongHolder {
|
||||
public Long someLong = 3L;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ternaryOperator_SPR15192() {
|
||||
SpelParserConfiguration configuration = new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, null);
|
||||
|
|
|
|||
Loading…
Reference in New Issue