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 d7d55e3d JEXL: getting ready for 3.3;
d7d55e3d is described below

commit d7d55e3dce7cec682fa00ef4afe18e35f47e60c3
Author: henrib <hen...@apache.org>
AuthorDate: Sat Mar 4 15:38:20 2023 +0100

    JEXL: getting ready for 3.3;
---
 .../java/org/apache/commons/jexl3/JexlOptions.java |  2 +-
 .../org/apache/commons/jexl3/internal/Engine.java  | 23 +++--
 .../apache/commons/jexl3/internal/Interpreter.java | 10 +--
 .../commons/jexl3/internal/InterpreterBase.java    | 10 ++-
 .../internal/introspection/PermissionsParser.java  |  2 +-
 .../org/apache/commons/jexl3/package-info.java     | 99 +---------------------
 .../org/apache/commons/jexl3/parser/JexlNode.java  |  3 +-
 .../apache/commons/jexl3/parser/JexlParser.java    |  9 +-
 src/site/xdoc/reference/examples.xml               |  2 +-
 src/site/xdoc/reference/syntax.xml                 |  9 +-
 .../java/org/apache/commons/jexl3/LexicalTest.java |  2 +-
 11 files changed, 46 insertions(+), 125 deletions(-)

diff --git a/src/main/java/org/apache/commons/jexl3/JexlOptions.java 
b/src/main/java/org/apache/commons/jexl3/JexlOptions.java
index 2f85b5c1..ac24a672 100644
--- a/src/main/java/org/apache/commons/jexl3/JexlOptions.java
+++ b/src/main/java/org/apache/commons/jexl3/JexlOptions.java
@@ -213,7 +213,7 @@ public final class JexlOptions {
      * <p>After a symbol is defined as local, dereferencing it outside its
      * scope will trigger an error instead of seeking a global variable of the
      * same name. To further reduce potential naming ambiguity errors,
-     * global variables (ie non local) must be declared to be assigned (@link 
JexlContext#has(String) )
+     * global variables (ie non-local) must be declared to be assigned (@link 
JexlContext#has(String) )
      * when this flag is on; attempting to set an undeclared global variables 
will
      * raise an error.
      * @return true if lexical shading is applied, false otherwise
diff --git a/src/main/java/org/apache/commons/jexl3/internal/Engine.java 
b/src/main/java/org/apache/commons/jexl3/internal/Engine.java
index 81b3e2ce..ff228295 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Engine.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Engine.java
@@ -215,7 +215,8 @@ public class Engine extends JexlEngine {
         options.setMathContext(arithmetic.getMathContext());
         options.setMathScale(arithmetic.getMathScale());
         options.setStrictArithmetic(arithmetic.isStrict());
-        this.functions = conf.namespaces() == null ? Collections.emptyMap() : 
conf.namespaces();
+        final Map<String, Object> ns = conf.namespaces();
+        this.functions = ns == null || ns.isEmpty()? Collections.emptyMap() : 
ns; // should we make a copy?
         this.classNameSolver = new FqcnResolver(uberspect, conf.imports());
         // parsing & features:
         final JexlFeatures features = conf.features() == null? 
DEFAULT_FEATURES : conf.features();
@@ -333,6 +334,15 @@ public class Engine extends JexlEngine {
         return charset;
     }
 
+    /**
+     * Solves a namespace using this engine map of functions.
+     * @param name the namespoce name
+     * @return the object associated
+     */
+    final Object getNamespace(String name) {
+        return functions.get(name);
+    }
+
     /**
      * Solves an optional option.
      * @param conf the option as configured, may be null
@@ -446,16 +456,17 @@ public class Engine extends JexlEngine {
                     }
                 } else if (key.startsWith(PRAGMA_JEXLNS)) {
                     if (ns == null)  {
-                        ns = new LinkedHashMap<>(functions);
+                        ns = new LinkedHashMap<>();
                     }
                     processPragmaNamespace(ns, key, value);
                 } else if (key.startsWith(PRAGMA_MODULE)) {
                     if (ns == null)  {
-                        ns = new LinkedHashMap<>(functions);
+                        ns = new LinkedHashMap<>();
                     }
                     processModulePragma(ns, key, value, script.jexlInfo(), 
context);
                 }
                 if (processor != null) {
+                    opts.setNamespaces(ns);
                     processor.processPragma(opts, key, value);
                 }
             }
@@ -466,14 +477,14 @@ public class Engine extends JexlEngine {
     /**
      * Utility to deal with single value or set of values.
      * @param value the value or the set
-     * @param vfunc the consumer of values
+     * @param consumer the consumer of values
      */
-    private void withValueSet(Object value, Consumer<Object> vfunc) {
+    private void withValueSet(Object value, Consumer<Object> consumer) {
         final Set<?> values = value instanceof Set<?>
                 ? (Set<?>) value
                 : Collections.singleton(value);
         for (final Object o : values) {
-            vfunc.accept(o);
+            consumer.accept(o);
         }
     }
 
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 3487c373..d243a816 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -667,7 +667,7 @@ public class Interpreter extends InterpreterBase {
             /* last child node is the statement to execute */
             final int numChildren = node.jjtGetNumChildren();
             final JexlNode statement = numChildren >= 3 ? 
node.jjtGetChild(numChildren - 1) : null;
-            // get an iterator for the collection/array etc via the 
introspector.
+            // get an iterator for the collection/array/etc. via the 
introspector.
             forEach = operators.tryOverload(node, JexlOperator.FOR_EACH, 
iterableValue);
             final Iterator<?> itemsIterator = forEach instanceof Iterator
                     ? (Iterator<?>) forEach
@@ -1395,7 +1395,7 @@ public class Interpreter extends InterpreterBase {
     }
 
     /**
-     * Executes an assignment with an optional side-effect operator.
+     * Executes an assignment with an optional side effect operator.
      * @param node     the node
      * @param assignop the assignment operator or null if simply assignment
      * @param data     the data
@@ -1529,7 +1529,7 @@ public class Interpreter extends InterpreterBase {
                 : null;
         final Object property;
         if (propertyId != null) {
-            // deal with creating/assignining antish variable
+            // deal with creating/assigning antish variable
             if (antish && ant != null && object == null && 
!propertyId.isSafe() && !propertyId.isExpression()) {
                 ant.append('.');
                 ant.append(propertyId.getName());
@@ -1537,7 +1537,7 @@ public class Interpreter extends InterpreterBase {
                 if (assignop == null) {
                     setContextVariable(propertyNode, name, right);
                 } else {
-                    final Object self = actual = context.get(ant.toString());
+                    final Object self = context.get(ant.toString());
                     final JexlNode pnode = propertyNode;
                     final Consumer<Object> assign = r -> 
setContextVariable(pnode, name, r);
                     actual = operators.tryAssignOverload(node, assignop, 
assign, self, right);
@@ -1606,7 +1606,7 @@ public class Interpreter extends InterpreterBase {
     /**
      * Execute a method call, ie syntactically written as name.call(...).
      * @param node the actual method call node
-     * @param antish non null when name.call is an antish variable
+     * @param antish non-null when name.call is an antish variable
      * @param data the context
      * @return the method call result
      */
diff --git 
a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java 
b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
index 69f479c0..2c3deb4d 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
@@ -81,7 +81,7 @@ public abstract class InterpreterBase extends ParserVisitor {
     protected final Operators operators;
     /** The map of 'prefix:function' to object resolving as namespaces. */
     protected final Map<String, Object> functions;
-    /** The map of dynamically creates namespaces, NamespaceFunctor or 
duck-types of those. */
+    /** The map of dynamically created namespaces, NamespaceFunctor or 
duck-types of those. */
     protected Map<String, Object> functors;
 
     /**
@@ -114,8 +114,7 @@ public abstract class InterpreterBase extends ParserVisitor 
{
             acancel = ((JexlContext.CancellationHandle) 
context).getCancellation();
         }
         this.cancelled = acancel != null? acancel : new AtomicBoolean(false);
-        final Map<String,Object> ons = options.getNamespaces();
-        this.functions = ons.isEmpty()? jexl.functions : ons;
+        this.functions = options.getNamespaces();
         this.functors = null;
         this.operators = new Operators(this);
         // the import package facility
@@ -176,7 +175,7 @@ public abstract class InterpreterBase extends ParserVisitor 
{
      * Resolves a namespace, eventually allocating an instance using context 
as constructor argument.
      * <p>
      * The lifetime of such instances span the current expression or script 
evaluation.</p>
-     * @param prefix the prefix name (may be null for global namespace)
+     * @param prefix the prefix name (can be null for global namespace)
      * @param node   the AST node
      * @return the namespace instance
      */
@@ -195,6 +194,9 @@ public abstract class InterpreterBase extends ParserVisitor 
{
         namespace = ns.resolveNamespace(prefix);
         if (namespace == null) {
             namespace = functions.get(prefix);
+            if (namespace == null) {
+                namespace = jexl.getNamespace(prefix);
+            }
             if (prefix != null && namespace == null) {
                 throw new JexlException(node, "no such function namespace " + 
prefix, null);
             }
diff --git 
a/src/main/java/org/apache/commons/jexl3/internal/introspection/PermissionsParser.java
 
b/src/main/java/org/apache/commons/jexl3/internal/introspection/PermissionsParser.java
index ad6ec0c1..d5084c9d 100644
--- 
a/src/main/java/org/apache/commons/jexl3/internal/introspection/PermissionsParser.java
+++ 
b/src/main/java/org/apache/commons/jexl3/internal/introspection/PermissionsParser.java
@@ -85,7 +85,7 @@ public class PermissionsParser {
      * @param srcs the sources
      * @return the permissions map
      */
-    Permissions parse(Set<String> wildcards, Map<String, 
Permissions.NoJexlPackage> packages, final String... srcs) {
+    synchronized Permissions parse(Set<String> wildcards, Map<String, 
Permissions.NoJexlPackage> packages, final String... srcs) {
         if (srcs == null || srcs.length == 0) {
             return Permissions.UNRESTRICTED;
         }
diff --git a/src/main/java/org/apache/commons/jexl3/package-info.java 
b/src/main/java/org/apache/commons/jexl3/package-info.java
index a84514ba..27acf230 100644
--- a/src/main/java/org/apache/commons/jexl3/package-info.java
+++ b/src/main/java/org/apache/commons/jexl3/package-info.java
@@ -348,105 +348,8 @@
  * For example, this would be the case if you wanted '+' to operate on arrays; 
you'd need to derive
  * JexlArithmetic and implement 'public Object add(Set&lt;?;&gt; x, 
Set&lt;?;&gt; y)' method.
  * Note however that you can <em>not</em> change the operator precedence.
- * The list of operator / method matches is the following:
+ * The list of operator / method matches is described in {@link 
org.apache.commons.jexl3.JexlOperator}:
  * </p>
- * <table><caption>Operators</caption>
- * <tr>
- * <th>Operator</th>
- * <th>Method Name</th>
- * <th>Example</th>
- * </tr>
- * <tr>
- * <td>+</td>
- * <td>add</td>
- * <td>add(x, y)</td>
- * </tr>
- * <tr>
- * <td>-</td>
- * <td>subtract</td>
- * <td>subtract(x, y)</td>
- * </tr>
- * <tr>
- * <td>*</td>
- * <td>multiply</td>
- * <td>multiply(x, y)</td>
- * </tr>
- * <tr>
- * <td>/</td>
- * <td>divide</td>
- * <td>divide(x, y)</td>
- * </tr>
- * <tr>
- * <td>%</td>
- * <td>mod</td>
- * <td>mod(x, y)</td>
- * </tr>
- * <tr>
- * <td>&amp;</td>
- * <td>bitwiseAnd</td>
- * <td>bitwiseAnd(x, y)</td>
- * </tr>
- * <tr>
- * <td>|</td>
- * <td>bitwiseOr</td>
- * <td>bitwiseOr(x, y)</td>
- * </tr>
- * <tr>
- * <td>^</td>
- * <td>bitwiseXor</td>
- * <td>bitwiseXor(x, y)</td>
- * </tr>
- * <tr>
- * <td>!</td>
- * <td>logicalNot</td>
- * <td>logicalNot(x)</td>
- * </tr>
- * <tr>
- * <td>-</td>
- * <td>bitwiseComplement</td>
- * <td>bitiwiseComplement(x)</td>
- * </tr>
- * <tr>
- * <td>==</td>
- * <td>equals</td>
- * <td>equals(x, y)</td>
- * </tr>
- * <tr>
- * <td>&lt;</td>
- * <td>lessThan</td>
- * <td>lessThan(x, y)</td>
- * </tr>
- * <tr>
- * <td>&lt;=</td>
- * <td>lessThanOrEqual</td>
- * <td>lessThanOrEqual(x, y)</td>
- * </tr>
- * <tr>
- * <td>&gt;</td>
- * <td>greaterThan</td>
- * <td>greaterThan(x, y)</td>
- * </tr>
- * <tr>
- * <td>&gt;=</td>
- * <td>greaterThanOrEqual</td>
- * <td>greaterThanOrEqual(x, y)</td>
- * </tr>
- * <tr>
- * <td>-</td>
- * <td>negate</td>
- * <td>negate(x)</td>
- * </tr>
- * <tr>
- * <td>size</td>
- * <td>size</td>
- * <td>size(x)</td>
- * </tr>
- * <tr>
- * <td>empty</td>
- * <td>empty</td>
- * <td>empty(x)</td>
- * </tr>
- * </table>
  * <p>
  * You can also add methods to overload property getters and setters operators 
behaviors.
  * Public methods of the JexlArithmetic instance named 
propertyGet/propertySet/arrayGet/arraySet are potential
diff --git a/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java 
b/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
index 9a00abd4..fe0dbb0a 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/JexlNode.java
@@ -110,7 +110,8 @@ public abstract class JexlNode extends SimpleNode {
         if (value instanceof JexlPropertyGet
             || value instanceof JexlPropertySet
             || value instanceof JexlMethod
-            || value instanceof Funcall ) {
+            || value instanceof Funcall
+            || value instanceof Class  ) {
             jjtSetValue(null);
         }
         for (int n = 0; n < jjtGetNumChildren(); ++n) {
diff --git a/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java 
b/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
index 487fcc46..eb2cbc0d 100644
--- a/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
+++ b/src/main/java/org/apache/commons/jexl3/parser/JexlParser.java
@@ -695,19 +695,20 @@ public abstract class JexlParser extends StringParser {
                 return true;
             }
             Scope blockScope = blockScopes.get(block);
+            int lexical = symbol;
             for (LexicalUnit unit : blocks) {
                 Scope unitScope = blockScopes.get(unit);
                 // follow through potential capture
                 if (blockScope != unitScope) {
-                    int cs = blockScope.getCaptureDeclaration(symbol);
-                    if (cs >= 0) {
-                        symbol = cs;
+                    int declared = blockScope.getCaptureDeclaration(lexical);
+                    if (declared >= 0) {
+                        lexical = declared;
                     }
                     if (unitScope != null) {
                         blockScope = unitScope;
                     }
                 }
-                if (unit.isConstant(symbol)) {
+                if (unit.isConstant(lexical)) {
                     return true;
                 }
             }
diff --git a/src/site/xdoc/reference/examples.xml 
b/src/site/xdoc/reference/examples.xml
index 29adf331..2101bab6 100644
--- a/src/site/xdoc/reference/examples.xml
+++ b/src/site/xdoc/reference/examples.xml
@@ -55,7 +55,7 @@
         <ul>
           <li>An <a 
href="https://commons.apache.org/jexl/apidocs/org/apache/commons/jexl3/JexlEngine.html";>engine</a>
 to create expressions,</li>
           <li>A <a 
href="https://commons.apache.org/jexl/apidocs/org/apache/commons/jexl3/JexlContext.html";>context</a>
 containing any variables, and</li>
-          <li>An <a 
href="https://commons.apache.org/jexl/apidocs/org/apache/commons/jexl3/Expression.html";>expression</a></li>
+          <li>An <a 
href="https://commons.apache.org/jexl/apidocs/org/apache/commons/jexl3/JexlExpression.html";>expression</a></li>
         </ul>
       </p>
       <p>
diff --git a/src/site/xdoc/reference/syntax.xml 
b/src/site/xdoc/reference/syntax.xml
index cbbb468a..83f3a40c 100644
--- a/src/site/xdoc/reference/syntax.xml
+++ b/src/site/xdoc/reference/syntax.xml
@@ -874,6 +874,9 @@
                             <li>&amp;=</li>
                             <li>|=</li>
                             <li>^=</li>
+                            <li>&lt;&lt;=</li>
+                            <li>&gt;&gt;=</li>
+                            <li>&gt;&gt;&gt;=</li>
                         </ul>
                     </td>
                 </tr>
@@ -889,7 +892,7 @@
                     <td>
                         The unary <code>+</code> operator is used. It performs 
an integral promotion meaning
                         that byte, short, char arguments will be promoted to 
integer as a result.
-                        For example  <code>+12</code> or <code>-(a * b)</code>
+                        For example  <code>+12</code> or <code>+(a * b)</code>
                     </td>
                 </tr>
                 <tr>
@@ -1022,7 +1025,7 @@
                     <td>while</td>
                     <td>
                         Loop until a condition is satisfied, e.g.
-                        <code>while (x lt 10) {
+                        <code>while (x &lt; 10) {
                             x = x + 2;
                             }</code>
                     </td>
@@ -1033,7 +1036,7 @@
                         Loop until a condition is satisfied, e.g.
                         <code>do {
                             x = x + 2;
-                            } while (x lt 10)</code>
+                            } while (x &lt; 10)</code>
                     </td>
                 </tr>
                 <tr>
diff --git a/src/test/java/org/apache/commons/jexl3/LexicalTest.java 
b/src/test/java/org/apache/commons/jexl3/LexicalTest.java
index be97c44d..62ecfbc3 100644
--- a/src/test/java/org/apache/commons/jexl3/LexicalTest.java
+++ b/src/test/java/org/apache/commons/jexl3/LexicalTest.java
@@ -930,7 +930,7 @@ public class LexicalTest {
     }
 
     @Test
-    public void testConstb0() {
+    public void testConst0b() {
         final JexlFeatures f = new JexlFeatures();
         final JexlEngine jexl = new JexlBuilder().strict(true).create();
         final JexlScript script = jexl.createScript(

Reply via email to