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 3520002 JEXL-265: making namespace identifier explicit in grammar and code 3520002 is described below commit 3520002a25461a7b9de0da0ca1005326e2175e28 Author: henrib <hen...@apache.org> AuthorDate: Mon Aug 6 11:15:04 2018 +0200 JEXL-265: making namespace identifier explicit in grammar and code --- .../apache/commons/jexl3/internal/Debugger.java | 8 ++- .../apache/commons/jexl3/internal/Interpreter.java | 19 ++------ .../commons/jexl3/internal/TemplateDebugger.java | 24 ++++----- .../apache/commons/jexl3/parser/ASTIdentifier.java | 8 ++- ...Identifier.java => ASTNamespaceIdentifier.java} | 57 ++++++++-------------- .../org/apache/commons/jexl3/parser/Parser.jjt | 21 +++++--- .../org/apache/commons/jexl3/Issues200Test.java | 24 +++++++++ 7 files changed, 85 insertions(+), 76 deletions(-) diff --git a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java index 08fec42..db75d81 100644 --- a/src/main/java/org/apache/commons/jexl3/internal/Debugger.java +++ b/src/main/java/org/apache/commons/jexl3/internal/Debugger.java @@ -602,8 +602,14 @@ public class Debugger extends ParserVisitor implements JexlInfo.Detail { @Override protected Object visit(ASTIdentifier node, Object data) { + String ns = node.getNamespace(); String image = StringParser.escapeIdentifier(node.getName()); - return check(node, image, data); + if (ns == null) { + return check(node, image, data); + } else { + String nsid = StringParser.escapeIdentifier(ns) + ":" + image; + return check(node, nsid, data); + } } @Override 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 7c39199..0ff4796 100644 --- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java +++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java @@ -1368,20 +1368,11 @@ public class Interpreter extends InterpreterBase { @Override protected Object visit(ASTFunctionNode node, Object data) { - int argc = node.jjtGetNumChildren(); - if (argc == 2) { - ASTIdentifier functionNode = (ASTIdentifier) node.jjtGetChild(0); - ASTArguments argNode = (ASTArguments) node.jjtGetChild(1); - return call(node, context, functionNode, argNode); - } else { - // objectNode 0 is the prefix - String prefix = ((ASTIdentifier) node.jjtGetChild(0)).getName(); - Object namespace = resolveNamespace(prefix, node); - // objectNode 1 is the identifier , the others are parameters. - ASTIdentifier functionNode = (ASTIdentifier) node.jjtGetChild(1); - ASTArguments argNode = (ASTArguments) node.jjtGetChild(2); - return call(node, namespace, functionNode, argNode); - } + ASTIdentifier functionNode = (ASTIdentifier) node.jjtGetChild(0); + String nsid = functionNode.getNamespace(); + Object namespace = (nsid != null)? resolveNamespace(nsid, node) : context; + ASTArguments argNode = (ASTArguments) node.jjtGetChild(1); + return call(node, namespace, functionNode, argNode); } /** diff --git a/src/main/java/org/apache/commons/jexl3/internal/TemplateDebugger.java b/src/main/java/org/apache/commons/jexl3/internal/TemplateDebugger.java index 4bccc56..394d9b9 100644 --- a/src/main/java/org/apache/commons/jexl3/internal/TemplateDebugger.java +++ b/src/main/java/org/apache/commons/jexl3/internal/TemplateDebugger.java @@ -151,20 +151,16 @@ public class TemplateDebugger extends Debugger { private int getPrintStatement(JexlNode child) { if (child instanceof ASTFunctionNode) { ASTFunctionNode node = (ASTFunctionNode) child; - int num = node.jjtGetNumChildren(); - if (num == 3) { - ASTIdentifier ns = (ASTIdentifier) node.jjtGetChild(0); - ASTIdentifier fn = (ASTIdentifier) node.jjtGetChild(1); - JexlNode args = node.jjtGetChild(2); - if ("jexl".equals(ns.getName()) - && "print".equals(fn.getName()) - && args.jjtGetNumChildren() == 1 - && args.jjtGetChild(0) instanceof ASTNumberLiteral) { - ASTNumberLiteral exprn = (ASTNumberLiteral) args.jjtGetChild(0); - int n = exprn.getLiteral().intValue(); - if (exprs != null && n >= 0 && n < exprs.length) { - return n; - } + ASTIdentifier ns = (ASTIdentifier) node.jjtGetChild(0); + JexlNode args = node.jjtGetChild(1); + if ("jexl".equals(ns.getNamespace()) + && "print".equals(ns.getName()) + && args.jjtGetNumChildren() == 1 + && args.jjtGetChild(0) instanceof ASTNumberLiteral) { + ASTNumberLiteral exprn = (ASTNumberLiteral) args.jjtGetChild(0); + int n = exprn.getLiteral().intValue(); + if (exprs != null && n >= 0 && n < exprs.length) { + return n; } } } diff --git a/src/main/java/org/apache/commons/jexl3/parser/ASTIdentifier.java b/src/main/java/org/apache/commons/jexl3/parser/ASTIdentifier.java index d53f22e..782ebf5 100644 --- a/src/main/java/org/apache/commons/jexl3/parser/ASTIdentifier.java +++ b/src/main/java/org/apache/commons/jexl3/parser/ASTIdentifier.java @@ -20,8 +20,8 @@ package org.apache.commons.jexl3.parser; * Identifiers, variables, ie symbols. */ public class ASTIdentifier extends JexlNode { - private String name = null; - private int symbol = -1; + protected String name = null; + protected int symbol = -1; ASTIdentifier(int id) { super(id); @@ -55,6 +55,10 @@ public class ASTIdentifier extends JexlNode { public String getName() { return name; } + + public String getNamespace() { + return null; + } @Override public Object jjtAccept(ParserVisitor visitor, Object data) { diff --git a/src/main/java/org/apache/commons/jexl3/parser/ASTIdentifier.java b/src/main/java/org/apache/commons/jexl3/parser/ASTNamespaceIdentifier.java similarity index 52% copy from src/main/java/org/apache/commons/jexl3/parser/ASTIdentifier.java copy to src/main/java/org/apache/commons/jexl3/parser/ASTNamespaceIdentifier.java index d53f22e..698fbd9 100644 --- a/src/main/java/org/apache/commons/jexl3/parser/ASTIdentifier.java +++ b/src/main/java/org/apache/commons/jexl3/parser/ASTNamespaceIdentifier.java @@ -17,47 +17,28 @@ package org.apache.commons.jexl3.parser; /** - * Identifiers, variables, ie symbols. + * Namespace : identifier. */ -public class ASTIdentifier extends JexlNode { - private String name = null; - private int symbol = -1; - - ASTIdentifier(int id) { +public class ASTNamespaceIdentifier extends ASTIdentifier { + private String namespace; + + public ASTNamespaceIdentifier(int id) { super(id); } - - ASTIdentifier(Parser p, int id) { - super(p, id); - } - - @Override - public String toString() { - return name; - } - - void setSymbol(String identifier) { - if (identifier.charAt(0) == '#') { - symbol = Integer.parseInt(identifier.substring(1)); - } - name = identifier; - } - - void setSymbol(int r, String identifier) { - symbol = r; - name = identifier; - } - - public int getSymbol() { - return symbol; - } - - public String getName() { - return name; - } - + @Override - public Object jjtAccept(ParserVisitor visitor, Object data) { - return visitor.visit(this, data); + public String getNamespace() { + return namespace; + } + + /** + * Sets the namespace:identifier. + * + * @param ns the namespace + * @param id the names + */ + public void setNamespace(String ns, String id) { + this.namespace = ns; + this.name = id; } } diff --git a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt index a2a2d27..6bcaae4 100644 --- a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt +++ b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt @@ -144,7 +144,7 @@ TOKEN_MGR_DECLS : { | < LBRACKET : "[" > | < RBRACKET : "]" > | < SEMICOL : ";" > - | < COLON : ":" > + | < COLON : ":" > | < COMMA : "," > | < DOT : "." > { pushDot(); } /* Lexical state is now DOT_ID */ | < QDOT : "?." > { pushDot(); } /* Lexical state is now DOT_ID */ @@ -591,15 +591,22 @@ void Identifier(boolean top) : t=<REGISTER> { jjtThis.setSymbol(t.image); } } + +void NamespaceIdentifier() #NamespaceIdentifier : +{ + Token ns; + Token id; +} +{ + ns=<IDENTIFIER> <COLON> id=<IDENTIFIER> { jjtThis.setNamespace(ns.image, id.image); } +} + void StringIdentifier() #Identifier : { Token t; } { - t=<STRING_LITERAL> - { - jjtThis.setSymbol(Parser.buildString(t.image, true)); - } + t=<STRING_LITERAL> { jjtThis.setSymbol(Parser.buildString(t.image, true)); } } void Literal() #void : @@ -736,7 +743,7 @@ void Arguments() #Arguments : {} void FunctionCallLookahead() #void : {} { - LOOKAHEAD(4) <IDENTIFIER> <COLON> <IDENTIFIER> <LPAREN> + LOOKAHEAD(2) <IDENTIFIER> <COLON> <IDENTIFIER> <LPAREN> | LOOKAHEAD(2) <IDENTIFIER> <LPAREN> | @@ -745,7 +752,7 @@ void FunctionCallLookahead() #void : {} void FunctionCall() #void : {} { - LOOKAHEAD(2) Identifier() <COLON> Identifier() Arguments() #FunctionNode(3) + LOOKAHEAD(2) NamespaceIdentifier() Arguments() #FunctionNode(2) | LOOKAHEAD(2) Identifier(true) Arguments() #FunctionNode(2) } diff --git a/src/test/java/org/apache/commons/jexl3/Issues200Test.java b/src/test/java/org/apache/commons/jexl3/Issues200Test.java index f35e0ef..a18dd9c 100644 --- a/src/test/java/org/apache/commons/jexl3/Issues200Test.java +++ b/src/test/java/org/apache/commons/jexl3/Issues200Test.java @@ -18,6 +18,7 @@ package org.apache.commons.jexl3; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -483,4 +484,27 @@ public class Issues200Test extends JexlTestCase { Assert.assertEquals(42, value); } } + + @Test + public void test265() throws Exception { + JexlEngine jexl = new JexlBuilder().cache(4).create(); + JexlContext ctxt = new MapContext(); + ctxt.set("x", 42); + Object result; + JexlScript script; + try { + script = jexl.createScript("(true) ? x : abs(1)"); + } catch (JexlException.Parsing xparse) { + // ambiguous, parsing fails + } + script = jexl.createScript("(true) ? (x) : abs(2)"); + result = script.execute(ctxt); + Assert.assertEquals(42, result); + script = jexl.createScript("(true) ? x : (abs(3))"); + result = script.execute(ctxt); + Assert.assertEquals(42, result); + script = jexl.createScript("(!true) ? abs(4) : x"); + result = script.execute(ctxt); + Assert.assertEquals(42, result); + } }