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 2009/09/02 16:14:59 UTC

svn commit: r810514 - in /commons/proper/jexl/branches/2.0/src: main/java/org/apache/commons/jexl/ main/java/org/apache/commons/jexl/parser/ test/java/org/apache/commons/jexl/

Author: henrib
Date: Wed Sep  2 14:14:58 2009
New Revision: 810514

URL: http://svn.apache.org/viewvc?rev=810514&view=rev
Log:
JEXL-87:
Fix in Parser.jjt, "x + y / a + b" was throwing a ParseException
Fixed JexlArithmetic; use the same algo wrt datatype for all operations, fixed modulo for BigDecimal and made integer results to scale down to 'int' (was only to long) when possible
Fixed tests to check for 'int(eger)' instead of 'long' when needed.

Modified:
    commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlArithmetic.java
    commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt
    commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ArithmeticTest.java
    commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ForEachTest.java
    commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/IssuesTest.java
    commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTest.java
    commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ScriptTest.java
    commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/WhileTest.java

Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlArithmetic.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlArithmetic.java?rev=810514&r1=810513&r2=810514&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlArithmetic.java (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/JexlArithmetic.java Wed Sep  2 14:14:58 2009
@@ -70,7 +70,7 @@
      * @return null if strict, else Long(0)
      */
     protected Object controlNullNullOperands() {
-        return strict? null : Long.valueOf(0);
+        return strict? null : Integer.valueOf(0);
     }
 
     /**
@@ -103,6 +103,7 @@
         }
         
         try {
+            // if either are floating point (double or float) use double
             if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
                 double l = toDouble(left);
                 double r = toDouble(right);
@@ -152,27 +153,36 @@
             return controlNullNullOperands();
         }
 
+        // if either are floating point (double or float) use double
+        if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
+            double l = toDouble(left);
+            double r = toDouble(right);
+            if (r == 0.0) {
+                throw new ArithmeticException("/");
+            }
+            return new Double(l / r);
+        }
+
         // if both are bigintegers use that type
         if (left instanceof BigInteger && right instanceof BigInteger) {
             BigInteger l = toBigInteger(left);
             BigInteger r = toBigInteger(right);
             return l.divide(r);
         }
-        
-        // if either are bigdecimal use that type 
+
+        // if either are bigdecimal use that type
         if (left instanceof BigDecimal || right instanceof BigDecimal) {
             BigDecimal l = toBigDecimal(left);
             BigDecimal r = toBigDecimal(right);
-            return l.divide(r, BigDecimal.ROUND_HALF_UP);
-        }
-
-        double l = toDouble(left);
-        double r = toDouble(right);
-        if (r == 0.0) {
-            throw new ArithmeticException("/");
+            BigDecimal d = l.divide(r);
+            return d;
         }
-        return new Double(l / r);
 
+        // otherwise treat as integers
+        BigInteger l = toBigInteger(left);
+        BigInteger r = toBigInteger(right);
+        BigInteger result = l.divide(r);
+        return narrowBigInteger(result);
     }
     
     /**
@@ -194,11 +204,12 @@
             return controlNullNullOperands();
         }
 
+        // if either are floating point (double or float) use double
         if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
             double l = toDouble(left);
             double r = toDouble(right);
             if (r == 0.0) {
-                throw new ArithmeticException("/");
+                throw new ArithmeticException("%");
             }
             return new Double(l % r);
         }
@@ -214,9 +225,7 @@
         if (left instanceof BigDecimal || right instanceof BigDecimal) {
             BigDecimal l = toBigDecimal(left);
             BigDecimal r = toBigDecimal(right);
-            BigInteger intDiv = l.divide(r, BigDecimal.ROUND_HALF_UP).toBigInteger();
-            BigInteger intValue = (r.multiply(new BigDecimal(intDiv))).toBigInteger();
-            BigDecimal remainder = new BigDecimal(l.subtract(new BigDecimal(intValue)).toBigInteger());
+            BigDecimal remainder = l.remainder(r);
             return remainder;
         }
 
@@ -245,7 +254,8 @@
         if (left == null && right == null) {
             return controlNullNullOperands();
         }
-        
+
+        // if either are floating point (double or float) use double
         if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
             double l = toDouble(left);
             double r = toDouble(right);
@@ -291,7 +301,8 @@
         if (left == null && right == null) {
             return controlNullNullOperands();
         }
-        
+
+        // if either are floating point (double or float) use double
         if (isFloatingPointNumber(left) || isFloatingPointNumber(right)) {
             double l = toDouble(left);
             double r = toDouble(right);
@@ -522,7 +533,7 @@
     public long toLong(Object val) {
         if (val == null) {
             controlNullOperand();
-            return 0;
+            return 0L;
         } else if (val instanceof String) {
             if ("".equals(val)) {
                 return 0;
@@ -555,7 +566,7 @@
         } else if (val instanceof String) {
             String string = (String) val;
             if ("".equals(string.trim())) {
-                return BigInteger.valueOf(0);
+                return BigInteger.ZERO;
             }
             return new BigInteger(string);
         } else if (val instanceof Number) {
@@ -581,7 +592,7 @@
             return (BigDecimal) val;
         } else if (val == null) {
             controlNullOperand();
-            return BigDecimal.valueOf(0);
+            return BigDecimal.ZERO;
         } else if (val instanceof String) {
             String string = (String) val;
             if ("".equals(string.trim())) {
@@ -737,11 +748,10 @@
             && bigi.compareTo(BIGI_LONG_MIN_VALUE) >= 0) {
             // coerce to int if possible
             long l = bigi.longValue();
-// TODO: think about coercing to int when possible to avoid method calls to fail
-// once and force a narrow call in the general 'int' case
-//            if (l <= ((long) Integer.MAX_VALUE) && l >= ((long) Integer.MIN_VALUE)) {
-//                return new Integer((int) l);
-//            }
+            // coerce to int when possible (int being so often used in method parms)
+            if (l <= ((long) Integer.MAX_VALUE) && l >= ((long) Integer.MIN_VALUE)) {
+                return new Integer((int) l);
+            }
             return new Long(l);
         }
         return bigi;

Modified: commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt?rev=810514&r1=810513&r2=810514&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt (original)
+++ commons/proper/jexl/branches/2.0/src/main/java/org/apache/commons/jexl/parser/Parser.jjt Wed Sep  2 14:14:58 2009
@@ -193,7 +193,7 @@
     "||" ConditionalAndExpression() #OrNode(2)
   |
     "or" ConditionalAndExpression() #OrNode(2)
-  )?
+  )*
 }
 
 void ConditionalAndExpression() #void :
@@ -204,28 +204,28 @@
     "&&" InclusiveOrExpression() #AndNode(2)
   |
     "and" InclusiveOrExpression() #AndNode(2)
-  )?
+  )*
 }
 
 void InclusiveOrExpression() #void :
 {}
 {
   ExclusiveOrExpression()
-  ( "|" ExclusiveOrExpression() #BitwiseOrNode(2) )?
+  ( "|" ExclusiveOrExpression() #BitwiseOrNode(2) )*
 }
 
 void ExclusiveOrExpression() #void :
 {}
 {
   AndExpression()
-  ( "^" AndExpression() #BitwiseXorNode(2) )?
+  ( "^" AndExpression() #BitwiseXorNode(2) )*
 }
 
 void AndExpression() #void :
 {}
 {
   EqualityExpression()
-  ( "&" EqualityExpression() #BitwiseAndNode(2) )?
+  ( "&" EqualityExpression() #BitwiseAndNode(2) )*
 }
 
 void EqualityExpression() #void :
@@ -295,7 +295,7 @@
     "%" UnaryExpression() #ModNode(2)
    |
     "mod" UnaryExpression() #ModNode(2)
-  )?
+  )*
 }
 
 void UnaryExpression() #void : {}

Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ArithmeticTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ArithmeticTest.java?rev=810514&r1=810513&r2=810514&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ArithmeticTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ArithmeticTest.java Wed Sep  2 14:14:58 2009
@@ -83,18 +83,18 @@
 
         asserter.setVariable("foo", new Integer(2));
 
-        asserter.assertExpression("foo + 2", new Long(4));
-        asserter.assertExpression("3 + 3", new Long(6));
-        asserter.assertExpression("3 + 3 + foo", new Long(8));
-        asserter.assertExpression("3 * 3", new Long(9));
-        asserter.assertExpression("3 * 3 + foo", new Long(11));
-        asserter.assertExpression("3 * 3 - foo", new Long(7));
+        asserter.assertExpression("foo + 2", new Integer(4));
+        asserter.assertExpression("3 + 3", new Integer(6));
+        asserter.assertExpression("3 + 3 + foo", new Integer(8));
+        asserter.assertExpression("3 * 3", new Integer(9));
+        asserter.assertExpression("3 * 3 + foo", new Integer(11));
+        asserter.assertExpression("3 * 3 - foo", new Integer(7));
 
         /*
          * test parenthesized exprs
          */
-        asserter.assertExpression("(4 + 3) * 6", new Long(42));
-        asserter.assertExpression("(8 - 2) * 7", new Long(42));
+        asserter.assertExpression("(4 + 3) * 6", new Integer(42));
+        asserter.assertExpression("(8 - 2) * 7", new Integer(42));
 
         /*
          * test some floaty stuff
@@ -105,19 +105,19 @@
         /*
          * test / and %
          */
-        asserter.assertExpression("6 / 3", new Double(6 / 3));
+        asserter.assertExpression("6 / 3", new Integer(6 / 3));
         asserter.assertExpression("6.4 / 3", new Double(6.4 / 3));
-        asserter.assertExpression("0 / 3", new Double(0 / 3));
+        asserter.assertExpression("0 / 3", new Integer(0 / 3));
         asserter.assertExpression("3 / 0", new Double(0));
-        asserter.assertExpression("4 % 3", new Long(1));
+        asserter.assertExpression("4 % 3", new Integer(1));
         asserter.assertExpression("4.8 % 3", new Double(4.8 % 3));
 
         /*
          * test new null coersion
          */
         asserter.setVariable("imanull", null);
-        asserter.assertExpression("imanull + 2", new Long(2));
-        asserter.assertExpression("imanull + imanull", new Long(0));
+        asserter.assertExpression("imanull + 2", new Integer(2));
+        asserter.assertExpression("imanull + imanull", new Integer(0));
     }
 
     /**

Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ForEachTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ForEachTest.java?rev=810514&r1=810513&r2=810514&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ForEachTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ForEachTest.java Wed Sep  2 14:14:58 2009
@@ -99,8 +99,8 @@
         jc.getVars().put("list", new Object[] {"1", "1"});
         jc.getVars().put("x", new Integer(0));
         Object o = e.evaluate(jc);
-        assertEquals("Result is wrong", new Long(2), o);
-        assertEquals("x is wrong", new Long(2), jc.getVars().get("x"));
+        assertEquals("Result is wrong", new Integer(2), o);
+        assertEquals("x is wrong", new Integer(2), jc.getVars().get("x"));
     }
 
     public void testForEachWithListExpression() throws Exception {

Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/IssuesTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/IssuesTest.java?rev=810514&r1=810513&r2=810514&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/IssuesTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/IssuesTest.java Wed Sep  2 14:14:58 2009
@@ -240,6 +240,26 @@
 
     }
 
+    // JEXL-87
+    public void test87() throws Exception {
+        JexlContext ctxt = JexlHelper.createContext();
+        JexlEngine jexl = new JexlEngine();
+        jexl.setSilent(false);
+        jexl.setLenient(false);
+        Expression divide = jexl.createExpression("l / r");
+        Expression modulo = jexl.createExpression("l % r");
+
+        ctxt.getVars().put("l", java.math.BigInteger.valueOf(7));
+        ctxt.getVars().put("r", java.math.BigInteger.valueOf(2));
+        assertEquals("3", divide.evaluate(ctxt).toString());
+        assertEquals("1", modulo.evaluate(ctxt).toString());
+
+        ctxt.getVars().put("l", java.math.BigDecimal.valueOf(7));
+        ctxt.getVars().put("r", java.math.BigDecimal.valueOf(2));
+        assertEquals("3.5", divide.evaluate(ctxt).toString());
+        assertEquals("1", modulo.evaluate(ctxt).toString());
+    }
+
     // JEXL-90: ';' is necessary between expressions
     public void test90() throws Exception {
         JexlContext ctxt = JexlHelper.createContext();

Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTest.java?rev=810514&r1=810513&r2=810514&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/JexlTest.java Wed Sep  2 14:14:58 2009
@@ -290,8 +290,8 @@
          * test new null coersion
          */
         jc.getVars().put("imanull", null );
