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 2018/08/06 09:15:25 UTC
[commons-jexl] branch master updated: JEXL-265: making namespace
identifier explicit in grammar and code
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 <he...@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);
+ }
}