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