This is an automated email from the ASF dual-hosted git repository. henrib pushed a commit to branch JEXL-418 in repository https://gitbox.apache.org/repos/asf/commons-jexl.git
The following commit(s) were added to refs/heads/JEXL-418 by this push: new d2d2ff57 JEXL-418: fixing reserved names, preparing for feature flag; d2d2ff57 is described below commit d2d2ff57adf991e639c4b218fd714a769bdd53aa Author: Henri Biestro <hbies...@cloudera.com> AuthorDate: Fri Feb 16 23:19:52 2024 +0100 JEXL-418: fixing reserved names, preparing for feature flag; --- .../org/apache/commons/jexl3/JexlFeatures.java | 4 +- .../apache/commons/jexl3/internal/Interpreter.java | 3 +- .../org/apache/commons/jexl3/parser/Parser.jjt | 20 +++++++-- .../org/apache/commons/jexl3/FeaturesTest.java | 2 +- .../java/org/apache/commons/jexl3/LexicalTest.java | 4 +- .../apache/commons/jexl3/TryCatchFinallyTest.java | 49 +++++++++++++++++----- 6 files changed, 61 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/apache/commons/jexl3/JexlFeatures.java b/src/main/java/org/apache/commons/jexl3/JexlFeatures.java index 4cee5a7d..be45f9b5 100644 --- a/src/main/java/org/apache/commons/jexl3/JexlFeatures.java +++ b/src/main/java/org/apache/commons/jexl3/JexlFeatures.java @@ -227,13 +227,13 @@ public final class JexlFeatures { /** * Protected future syntactic elements. - * <p><em>try, catch, throw, finally, switch, case, default, class, instanceof, jexl, $jexl</em></p> + * <p><em>throw, switch, case, default, class, instanceof, jexl, $jexl</em></p> * @since 3.3.1 */ private static final Set<String> RESERVED_WORDS = Collections.unmodifiableSet( new HashSet<>((Arrays.asList( - "try", "catch", "throw", "finally", "switch", "case", "default", "class", "instanceof", "jexl", "$jexl")))); + "switch", "case", "default", "class", "instanceof", "jexl", "$jexl")))); /** * The modern scripting features set. 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 c2553001..82a77edf 100644 --- a/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java +++ b/src/main/java/org/apache/commons/jexl3/internal/Interpreter.java @@ -695,10 +695,10 @@ public class Interpreter extends InterpreterBase { */ private Object evalTry(JexlNode tryVar, JexlNode tryExpression, JexlNode tryBody, final Object data) { boolean lexical = false; + Object tryResult = null; try { final ASTIdentifier tryVariable; final int symbol; - Object tryResult = null; /* Capture try variable if any. */ if (tryVar instanceof ASTReference) { tryVariable = (ASTIdentifier) tryVar.jjtGetChild(0); @@ -734,6 +734,7 @@ public class Interpreter extends InterpreterBase { // evaluate the body return tryBody.jjtAccept(this, data); } finally { + closeIfSupported(tryResult); // restore lexical frame if (lexical) { block = block.pop(); 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 7dbcebaa..a09f2f21 100644 --- a/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt +++ b/src/main/java/org/apache/commons/jexl3/parser/Parser.jjt @@ -82,6 +82,7 @@ PARSER_END(Parser) TOKEN_MGR_DECLS : { boolean comparatorNames = false; + boolean jexl331 = true; } /*************************************** @@ -219,11 +220,14 @@ TOKEN_MGR_DECLS : { | < NULL : "null" > | < TRUE : "true" > | < FALSE : "false" > - | < THROW : "throw" > +} + +<NEVER> TOKEN : /* Exception handling. */ +{ + < THROW : "throw" > | < TRY : "try" > | < CATCH : "catch" > | < FINALLY : "finally" > - } /*************************************** @@ -249,7 +253,8 @@ TOKEN_MGR_DECLS : { < IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>|<ESCAPE>)* > { matchedToken.image = StringParser.unescapeIdentifier(matchedToken.image); - if (comparatorNames && matchedToken.image.length() == 2) { + final int length = matchedToken.image.length(); + if (comparatorNames && length == 2) { switch (matchedToken.image) { case "ne" : matchedToken.kind = NE; break; case "eq" : matchedToken.kind = EQ; break; @@ -258,6 +263,13 @@ TOKEN_MGR_DECLS : { case "gt" : matchedToken.kind = GT; break; case "ge" : matchedToken.kind = GE; break; } + } else if (jexl331 && length >= 3 && length <= 7) { + switch (matchedToken.image) { + case "try" : matchedToken.kind = TRY; break; + case "catch" : matchedToken.kind = CATCH; break; + case "finally" : matchedToken.kind = FINALLY; break; + case "throw" : matchedToken.kind = THROW; break; + } } } | @@ -420,7 +432,7 @@ void TryStatement() : { { pushUnit(jjtThis); } - <TRY> (<LPAREN> (LOOKAHEAD(3) InlineVar() <assign> { tryForm |= 1; })? Expression() <RPAREN> { tryForm |= 2; })? + <TRY> (LOOKAHEAD(2) <LPAREN> (LOOKAHEAD(3) InlineVar() <assign> { tryForm |= 1; })? Expression() <RPAREN> { tryForm |= 2; })? ((LOOKAHEAD(1) Block() | StatementNoVar()) { tryForm |= 4; }) (LOOKAHEAD(1) <CATCH> <LPAREN> InlineVar() <RPAREN> (LOOKAHEAD(1) Block() | StatementNoVar()) { tryForm |= 8; })? (LOOKAHEAD(1) <FINALLY> (LOOKAHEAD(1) Block() | StatementNoVar()) { tryForm |= 16; })? diff --git a/src/test/java/org/apache/commons/jexl3/FeaturesTest.java b/src/test/java/org/apache/commons/jexl3/FeaturesTest.java index a125a389..ce7e49c4 100644 --- a/src/test/java/org/apache/commons/jexl3/FeaturesTest.java +++ b/src/test/java/org/apache/commons/jexl3/FeaturesTest.java @@ -97,7 +97,7 @@ public class FeaturesTest extends JexlTestCase { for(String varName : reserved) { String src = "var " + varName; //JexlScript script = jexl.createScript(src); - Assert.assertThrows(JexlException.Feature.class, () -> jexl.createScript(src)); + Assert.assertThrows(src, JexlException.Feature.class, () -> jexl.createScript(src)); } final String[] cmpNameScripts = { "1 eq 1", diff --git a/src/test/java/org/apache/commons/jexl3/LexicalTest.java b/src/test/java/org/apache/commons/jexl3/LexicalTest.java index 6a5549a8..a657a5f0 100644 --- a/src/test/java/org/apache/commons/jexl3/LexicalTest.java +++ b/src/test/java/org/apache/commons/jexl3/LexicalTest.java @@ -550,8 +550,8 @@ public class LexicalTest { ctxt.set("options", options); final JexlScript runner = jexl.createScript( "options.lexical = flag; options.lexicalShade = flag;" - + "tryCatch(test, catch, 42);", - "flag", "test", "catch"); + + "tryCatch(test, catcher, 42);", + "flag", "test", "catcher"); final JexlScript tested = jexl.createScript("(y)->{ {var x = y;} x }"); final JexlScript catchFn = jexl.createScript("(xany)-> { xany }"); Object result; diff --git a/src/test/java/org/apache/commons/jexl3/TryCatchFinallyTest.java b/src/test/java/org/apache/commons/jexl3/TryCatchFinallyTest.java index 38535f64..7732b1c5 100644 --- a/src/test/java/org/apache/commons/jexl3/TryCatchFinallyTest.java +++ b/src/test/java/org/apache/commons/jexl3/TryCatchFinallyTest.java @@ -19,6 +19,9 @@ package org.apache.commons.jexl3; import org.junit.Assert; import org.junit.Test; +import java.io.Closeable; +import java.io.IOException; + public class TryCatchFinallyTest extends JexlTestCase { public TryCatchFinallyTest() { super(TryCatchFinallyTest.class.getSimpleName()); @@ -32,6 +35,7 @@ public class TryCatchFinallyTest extends JexlTestCase { Object result = script.execute(null); Assert.assertEquals(42, result); } + @Test public void testForm0x17() { String src = "try(let x = 42) { x; } finally { 169; }"; @@ -41,18 +45,41 @@ public class TryCatchFinallyTest extends JexlTestCase { Assert.assertEquals(42, result); } + public static class Circuit implements Closeable { + boolean opened = true; - @Test - public void testEdgeTry() { - int i = 0; - while(i++ < 5) { - System.out.println("i: " + i); - try { - throw new JexlException.Continue(null); - } finally { - continue; - } + public boolean isOpened() { + return opened; + } + @Override + public void close() throws IOException { + opened = false; } - System.out.println("iii: " + i); } + + @Test + public void testForm0x17a() { + String src = "try(let x = c) { c.isOpened()? 42 : -42; } finally { 169; }"; + JexlScript script = JEXL.createScript(src, "c"); + Circuit circuit = new Circuit(); + Assert.assertNotNull(script); + Object result = script.execute(null, circuit); + Assert.assertEquals(42, result); + Assert.assertFalse(circuit.isOpened()); + } + + +// @Test +// public void testEdgeTry() { +// int i = 0; +// while(i++ < 5) { +// System.out.println("i: " + i); +// try { +// throw new JexlException.Continue(null); +// } finally { +// continue; +// } +// } +// System.out.println("iii: " + i); +// } }