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/01/16 13:39:34 UTC

[commons-jexl] 02/04: JEXL-307: better detection of shaded variables Task #JEXL-307 - Variable redeclaration option

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 8f78f4580341ca2edf17c0eae1cf9f36f39c28f5
Author: henrib <he...@apache.org>
AuthorDate: Thu Jan 16 14:35:47 2020 +0100

    JEXL-307: better detection of shaded variables
    Task #JEXL-307 - Variable redeclaration option
---
 .../apache/commons/jexl3/internal/Interpreter.java |  4 +--
 .../commons/jexl3/internal/InterpreterBase.java    | 42 ++++++++++++++--------
 2 files changed, 30 insertions(+), 16 deletions(-)

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 dac5b49..563877f 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java
@@ -149,6 +149,7 @@ public class Interpreter extends InterpreterBase {
     protected Interpreter(Interpreter ii, JexlArithmetic jexla) {
         super(ii, jexla);
         frame = ii.frame;
+        block = ii.block != null? new LexicalFrame(ii.block) : null;
     }
 
     /**
@@ -1311,8 +1312,7 @@ public class Interpreter extends InterpreterBase {
                     if (!block.declareSymbol(symbol)) {
                         return redefinedVariable(var, var.getName());
                     }
-                // if not in lexical block, undefined if (in its symbol) shade
-                } else if (!block.hasSymbol(symbol) && options.isLexicalShade()) {
+                } else if (isSymbolShaded(symbol, block)) { 
                     return undefinedVariable(var, var.getName());
                 }
             }
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 75b2d12..97c936d 100644
--- a/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
+++ b/src/main/java/org/apache/commons/jexl3/internal/InterpreterBase.java
@@ -69,12 +69,12 @@ public abstract class InterpreterBase extends ParserVisitor {
     protected static final Object[] EMPTY_PARAMS = new Object[0];
     /** The context to store/retrieve variables. */
     protected final JexlContext.NamespaceResolver ns;
+    /** The operators evaluation delegate. */
+    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. */
     protected Map<String, Object> functors;
-    /** The operators evaluation delegate. */
-    protected final Operators operators;
     
     /**
      * Creates an interpreter base.
@@ -120,15 +120,15 @@ public abstract class InterpreterBase extends ParserVisitor {
         jexl = ii.jexl;
         logger = ii.logger;
         uberspect = ii.uberspect;
+        arithmetic = jexla;
         context = ii.context;
-        arithmetic = ii.arithmetic;
+        options = ii.options.copy();
         cache = ii.cache;
         ns = ii.ns;
+        operators = ii.operators;
         cancelled = ii.cancelled;
         functions = ii.functions;
         functors = ii.functors;
-        operators = ii.operators;
-        options = ii.options.copy();
     }
 
 
@@ -243,6 +243,27 @@ public abstract class InterpreterBase extends ParserVisitor {
     }
 
     /**
+     * Checks whether a symbol is a shade or actually accessible.
+     * @param symbol the symbol
+     * @param block the block to check from (canoot be null)
+     * @return true is symbol is just a shade, false otherwise
+     */
+    protected boolean isSymbolShaded(int symbol, LexicalScope block) {
+        if (!options.isLexicalShade()) {
+            return false;
+        }
+        // if not in lexical block, undefined if (in its symbol) shade
+        LexicalScope b = block;
+        while (b != null) {
+            if (b.hasSymbol(symbol)) {
+                return false;
+            }
+            b = b.previous;
+        }
+        return true;
+    }
+    
+    /**
      * Gets a value of a defined local variable or from the context.
      * @param frame the local frame
      * @param block the lexical block if any
@@ -254,15 +275,8 @@ public abstract class InterpreterBase extends ParserVisitor {
         // if we have a symbol, we have a scope thus a frame
         if (symbol >= 0) {
             if (frame.has(symbol)) {
-                if (options.isLexical() && options.isLexicalShade()) {
-                    // if not in lexical block, undefined if (in its symbol) shade
-                    LexicalScope b = block;
-                    while(b != null && !b.hasSymbol(symbol)) {
-                        b = b.previous;
-                    }
-                    if (b == null) {
-                        return undefinedVariable(identifier, identifier.getName());
-                    }
+                if (options.isLexical() && isSymbolShaded(symbol, block)) {
+                    return undefinedVariable(identifier, identifier.getName());
                 }
                 Object value = frame.get(symbol);
                 if (value != Scope.UNDEFINED) {