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 <hen...@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