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 2018/09/13 16:26:30 UTC

[commons-jexl] branch master updated (ce22c98 -> 02f4e33)

This is an automated email from the ASF dual-hosted git repository.

henrib pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/commons-jexl.git.


    from ce22c98  JEXL-175: changes & release notes
     new 65ce82f  Introduce do/while loop syntax
     new 8aa5ca9  Merge branch 'experimental-do-while' of https://github.com/dmitri-blinov/commons-jexl
     new 4c17fb2  JEXL: more tests on do...while loops
     new 02f4e33  JEXL-273: changes & release notes

The 4 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 RELEASE-NOTES.txt                                  |  1 +
 .../apache/commons/jexl3/internal/Debugger.java    | 16 ++++++++++
 .../apache/commons/jexl3/internal/Interpreter.java | 23 ++++++++++++++
 .../commons/jexl3/internal/ScriptVisitor.java      |  6 ++++
 .../commons/jexl3/parser/FeatureController.java    |  8 +++++
 .../org/apache/commons/jexl3/parser/Parser.jjt     |  8 ++++-
 .../apache/commons/jexl3/parser/ParserVisitor.java |  2 ++
 src/site/xdoc/changes.xml                          |  3 ++
 src/site/xdoc/reference/syntax.xml                 | 15 +++++++--
 .../jexl3/{WhileTest.java => DoWhileTest.java}     | 37 ++++++++++++++++------
 10 files changed, 105 insertions(+), 14 deletions(-)
 copy src/test/java/org/apache/commons/jexl3/{WhileTest.java => DoWhileTest.java} (64%)


[commons-jexl] 04/04: JEXL-273: changes & release notes

Posted by he...@apache.org.
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

commit 02f4e3355f9c55725c6de59c961985e50935082e
Author: henrib <he...@apache.org>
AuthorDate: Thu Sep 13 18:25:24 2018 +0200

    JEXL-273: changes & release notes
---
 RELEASE-NOTES.txt         | 1 +
 src/site/xdoc/changes.xml | 3 +++
 2 files changed, 4 insertions(+)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 18ff94f..4d049d8 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -39,6 +39,7 @@ What's new in 3.2:
 New Features in 3.2:
 ====================
 
+* JEXL-273:      Add do...while(...) loops
 * JEXL-264:      Allow space, quote & double-quote in identifiers
 * JEXL-260:      Automatically inject JexlContext in constructor call when possible
 * JEXL-252:      Allow for interpolated strings to be used in property access operators
diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml
index 5994b12..61baaf0 100644
--- a/src/site/xdoc/changes.xml
+++ b/src/site/xdoc/changes.xml
@@ -26,6 +26,9 @@
     </properties>
     <body>
         <release version="3.2" date="unreleased">
+            <action dev="Dmitri Blinov" type="add" issue="JEXL-175" due-to="Dmitri Blinov">
+                 Add do...while(...) loops
+            </action>
             <action dev="henrib" type="fix" issue="JEXL-272">
                 Dereferencing null property not reported on method call
             </action>


[commons-jexl] 03/04: JEXL: more tests on do...while loops

Posted by he...@apache.org.
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

commit 4c17fb2790a2837ab2e2d49b3860c2700ff5609f
Author: henrib <he...@apache.org>
AuthorDate: Thu Sep 13 18:05:37 2018 +0200

    JEXL: more tests on do...while loops
---
 .../java/org/apache/commons/jexl3/DoWhileTest.java | 35 ++++++++++++----------
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/src/test/java/org/apache/commons/jexl3/DoWhileTest.java b/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
index a01e851..b712821 100644
--- a/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
+++ b/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
@@ -20,8 +20,8 @@ import org.junit.Assert;
 import org.junit.Test;
 
 /**
- * Tests for while statement.
- * @since 1.1
+ * Tests do while statement.
+ * @since 3.2
  */
 @SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
 public class DoWhileTest extends JexlTestCase {
@@ -37,16 +37,32 @@ public class DoWhileTest extends JexlTestCase {
 
         Object o = e.execute(jc);
         Assert.assertNull("Result is not null", o);
+        e = JEXL.createScript("do {} while (false); 23");
+        o = e.execute(jc);
+        Assert.assertEquals(23, o);
+        
     }
 
     @Test
     public void testWhileExecutesExpressionWhenLooping() throws Exception {
         JexlScript e = JEXL.createScript("do x = x + 1 while (x < 10)");
         JexlContext jc = new MapContext();
-        jc.set("x", new Integer(1));
+        jc.set("x", 1);
 
         Object o = e.execute(jc);
-        Assert.assertEquals("Result is wrong", new Integer(10), o);
+        Assert.assertEquals(10, o);
+        Assert.assertEquals(10, jc.get("x"));
+        
+        e = JEXL.createScript("var x = 0; do x += 1; while (x < 23)");
+        o = e.execute(jc);
+        Assert.assertEquals(23, o);
+        
+        
+        jc.set("x", 1);
+        e = JEXL.createScript("do x += 1; while (x < 23); return 42;");
+        o = e.execute(jc);
+        Assert.assertEquals(23, jc.get("x"));
+        Assert.assertEquals(42, o);
     }
 
     @Test
@@ -62,15 +78,4 @@ public class DoWhileTest extends JexlTestCase {
         Assert.assertEquals("y is wrong", new Integer(512), jc.get("y"));
     }
 
-    @Test
-    public void testWhileRemoveBroken() throws Exception {
-        try {
-            JexlScript e = JEXL.createScript("do remove while (x < 10)");
-            Assert.fail("remove is out of loop!");
-        } catch (JexlException.Parsing xparse) {
-            String str = xparse.detailedMessage();
-            Assert.assertTrue(str.contains("remove"));
-        }
-    }
-
 }


