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 2020/11/17 15:29:13 UTC

[commons-jexl] branch master updated: JEXL-307 : - Fixed a potential bug when cleaning lexical frame; - Java8 cleanup

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 186847b  JEXL-307 : - Fixed a potential bug when cleaning lexical frame; - Java8 cleanup
186847b is described below

commit 186847b2f3e6124a9bc06910ec2f654b42c6ec0c
Author: henrib <he...@apache.org>
AuthorDate: Tue Nov 17 16:27:10 2020 +0100

    JEXL-307 :
    - Fixed a potential bug when cleaning lexical frame;
    - Java8 cleanup
---
 .../commons/jexl3/internal/LexicalFrame.java       | 66 +++++++++++-----------
 .../commons/jexl3/internal/LexicalScope.java       | 57 +++++++++++++++----
 .../jexl3/internal/TemplateInterpreter.java        | 24 ++++----
 3 files changed, 92 insertions(+), 55 deletions(-)

diff --git a/src/main/java/org/apache/commons/jexl3/internal/LexicalFrame.java b/src/main/java/org/apache/commons/jexl3/internal/LexicalFrame.java
index 22eefde..9318da5 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/LexicalFrame.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/LexicalFrame.java
@@ -24,58 +24,69 @@ import java.util.Deque;
  * <p>The symbol identifiers are determined by the functional scope.
  */
 public class LexicalFrame extends LexicalScope {
-    /** The script frame. */
+    /**
+     * The script frame.
+     */
     private final Frame frame;
-    /** The stack of values in the lexical frame. */
-    private Deque<Object> stack = null;
-    /** Previous frame. */
+    /**
+     * Previous frame.
+     */
     protected LexicalFrame previous;
     /**
+     * The stack of values in the lexical frame.
+     */
+    private Deque<Object> stack = null;
+
+    /**
      * Lexical frame ctor.
+     *
      * @param scriptf the script frame
-     * @param outerf the previous lexical frame
+     * @param outerf  the previous lexical frame
      */
     public LexicalFrame(Frame scriptf, LexicalFrame outerf) {
         this.previous = outerf;
         this.frame = scriptf;
     }
-    
+
     /**
      * Copy ctor.
+     *
      * @param src the frame to copy
      */
     public LexicalFrame(LexicalFrame src) {
         super(src.symbols, src.moreSymbols);
         frame = src.frame;
         previous = src.previous;
-        stack = src.stack != null? new ArrayDeque<Object>(src.stack) : null;
+        stack = src.stack != null ? new ArrayDeque<>(src.stack) : null;
     }
-   
+
     /**
      * Define the arguments.
+     *
      * @return this frame
      */
     public LexicalFrame defineArgs() {
         if (frame != null) {
             int argc = frame.getScope().getArgCount();
-            for(int a  = 0; a < argc; ++a) {
+            for (int a = 0; a < argc; ++a) {
                 super.addSymbol(a);
             }
         }
         return this;
     }
 
-   /**
-    * Defines a symbol.
-    * @param symbol the symbol to define
-    * @param capture whether this redefines a captured symbol
-    * @return true if symbol is defined, false otherwise
-    */
-   public boolean defineSymbol(int symbol, boolean capture) {
+    /**
+     * Defines a symbol.
+     *
+     * @param symbol  the symbol to define
+     * @param capture whether this redefines a captured symbol
+     * @return true if symbol is defined, false otherwise
+     */
+    public boolean defineSymbol(int symbol, boolean capture) {
         boolean declared = addSymbol(symbol);
         if (declared && capture) {
             if (stack == null) {
-                stack = new ArrayDeque<Object>() ;
+                stack = new ArrayDeque<>();
             }
             stack.push(symbol);
             Object value = frame.get(symbol);
@@ -89,30 +100,19 @@ public class LexicalFrame extends LexicalScope {
 
     /**
      * Pops back values and lexical frame.
+     *
      * @return the previous frame
      */
     public LexicalFrame pop() {
-        long clean = symbols;
-        // undefine symbols getting out of scope
-        while (clean != 0L) {
-            int s = Long.numberOfTrailingZeros(clean);
-            clean &= ~(1L << s);
-            frame.set(s, Scope.UNDEFINED);
-        }
-        symbols = 0L;
-        if (moreSymbols != null) {
-            for (int s = moreSymbols.nextSetBit(0); s != -1; s = moreSymbols.nextSetBit(s + 1)) {
-                frame.set(s, Scope.UNDEFINED);
-            }
-            moreSymbols.clear();
-        }
+        // undefine all symbols
+        clearSymbols(s ->   frame.set(s, Scope.UNDEFINED) );
         // restore values of captured symbols that were overwritten
         if (stack != null) {
-            while(!stack.isEmpty()) {
+            while (!stack.isEmpty()) {
                 Object value = stack.pop();
                 if (value == Scope.UNDECLARED) {
                     value = Scope.UNDEFINED;
-                } else if (value == this) {// || value == Scope.UNDEFINED) {
+                } else if (value == this) {
                     value = null;
                 }
                 int symbol = (Integer) stack.pop();
diff --git a/src/main/java/org/apache/commons/jexl3/internal/LexicalScope.java b/src/main/java/org/apache/commons/jexl3/internal/LexicalScope.java
index 6ea93cc..1a10e47 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/LexicalScope.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/LexicalScope.java
@@ -23,30 +23,39 @@ import java.util.BitSet;
  * <p>The symbol identifiers are determined by the functional scope.
  */
 public class LexicalScope {
-    /** Number of bits in a long. */
+    /**
+     * Number of bits in a long.
+     */
     protected static final int LONGBITS = 64;
-    /** The mask of symbols in the frame. */
+    /**
+     * The mask of symbols in the frame.
+     */
     protected long symbols = 0L;
-    /** Symbols after 64. */
+    /**
+     * Symbols after 64.
+     */
     protected BitSet moreSymbols = null;
 
     /**
      * Create a scope.
      */
-    public LexicalScope() {}
-        
+    public LexicalScope() {
+    }
+
     /**
      * Frame copy ctor base.
-     * @param s the symbols mask
+     *
+     * @param s  the symbols mask
      * @param ms the more symbols bitset
      */
     protected LexicalScope(long s, BitSet ms) {
         symbols = s;
-        moreSymbols = ms != null? (BitSet) ms.clone() : null;
+        moreSymbols = ms != null ? (BitSet) ms.clone() : null;
     }
-    
+
     /**
      * Ensure more symbpls can be stored.
+     *
      * @return the set of more symbols
      */
     protected final BitSet moreSymbols() {
@@ -58,6 +67,7 @@ public class LexicalScope {
 
     /**
      * Checks whether a symbol has already been declared.
+     *
      * @param symbol the symbol
      * @return true if declared, false otherwise
      */
@@ -71,10 +81,11 @@ public class LexicalScope {
 
     /**
      * Adds a symbol in this scope.
+     *
      * @param symbol the symbol
      * @return true if registered, false if symbol was already registered
      */
-    public final boolean addSymbol(int symbol) {
+    public boolean addSymbol(int symbol) {
         if (symbol < LONGBITS) {
             if ((symbols & (1L << symbol)) != 0L) {
                 return false;
@@ -92,9 +103,35 @@ public class LexicalScope {
     }
 
     /**
+     * Clear all symbols.
+     *
+     * @param cleanSymbol a (optional, may be null) functor to call for each cleaned symbol
+     */
+    public final void clearSymbols(java.util.function.IntConsumer cleanSymbol) {
+        // undefine symbols getting out of scope
+        if (cleanSymbol != null) {
+            long clean = symbols;
+            while (clean != 0L) {
+                int s = Long.numberOfTrailingZeros(clean);
+                clean &= ~(1L << s);
+                cleanSymbol.accept(s);
+            }
+        }
+        symbols = 0L;
+        if (moreSymbols != null) {
+            if (cleanSymbol != null) {
+                for (int s = moreSymbols.nextSetBit(0); s != -1; s = moreSymbols.nextSetBit(s + 1)) {
+                    cleanSymbol.accept(s + LONGBITS);
+                }
+            }
+            moreSymbols.clear();
+        }
+    }
+
+    /**
      * @return the number of symbols defined in this scope.
      */
     public int getSymbolCount() {
-        return Long.bitCount(symbols) + (moreSymbols == null? 0 : moreSymbols.cardinality());
+        return Long.bitCount(symbols) + (moreSymbols == null ? 0 : moreSymbols.cardinality());
     }
 }
diff --git a/src/main/java/org/apache/commons/jexl3/internal/TemplateInterpreter.java b/src/main/java/org/apache/commons/jexl3/internal/TemplateInterpreter.java
index ebfab0d..865469e 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/TemplateInterpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/TemplateInterpreter.java
@@ -57,50 +57,50 @@ public class TemplateInterpreter extends Interpreter {
         TemplateExpression[] expressions;
         /** The writer. */
         Writer out;
-        
+
         /**
          * Sole ctor.
          * @param e the JEXL engine
-         */  
+         */
         Arguments(Engine e) {
             this.jexl = e;
-        } 
+        }
         /**
          * Sets the options.
          * @param o the options
          * @return this instance
-         */         
+         */
         Arguments options(JexlOptions o) {
             this.options = o;
             return this;
-        } 
+        }
         /**
          * Sets the context.
          * @param j the context
          * @return this instance
-         */      
+         */
         Arguments context(JexlContext j) {
             this.jcontext = j;
             return this;
-        } 
+        }
         /**
          * Sets the frame.
          * @param f the frame
          * @return this instance
-         */        
+         */
         Arguments frame(Frame f) {
             this.jframe = f;
             return this;
-        }  
+        }
         /**
          * Sets the expressions.
          * @param e the expressions
          * @return this instance
-         */  
+         */
         Arguments expressions(TemplateExpression[] e) {
             this.expressions = e;
             return this;
-        }   
+        }
         /**
          * Sets the writer.
          * @param o the writer
@@ -111,7 +111,7 @@ public class TemplateInterpreter extends Interpreter {
             return this;
         }
     }
-    
+
     /**
      * Creates a template interpreter instance.
      * @param args the template interpreter arguments