You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by he...@apache.org on 2019/03/27 17:53:28 UTC
[commons-jexl] branch master updated: JEXL-295: add unary plus
support and arithmetic positivize method Task #JEXL-295 - Add unary plus
operator
This is an automated email from the ASF dual-hosted git repository.
henrib pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
The following commit(s) were added to refs/heads/master by this push:
new 1f00432 JEXL-295: add unary plus support and arithmetic positivize method Task #JEXL-295 - Add unary plus operator
1f00432 is described below
commit 1f00432517aa46bdf0197e1e85a007f4076c01ed
Author: henrib <he...@apache.org>
AuthorDate: Wed Mar 27 18:52:49 2019 +0100
JEXL-295: add unary plus support and arithmetic positivize method
Task #JEXL-295 - Add unary plus operator
---
.../org/apache/commons/jexl3/JexlArithmetic.java | 31 ++++++++++++++++++++++
.../org/apache/commons/jexl3/JexlOperator.java | 8 ++++++
.../apache/commons/jexl3/internal/Debugger.java | 6 +++++
.../apache/commons/jexl3/internal/Interpreter.java | 23 +++++++++++++++-
.../commons/jexl3/internal/ScriptVisitor.java | 10 +++++--
.../org/apache/commons/jexl3/parser/Parser.jjt | 2 ++
.../apache/commons/jexl3/parser/ParserVisitor.java | 2 ++
.../org/apache/commons/jexl3/ArithmeticTest.java | 28 ++++++++++++++++++-
8 files changed, 106 insertions(+), 4 deletions(-)
diff --git a/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java b/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
index 2e6114e..6078bab 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlArithmetic.java
@@ -827,6 +827,37 @@ public class JexlArithmetic {
}
/**
+ * Absolute (positive) value (unary plus for numbers).
+ *
+ * @param val the value to get the absolute value from
+ * @return the positive value
+ */
+ public Object positivize(Object val) {
+ if (val instanceof Integer) {
+ return Math.abs((Integer) val);
+ } else if (val instanceof Double) {
+ return Math.abs((Double) val);
+ } else if (val instanceof Long) {
+ return Math.abs((Long) val);
+ } else if (val instanceof BigDecimal) {
+ return ((BigDecimal) val).abs();
+ } else if (val instanceof BigInteger) {
+ return ((BigInteger) val).abs();
+ } else if (val instanceof Float) {
+ return Math.abs((Float) val);
+ } else if (val instanceof Short) {
+ return (short) Math.abs((Short) val);
+ } else if (val instanceof Byte) {
+ return (byte) Math.abs((Byte) val);
+ } else if (val instanceof Boolean) {
+ return Boolean.TRUE;
+ } else if (val instanceof AtomicBoolean) {
+ return Boolean.TRUE;
+ }
+ throw new ArithmeticException("Object abs:(" + val + ")");
+ }
+
+ /**
* Test if left contains right (right matches/in left).
* <p>Beware that this method arguments are the opposite of the operator arguments.
* 'x in y' means 'y contains x'.</p>
diff --git a/src/main/java/org/apache/commons/jexl3/JexlOperator.java b/src/main/java/org/apache/commons/jexl3/JexlOperator.java
index 5bc448e..eab309e 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlOperator.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlOperator.java
@@ -191,6 +191,14 @@ public enum JexlOperator {
* @see JexlArithmetic#negate
*/
NEGATE("-", "negate", 1),
+
+ /**
+ * Absolute operator.
+ * <br><strong>Syntax:</strong> <code>+x</code>
+ * <br><strong>Method:</strong> <code>T plus(L x);</code>.
+ * @see JexlArithmetic#positivize
+ */
+ POSITIVIZE("+", "positivize", 1),
/**
* Empty operator.
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
index 6ace488..546447d 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
@@ -100,6 +100,7 @@ import org.apache.commons.jexl3.parser.JexlNode;
import org.apache.commons.jexl3.parser.ParserVisitor;
import java.util.regex.Pattern;
+import org.apache.commons.jexl3.parser.ASTUnaryPlusNode;
import org.apache.commons.jexl3.parser.StringParser;
/**
@@ -993,6 +994,11 @@ public class Debugger extends ParserVisitor implements JexlInfo.Detail {
}
@Override
+ protected Object visit(ASTUnaryPlusNode node, Object data) {
+ return prefixChild(node, "+", data);
+ }
+
+ @Override
protected Object visit(ASTVar node, Object data) {
builder.append("var ");
check(node, node.getName(), data);
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
index f6241b1..aaea4d9 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -113,6 +113,7 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
+import org.apache.commons.jexl3.parser.ASTUnaryPlusNode;
/**
@@ -598,7 +599,27 @@ public class Interpreter extends InterpreterBase {
throw new JexlException(valNode, "- error", xrt);
}
}
-
+
+ @Override
+ protected Object visit(ASTUnaryPlusNode node, Object data) {
+ JexlNode valNode = node.jjtGetChild(0);
+ Object val = valNode.jjtAccept(this, data);
+ try {
+ Object result = operators.tryOverload(node, JexlOperator.POSITIVIZE, val);
+ if (result != JexlEngine.TRY_FAILED) {
+ return result;
+ }
+ Object number = arithmetic.positivize(val);
+ // attempt to recoerce to literal class
+ if (valNode instanceof ASTNumberLiteral && number instanceof Number) {
+ number = arithmetic.narrowNumber((Number) number, ((ASTNumberLiteral) valNode).getLiteralClass());
+ }
+ return number;
+ } catch (ArithmeticException xrt) {
+ throw new JexlException(valNode, "- error", xrt);
+ }
+ }
+
@Override
protected Object visit(ASTBitwiseComplNode node, Object data) {
Object arg = node.jjtGetChild(0).jjtAccept(this, data);
diff --git a/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java b/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
index bfa1a80..ca33ca3 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
@@ -90,6 +90,7 @@ import org.apache.commons.jexl3.parser.ASTSubNode;
import org.apache.commons.jexl3.parser.ASTTernaryNode;
import org.apache.commons.jexl3.parser.ASTTrueNode;
import org.apache.commons.jexl3.parser.ASTUnaryMinusNode;
+import org.apache.commons.jexl3.parser.ASTUnaryPlusNode;
import org.apache.commons.jexl3.parser.ASTVar;
import org.apache.commons.jexl3.parser.ASTWhileStatement;
import org.apache.commons.jexl3.parser.JexlNode;
@@ -288,8 +289,8 @@ public class ScriptVisitor extends ParserVisitor {
@Override
protected Object visit(ASTNEWNode node, Object data) {
-
- return visitNode(node, data); }
+ return visitNode(node, data);
+ }
@Override
protected Object visit(ASTAddNode node, Object data) {
@@ -322,6 +323,11 @@ public class ScriptVisitor extends ParserVisitor {
}
@Override
+ protected Object visit(ASTUnaryPlusNode node, Object data) {
+ return visitNode(node, data);
+ }
+
+ @Override
protected Object visit(ASTBitwiseComplNode node, Object data) {
return visitNode(node, data);
}
diff --git a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
index 3565ba0..0451b72 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
+++ b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
@@ -580,6 +580,8 @@ void UnaryExpression() #void : {}
{
<minus> UnaryExpression() #UnaryMinusNode(1)
|
+ <plus> UnaryExpression() #UnaryPlusNode(1)
+ |
<tilda> UnaryExpression() #BitwiseComplNode(1)
|
<not> UnaryExpression() #NotNode(1)
diff --git a/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java b/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
index c584459..a3d0d59 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
@@ -113,6 +113,8 @@ public abstract class ParserVisitor {
protected abstract Object visit(ASTModNode node, Object data);
protected abstract Object visit(ASTUnaryMinusNode node, Object data);
+
+ protected abstract Object visit(ASTUnaryPlusNode node, Object data);
protected abstract Object visit(ASTBitwiseComplNode node, Object data);
diff --git a/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java b/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java
index f521088..3a50d66 100644
--- a/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java
+++ b/src/test/java/org/apache/commons/jexl3/ArithmeticTest.java
@@ -153,7 +153,33 @@ public class ArithmeticTest extends JexlTestCase {
asserter.assertExpression("-aBigInteger", new BigInteger("-7"));
asserter.assertExpression("-aBigDecimal", new BigDecimal("-8.8"));
}
-
+
+ /**
+ * test some simple mathematical calculations
+ */
+ @Test
+ public void testUnaryPlusus() throws Exception {
+ asserter.setVariable("aByte", new Byte((byte) -1));
+ asserter.setVariable("aShort", new Short((short) -2));
+ asserter.setVariable("anInteger", new Integer(-3));
+ asserter.setVariable("aLong", new Long(-4));
+ asserter.setVariable("aFloat", new Float(-5.5));
+ asserter.setVariable("aDouble", new Double(-6.6));
+ asserter.setVariable("aBigInteger", new BigInteger("-7"));
+ asserter.setVariable("aBigDecimal", new BigDecimal("-8.8"));
+
+ asserter.assertExpression("+3", new Integer("3"));
+ asserter.assertExpression("+3.0", new Double("3.0"));
+ asserter.assertExpression("+aByte", new Byte((byte) 1));
+ asserter.assertExpression("+aShort", new Short((short) 2));
+ asserter.assertExpression("+anInteger", new Integer(3));
+ asserter.assertExpression("+aLong", new Long(4));
+ asserter.assertExpression("+aFloat", new Float(5.5));
+ asserter.assertExpression("+aDouble", new Double(6.6));
+ asserter.assertExpression("+aBigInteger", new BigInteger("7"));
+ asserter.assertExpression("+aBigDecimal", new BigDecimal("8.8"));
+ }
+
/**
* test some simple mathematical calculations
*/