[commons-jexl] 02/04: Merge branch 'experimental-do-while' of https://github.com/dmitri-blinov/commons-jexl

Posted by he...@apache.org.
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

commit 8aa5ca9e4ac117067417d4e66e2210e9d94a93f7
Merge: ce22c98 65ce82f
Author: henrib <he...@apache.org>
AuthorDate: Thu Sep 13 17:45:07 2018 +0200

    Merge branch 'experimental-do-while' of https://github.com/dmitri-blinov/commons-jexl

 .../apache/commons/jexl3/internal/Debugger.java    | 16 +++++
 .../apache/commons/jexl3/internal/Interpreter.java | 23 +++++++
 .../commons/jexl3/internal/ScriptVisitor.java      |  6 ++
 .../commons/jexl3/parser/FeatureController.java    |  8 +++
 .../org/apache/commons/jexl3/parser/Parser.jjt     |  8 ++-
 .../apache/commons/jexl3/parser/ParserVisitor.java |  2 +
 src/site/xdoc/reference/syntax.xml                 | 15 ++++-
 .../java/org/apache/commons/jexl3/DoWhileTest.java | 76 ++++++++++++++++++++++
 8 files changed, 150 insertions(+), 4 deletions(-)



[commons-jexl] 01/04: Introduce do/while loop syntax

Posted by he...@apache.org.
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

commit 65ce82f5ab9779b149f9ee453c80744ca13605a0
Author: Dmitri Blinov <dm...@mail.ru>
AuthorDate: Mon Aug 20 11:55:20 2018 +0300

    Introduce do/while loop syntax
---
 .../apache/commons/jexl3/internal/Debugger.java    | 16 +++++
 .../apache/commons/jexl3/internal/Interpreter.java | 23 +++++++
 .../commons/jexl3/internal/ScriptVisitor.java      |  6 ++
 .../commons/jexl3/parser/FeatureController.java    |  8 +++
 .../org/apache/commons/jexl3/parser/Parser.jjt     |  8 ++-
 .../apache/commons/jexl3/parser/ParserVisitor.java |  2 +
 src/site/xdoc/reference/syntax.xml                 | 15 ++++-
 .../java/org/apache/commons/jexl3/DoWhileTest.java | 76 ++++++++++++++++++++++
 8 files changed, 150 insertions(+), 4 deletions(-)

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 db75d81..3126647 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java
@@ -35,6 +35,7 @@ import org.apache.commons.jexl3.parser.ASTBreak;
 import org.apache.commons.jexl3.parser.ASTConstructorNode;
 import org.apache.commons.jexl3.parser.ASTContinue;
 import org.apache.commons.jexl3.parser.ASTDivNode;
+import org.apache.commons.jexl3.parser.ASTDoWhileStatement;
 import org.apache.commons.jexl3.parser.ASTEQNode;
 import org.apache.commons.jexl3.parser.ASTERNode;
 import org.apache.commons.jexl3.parser.ASTEWNode;
