Fix compilation of SpEL elvis/ternary expressions
Without this fix the compiled version of elvis actual behaved differently to the interpreted version if the value being queried was an empty string. This is now fixed. It also now correctly handles the query value being a primitive and addresses the findings of SPR-15192 where some type inferencing logic was trying to be too clever, that code has been deleted. Issue: SPR-15192
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -49,6 +49,7 @@ public class Elvis extends SpelNodeImpl {
|
||||
@Override
|
||||
public TypedValue getValueInternal(ExpressionState state) throws EvaluationException {
|
||||
TypedValue value = this.children[0].getValueInternal(state);
|
||||
// If this check is changed, the generateCode method will need changing too
|
||||
if (!StringUtils.isEmpty(value.getValue())) {
|
||||
return value;
|
||||
}
|
||||
@@ -77,11 +78,17 @@ public class Elvis extends SpelNodeImpl {
|
||||
// exit type descriptor can be null if both components are literal expressions
|
||||
computeExitTypeDescriptor();
|
||||
this.children[0].generateCode(mv, cf);
|
||||
CodeFlow.insertBoxIfNecessary(mv, cf.lastDescriptor().charAt(0));
|
||||
Label elseTarget = new Label();
|
||||
Label endOfIf = new Label();
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitJumpInsn(IFNULL, elseTarget);
|
||||
mv.visitJumpInsn(GOTO, endOfIf);
|
||||
// Also check if empty string, as per the code in the interpreted version
|
||||
mv.visitInsn(DUP);
|
||||
mv.visitLdcInsn("");
|
||||
mv.visitInsn(SWAP);
|
||||
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z",false);
|
||||
mv.visitJumpInsn(IFEQ, endOfIf); // If not empty, drop through to elseTarget
|
||||
mv.visitLabel(elseTarget);
|
||||
mv.visitInsn(POP);
|
||||
this.children[1].generateCode(mv, cf);
|
||||
@@ -100,12 +107,6 @@ public class Elvis extends SpelNodeImpl {
|
||||
if (conditionDescriptor.equals(ifNullValueDescriptor)) {
|
||||
this.exitTypeDescriptor = conditionDescriptor;
|
||||
}
|
||||
else if (conditionDescriptor.equals("Ljava/lang/Object") && !CodeFlow.isPrimitive(ifNullValueDescriptor)) {
|
||||
this.exitTypeDescriptor = ifNullValueDescriptor;
|
||||
}
|
||||
else if (ifNullValueDescriptor.equals("Ljava/lang/Object") && !CodeFlow.isPrimitive(conditionDescriptor)) {
|
||||
this.exitTypeDescriptor = conditionDescriptor;
|
||||
}
|
||||
else {
|
||||
// Use the easiest to compute common super type
|
||||
this.exitTypeDescriptor = "Ljava/lang/Object";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2014 the original author or authors.
|
||||
* Copyright 2002-2016 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.
|
||||
@@ -71,12 +71,6 @@ public class Ternary extends SpelNodeImpl {
|
||||
if (leftDescriptor.equals(rightDescriptor)) {
|
||||
this.exitTypeDescriptor = leftDescriptor;
|
||||
}
|
||||
else if (leftDescriptor.equals("Ljava/lang/Object") && !CodeFlow.isPrimitive(rightDescriptor)) {
|
||||
this.exitTypeDescriptor = rightDescriptor;
|
||||
}
|
||||
else if (rightDescriptor.equals("Ljava/lang/Object") && !CodeFlow.isPrimitive(leftDescriptor)) {
|
||||
this.exitTypeDescriptor = leftDescriptor;
|
||||
}
|
||||
else {
|
||||
// Use the easiest to compute common super type
|
||||
this.exitTypeDescriptor = "Ljava/lang/Object";
|
||||
|
||||
Reference in New Issue
Block a user