-        assertExpression(jc, "imanull + 2", new Long(2));
-        assertExpression(jc, "imanull + imanull", new Long(0));
+        assertExpression(jc, "imanull + 2", new Integer(2));
+        assertExpression(jc, "imanull + imanull", new Integer(0));
         
         /* test for bugzilla 31577 */
         jc.getVars().put("n", new Integer(0));
@@ -691,7 +691,7 @@
      */
     public void testComment() throws Exception
     {
-        assertExpression(JexlHelper.createContext(), "## double or nothing\n 1 + 1", Long.valueOf("2"));
+        assertExpression(JexlHelper.createContext(), "## double or nothing\n 1 + 1", Integer.valueOf("2"));
     }
     
     /**
@@ -709,8 +709,8 @@
         
         assertExpression(jc, "hello = 'world'", "world");
         assertEquals("hello variable not changed", "world", jc.getVars().get("hello"));
-        assertExpression(jc, "result = 1 + 1", new Long(2));
-        assertEquals("result variable not changed", new Long(2), jc.getVars().get("result"));
+        assertExpression(jc, "result = 1 + 1", new Integer(2));
+        assertEquals("result variable not changed", new Integer(2), jc.getVars().get("result"));
         // todo: make sure properties can be assigned to, fall back to flat var if no property
         // assertExpression(jc, "foo.property1 = '99'", "99");
         // assertEquals("property not set", "99", foo.getProperty1());

Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ScriptTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ScriptTest.java?rev=810514&r1=810513&r2=810514&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ScriptTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/ScriptTest.java Wed Sep  2 14:14:58 2009
@@ -58,7 +58,7 @@
         jc.getVars().put("x", new Integer(1));
     
         Object o = s.execute(jc);
-        assertEquals("Result is wrong", new Long(10), o);
+        assertEquals("Result is wrong", new Integer(10), o);
         assertEquals("getText is wrong", code, s.getText());
     }
     
@@ -69,7 +69,7 @@
         jc.getVars().put("out", System.out);
         Object result = s.execute(jc);
         assertNotNull("No result", result);
-        assertEquals("Wrong result", new Long(7), result);
+        assertEquals("Wrong result", new Integer(7), result);
     }
 
     public void testScriptFromURL() throws Exception {
@@ -79,7 +79,7 @@
         jc.getVars().put("out", System.out);
         Object result = s.execute(jc);
         assertNotNull("No result", result);
-        assertEquals("Wrong result", new Long(7), result);
+        assertEquals("Wrong result", new Integer(7), result);
     }
     
     public void testScriptUpdatesContext() throws Exception {

Modified: commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/WhileTest.java
URL: http://svn.apache.org/viewvc/commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/WhileTest.java?rev=810514&r1=810513&r2=810514&view=diff
==============================================================================
--- commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/WhileTest.java (original)
+++ commons/proper/jexl/branches/2.0/src/test/java/org/apache/commons/jexl/WhileTest.java Wed Sep  2 14:14:58 2009
@@ -42,7 +42,7 @@
         jc.getVars().put("x", new Integer(1));
 
         Object o = e.evaluate(jc);
-        assertEquals("Result is wrong", new Long(10), o);
+        assertEquals("Result is wrong", new Integer(10), o);
     }
 
     public void testWhileWithBlock() throws Exception {
@@ -52,8 +52,8 @@
         jc.getVars().put("y", new Integer(1));
 
         Object o = e.evaluate(jc);
-        assertEquals("Result is wrong", new Long(512), o);
-        assertEquals("x is wrong", new Long(10), jc.getVars().get("x"));
-        assertEquals("y is wrong", new Long(512), jc.getVars().get("y"));
+        assertEquals("Result is wrong", new Integer(512), o);
+        assertEquals("x is wrong", new Integer(10), jc.getVars().get("x"));
+        assertEquals("y is wrong", new Integer(512), jc.getVars().get("y"));
     }
 }