@@ -282,6 +283,7 @@ public class Debugger extends ParserVisitor implements JexlInfo.Detail {
             || child instanceof ASTIfStatement
             || child instanceof ASTForeachStatement
             || child instanceof ASTWhileStatement
+            || child instanceof ASTDoWhileStatement
             || child instanceof ASTAnnotation)) {
             builder.append(';');
             if (indent > 0) {
@@ -961,6 +963,20 @@ public class Debugger extends ParserVisitor implements JexlInfo.Detail {
     }
 
     @Override
+    protected Object visit(ASTDoWhileStatement node, Object data) {
+        builder.append("do ");
+
+        acceptStatement(node.jjtGetChild(0), data);
+
+        builder.append(" while (");
+
+        accept(node.jjtGetChild(1), data);
+
+        builder.append(")");
+        return data;
+    }
+
+    @Override
     protected Object visit(ASTSetAddNode node, Object data) {
         return infixChildren(node, " += ", false, 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 0ff4796..067405c 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -47,6 +47,7 @@ import org.apache.commons.jexl3.parser.ASTBreak;
 import org.apache.commons.jexl3.parser.ASTConstructorNode;
 import org.apache.commons.jexl3.parser.ASTContinue;
 import org.apache.commons.jexl3.parser.ASTDivNode;
+import org.apache.commons.jexl3.parser.ASTDoWhileStatement;
 import org.apache.commons.jexl3.parser.ASTEQNode;
 import org.apache.commons.jexl3.parser.ASTERNode;
 import org.apache.commons.jexl3.parser.ASTEWNode;
@@ -706,6 +707,28 @@ public class Interpreter extends InterpreterBase {
     }
 
     @Override
+    protected Object visit(ASTDoWhileStatement node, Object data) {
+        Object result = null;
+        /* last objectNode is the expression */
+        Node expressionNode = node.jjtGetChild(1);
+        do {
+            cancelCheck(node);
+
+            try {
+                // execute statement
+                result = node.jjtGetChild(0).jjtAccept(this, data);
+            } catch (JexlException.Break stmtBreak) {
+                break;
+            } catch (JexlException.Continue stmtContinue) {
+                //continue;
+            }
+
+        } while (arithmetic.toBoolean(expressionNode.jjtAccept(this, data)));
+
+        return result;
+    }
+
+    @Override
     protected Object visit(ASTAndNode node, Object data) {
         /**
          * The pattern for exception mgmt is to let the child*.jjtAccept out of the try/catch loop so that if one fails,
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 8f72800..2d1e7ca 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/ScriptVisitor.java
@@ -35,6 +35,7 @@ import org.apache.commons.jexl3.parser.ASTBreak;
 import org.apache.commons.jexl3.parser.ASTConstructorNode;
 import org.apache.commons.jexl3.parser.ASTContinue;
 import org.apache.commons.jexl3.parser.ASTDivNode;
+import org.apache.commons.jexl3.parser.ASTDoWhileStatement;
 import org.apache.commons.jexl3.parser.ASTEQNode;
 import org.apache.commons.jexl3.parser.ASTERNode;
 import org.apache.commons.jexl3.parser.ASTEWNode;
@@ -155,6 +156,11 @@ public class ScriptVisitor extends ParserVisitor {
     }
 
     @Override
+    protected Object visit(ASTDoWhileStatement node, Object data) {
+        return visitNode(node, data);
+    }
+
+    @Override
     protected Object visit(ASTContinue node, Object data) {
         return visitNode(node, data);
     }
diff --git a/src/main/java/org/apache/commons/jexl3/parser/FeatureController.java b/src/main/java/org/apache/commons/jexl3/parser/FeatureController.java
index 92d0e72..e40192d 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/FeatureController.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/FeatureController.java
@@ -112,6 +112,14 @@ public class FeatureController extends ScriptVisitor {
     }
 
     @Override
+    protected Object visit(ASTDoWhileStatement node, Object data) {
+        if (!features.supportsLoops()) {
+            throwFeatureException(JexlFeatures.LOOP, node);
+        }
+        return data;
+    }
+
+    @Override
     protected Object visit(ASTForeachStatement node, Object data) {
         if (!features.supportsLoops()) {
             throwFeatureException(JexlFeatures.LOOP, node);
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 6bcaae4..d63911b 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
+++ b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt
@@ -121,6 +121,7 @@ TOKEN_MGR_DECLS : {
     | < ELSE : "else" >
     | < FOR : "for" >
     | < WHILE : "while" >
+    | < DO : "do" >
     | < NEW : "new" >
     | < VAR : "var" >
     | < EMPTY : "empty" > { popDot(); } /* Revert state to default if was DOT_ID. */
@@ -311,6 +312,7 @@ void Statement() #void : {}
     | IfStatement()
     | ForeachStatement()
     | WhileStatement()
+    | DoWhileStatement()
     | ExpressionStatement()
     | ReturnStatement()
     | Continue()
@@ -338,12 +340,16 @@ void IfStatement() : {}
     ( LOOKAHEAD(1) <ELSE>  (LOOKAHEAD(1) Block() | Statement()) )?
 }
 
-
 void WhileStatement() : {}
 {
     <WHILE> <LPAREN> Expression() <RPAREN>  { loopCount += 1; }  (LOOKAHEAD(1) Block() | Statement()) { loopCount -= 1; }
 }
 
+void DoWhileStatement() : {}
+{
+    <DO> { loopCount += 1; } (LOOKAHEAD(1) Block() | Statement()) <WHILE> <LPAREN> Expression() <RPAREN> { loopCount -= 1; }
+}
+
 void ReturnStatement() : {}
 {
     <RETURN> ExpressionStatement()
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 0304738..e749226 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/ParserVisitor.java
@@ -48,6 +48,8 @@ public abstract class ParserVisitor {
 
     protected abstract Object visit(ASTWhileStatement node, Object data);
 
+    protected abstract Object visit(ASTDoWhileStatement node, Object data);
+
     protected abstract Object visit(ASTContinue node, Object data);
 
     protected abstract Object visit(ASTBreak node, Object data);
diff --git a/src/site/xdoc/reference/syntax.xml b/src/site/xdoc/reference/syntax.xml
index e0ac82d..3909a86 100644
--- a/src/site/xdoc/reference/syntax.xml
+++ b/src/site/xdoc/reference/syntax.xml
@@ -94,7 +94,7 @@
                         </p>
                         <p>
                             <strong>N.B.</strong> the following keywords are reserved, and cannot be used as a variable name or property when using the dot operator:
-                            <code>or and eq ne lt gt le ge div mod not null true false new var break continue return</code>
+                            <code>or and eq ne lt gt le ge div mod not null true false new do while var break continue return</code>
                             For example, the following is invalid:
                             <code>my.new.dotted.var // invalid ('new' is keyword)</code>
                             In such cases, quoted identifiers or the [ ] operator can be used, for example:
@@ -902,15 +902,24 @@
                     </td>
                 </tr>
                 <tr>
+                    <td>do/while</td>
+                    <td>
+                        Loop until a condition is satisfied, e.g.
+                        <code>do {
+                            x = x + 2;
+                            } while (x lt 10)</code>
+                    </td>
+                </tr>
+                <tr>
                     <td>continue</td>
                     <td>
-                        Within loops (while/for), allows to skip to the next iteration.
+                        Within loops (do/while/for), allows to skip to the next iteration.
                     </td>
                 </tr>
                 <tr>
                     <td>break</td>
                     <td>
-                        Allows to break from a loop (while/for) inconditionally.
+                        Allows to break from a loop (do/while/for) unconditionally.
                     </td>
                 </tr>
             </table>
diff --git a/src/test/java/org/apache/commons/jexl3/DoWhileTest.java b/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
new file mode 100644
index 0000000..a01e851
--- /dev/null
+++ b/src/test/java/org/apache/commons/jexl3/DoWhileTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.jexl3;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests for while statement.
+ * @since 1.1
+ */
+@SuppressWarnings({"UnnecessaryBoxing", "AssertEqualsBetweenInconvertibleTypes"})
+public class DoWhileTest extends JexlTestCase {
+
+    public DoWhileTest() {
+        super("DoWhileTest");
+    }
+
+    @Test
+    public void testSimpleWhileFalse() throws Exception {
+        JexlScript e = JEXL.createScript("do {} while (false)");
+        JexlContext jc = new MapContext();
+
+        Object o = e.execute(jc);
+        Assert.assertNull("Result is not null", o);
+    }
+
+    @Test
+    public void testWhileExecutesExpressionWhenLooping() throws Exception {
+        JexlScript e = JEXL.createScript("do x = x + 1 while (x < 10)");
+        JexlContext jc = new MapContext();
+        jc.set("x", new Integer(1));
+
+        Object o = e.execute(jc);
+        Assert.assertEquals("Result is wrong", new Integer(10), o);
+    }
+
+    @Test
+    public void testWhileWithBlock() throws Exception {
+        JexlScript e = JEXL.createScript("do { x = x + 1; y = y * 2; } while (x < 10)");
+        JexlContext jc = new MapContext();
+        jc.set("x", new Integer(1));
+        jc.set("y", new Integer(1));
+
+        Object o = e.execute(jc);
+        Assert.assertEquals("Result is wrong", new Integer(512), o);
+        Assert.assertEquals("x is wrong", new Integer(10), jc.get("x"));
+        Assert.assertEquals("y is wrong", new Integer(512), jc.get("y"));
+    }
+
+    @Test
+    public void testWhileRemoveBroken() throws Exception {
+        try {
+            JexlScript e = JEXL.createScript("do remove while (x < 10)");
+            Assert.fail("remove is out of loop!");
+        } catch (JexlException.Parsing xparse) {
+            String str = xparse.detailedMessage();
+            Assert.assertTrue(str.contains("remove"));
+        }
+    }
+
+}