[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17020834#comment-17020834 ] Dmitri Blinov edited comment on JEXL-307 at 1/23/20 9:07 AM: - And one more thing... hoisted variables are not resolved in nested blocks - _*variable 'x' is undefined*_ {code:java} @Test public void testHoisted() throws Exception { JexlFeatures f = new JexlFeatures(); f.lexical(true); JexlEngine jexl = new JexlBuilder().strict(true).features(f).create(); JexlScript script = jexl.createScript("var x = 10; var a = function(var b) {for (var q : 1 ..10) {return x + b}}; a(32)"); JexlContext jc = new MapContext(); Object result = script.execute(null); Assert.assertEquals(result, 42); } {code} If the lexical feature is switched off everything works OK. The problem stems from the fact that hoisted variables *may* change their frame pointer index (aka symbol) between frames. So when we check identifier inside {{JexlParser.checkVariable()}} we can not simply check for all lexical units for the identifier to be declared by its *symbol*. We either need to keep track of Frame-LexicalUnit relation when we traverse the lexical stack, or to check for variable by identifier *name* inside LexicalUnit. PS. Technically, what we call a *hoisted* variable in JEXL is a *captured* variable. Maybe its a good point to rebrand this term to make things clear not only from implementation point, but from its definition? was (Author: dmitri_blinov): And one more thing... hoisted variables are not resolved in nested blocks - _*variable 'x' is undefined*_ {code:java} @Test public void testHoisted() throws Exception { JexlFeatures f = new JexlFeatures(); f.lexical(true); JexlEngine jexl = new JexlBuilder().strict(true).features(f).create(); JexlScript script = jexl.createScript("var x = 10; var a = function(var b) {for (var q : 1 ..10) {return x + b}}; a(32)"); JexlContext jc = new MapContext(); Object result = script.execute(null); Assert.assertEquals(result, 42); } {code} If the lexical feature is switched off everything works OK. The problem stems from the fact that hoisted variables *may* change their frame pointer index (aka symbol) between frames. So when we check identifier inside {{JexlParser.checkVariable()}} we can not simply check for all lexical units for the identifier to be declared by its *symbol*. We either need to keep track of Frame-LexicalUnit relation when we traverse the lexical stack, or to check for variable by identifier *name* inside LexicalUnit. > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17020834#comment-17020834 ] Dmitri Blinov edited comment on JEXL-307 at 1/23/20 7:26 AM: - And one more thing... hoisted variables are not resolved in nested blocks - _*variable 'x' is undefined*_ {code:java} @Test public void testHoisted() throws Exception { JexlFeatures f = new JexlFeatures(); f.lexical(true); JexlEngine jexl = new JexlBuilder().strict(true).features(f).create(); JexlScript script = jexl.createScript("var x = 10; var a = function(var b) {for (var q : 1 ..10) {return x + b}}; a(32)"); JexlContext jc = new MapContext(); Object result = script.execute(null); Assert.assertEquals(result, 42); } {code} If the lexical feature is switched off everything works OK. The problem stems from the fact that hoisted variables *may* change their frame pointer index (aka symbol) between frames. So when we check identifier inside {{JexlParser.checkVariable()}} we can not simply check for all lexical units for the identifier to be declared by its *symbol*. We either need to keep track of Frame-LexicalUnit relation when we traverse the lexical stack, or to check for variable by identifier *name* inside LexicalUnit. was (Author: dmitri_blinov): And one more thing... hoisted variables are not resolved in nested blocks - _*variable 'x' is undefined*_ {code:java} @Test public void testHoisted() throws Exception { JexlFeatures f = new JexlFeatures(); f.lexical(true); JexlEngine jexl = new JexlBuilder().strict(true).features(f).create(); JexlScript script = jexl.createScript("var x = 10; var a = function(var b) {for (var q : 1 ..10) {return x + b}}; a(32)"); JexlContext jc = new MapContext(); Object result = script.execute(null); Assert.assertEquals(result, 42); } {code} If the lexical feature is switched off everything works OK. > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16986701#comment-16986701 ] Dmitri Blinov edited comment on JEXL-307 at 12/3/19 8:37 AM: - Maybe I do not fully understand what the lexical feature is all about, but from the previous test case I've learned the idea was to control the access to undeclared local variables. If I'm right, then the following test case should also pass, but it doesn't. {code:java} @Test public void testForVariable() throws Exception { JexlFeatures f = new JexlFeatures(); f.lexical(true); JexlEngine jexl = new JexlBuilder().strict(true).features(f).create(); try { JexlScript script = jexl.createScript("for(var x : 1..3) { var c = 0}; return x"); Assert.fail("Should not have been parsed"); } catch (Exception ex) { // OK } } {code} Compare this to test case that passes correctly: {code:java} @Test public void testUndeclaredVariable() throws Exception { JexlFeatures f = new JexlFeatures(); f.lexical(true); JexlEngine jexl = new JexlBuilder().strict(true).features(f).create(); try { JexlScript script = jexl.createScript("{var x = 0}; return x"); Assert.fail("Should not have been parsed"); } catch (Exception ex) { // OK } } {code} was (Author: dmitri_blinov): Maybe I do not fully understand what the lexical feature is all about, but from the previous test case I've learned the idea was to control the access to undeclared local variables. If I'm right, then the following test case should also pass, but it doesn't. {code:java} @Test public void testForVariable() throws Exception { JexlFeatures f = new JexlFeatures(); f.lexical(true); JexlEngine jexl = new JexlBuilder().strict(true).features(f).create(); try { JexlScript script = jexl.createScript("for(var x : 1..3) { var c = 0}; return x"); Assert.fail("Should not have been parsed"); } catch (Exception ex) { // OK } } {code} > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16984518#comment-16984518 ] Henri Biestro edited comment on JEXL-307 at 11/28/19 4:13 PM: -- Thanks for the find. # [src/main/java/org/apache/commons/jexl3/JexlEngine.java|https://github.com/apache/commons-jexl#diff-6cd4728e86a21e88658014798b66f1c6] # [src/main/java/org/apache/commons/jexl3/internal/Engine.java|https://github.com/apache/commons-jexl#diff-41922f0eb638444de5b25b4cc16b6f1f] # [src/test/java/org/apache/commons/jexl3/LexicalTest.java|https://github.com/apache/commons-jexl#diff-e970fae7048740d7efe69fa7b2e1c082] Changeset: 4f1a6d15e8a9a837b4e2326f74a44a8632163559 Author: henrib Date: 2019-11-28 17:09 Message: JEXL-307: handle top-level lambda creation consistently was (Author: henrib): Changeset: 4f1a6d15e8a9a837b4e2326f74a44a8632163559 Author:henrib Date: 2019-11-28 17:09 Message: JEXL-307: handle top-level lambda creation consistently > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16984222#comment-16984222 ] Dmitri Blinov edited comment on JEXL-307 at 11/28/19 11:40 AM: --- I've got a regression with recent changes. For some reason the script created with JexlInfo fails to report declared parameters and local variables. The following test case illustrates this {code:java} @Test public void testParameters() throws Exception { String str = "function(u) {}"; JexlEngine jexl = new JexlBuilder().create(); JexlScript e = jexl.createScript(new JexlInfo("TestScript", 1, 1), str); Assert.assertEquals(1, e.getParameters().length); } {code} While the following test case passes correctly: {code:java} @Test public void testParameters() throws Exception { String str = "function(u) {}"; JexlEngine jexl = new JexlBuilder().create(); JexlScript e = jexl.createScript(str); Assert.assertEquals(1, e.getParameters().length); } {code} was (Author: dmitri_blinov): I've got a regression with recent changes. For some reason the script created with JexlInfo fails to report declared parameters and local variables. The following test case illustrates this {code:java} @Test public void testParameters() throws Exception { String str = "function(u) {}"; JexlEngine jexl = new JexlBuilder().create(); JexlScript e = jexl.createScript(new JexlInfo("TestScript", 1, 1), str); Assert.assertEquals(1, e.getParameters().length); } {code} > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16976371#comment-16976371 ] Dmitri Blinov edited comment on JEXL-307 at 11/18/19 9:04 AM: -- The problem is that by allowing lexical option to be dynamically enabled/disabled we are creating controversy that does not help in any way with initial intention of finding bugs. Consider the following, exaggerated and artificial, example {code:java} @Test public void testLexicalOption() throws Exception { JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).create(); JexlEvalContext ctxt = new JexlEvalContext(); JexlOptions options = ctxt.getEngineOptions(); ctxt.set("options", options); JexlScript script = jexl.createScript("{var x = 42;} options.lexical = false; x"); Object result = script.execute(ctxt); Assert.assertNull(result); } {code} What should we expect as a result here? Until {{options.lexical = false}} we were in lexical mode, so one might think that once the block finished no variables should be visible and what't more critical - have any value. By allowing to change the mode on the fly, we are asking for trouble... We may spend some more effort to try to fix this particular case, to allow lexical mode to coexist with non-lexical, but globally I think we should not mix the two. At least once we have parsed the script with lexical feature enabled, there is no point in allowing it to be disabled via options. was (Author: dmitri_blinov): The problem is that by allowing lexical option to be dynamically enabled/disabled we are creating controversy that does not help in any way with initial intention of finding bugs. Consider the following, exaggerated and artificial, example {code:java} @Test public void testLexicalOption() throws Exception { JexlEngine jexl = new JexlBuilder().strict(true).lexical(true).create(); JexlEvalContext ctxt = new JexlEvalContext(); JexlOptions options = ctxt.getEngineOptions(); ctxt.set("options", options); JexlScript script = jexl.createScript("{var x = 42;} options.lexical = false; x"); Object result = script.execute(ctxt); Assert.assertNull(result); } {code} What should we expect as a result here? Until {{options.lexical = false}} we were in lexical mode, so one might think that once the block finished no variables should be visible and what't more critical - have any value. By allowing to change the mode on the fly, we are asking for trouble... We may spend some more effort to try to fix this particular case, to allow lexical mode to coexist with non-lexical, but globally I think we should not mix the two. At least once we parsed the script with lexical feature enabled, there is no point in allowing it to be disabled via options. > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16971465#comment-16971465 ] Dmitri Blinov edited comment on JEXL-307 at 11/11/19 11:47 AM: --- Regarding Options API cleanup - what is the purpose of having lexical option both at context level and at parsing level? I mean its easy to get in trouble by, for example, parsing the script in non-lexical mode and later executing it with lexical option enabled. I haven't tested this mix, but sure there will be unexpected results... Should we better bind this to the script whether it was in lexical mode or not at parsing time? was (Author: dmitri_blinov): Regarding Options API cleanup - what is the purpose of having lexical option both at context level and at parsing level? I mean its easy to get in trouble by, for example parsing, the script in lon-lexical mode and later executing it with lexical option enabled. I haven't tested this mix, but sure there will be unexpected results... Should we better bind this to the script whether it was in lexical mode or not at parsing time? > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16960572#comment-16960572 ] Henri Biestro edited comment on JEXL-307 at 10/27/19 2:03 PM: -- Changeset: d15901734478efeac605d3dc55c4b25a479c28d4 Author: henrib Date: 2019-10-27 13:59 Message: JEXL-307: added lexical and lexical shade option; JEXL-307: added lexical feature, controlling var redefinition at parsing time; JEXL-307: refactored option (JexlOption) and added feature to deal with lexical scope; JEXL-307: refactored test code to use new option classes; JEXL-307: added lexical scope and frame handling interpreting scripts, lambdas, for-loops; JEXL-314: changed JexlArithmetic/Interpreter to handle NullOperand exception when needed Changes not visible through GitHub (yet): https://issues.apache.org/jira/browse/INFRA-19344 was (Author: henrib): Changeset: d15901734478efeac605d3dc55c4b25a479c28d4 Author:henrib Date: 2019-10-27 13:59 Message: JEXL-307: added lexical and lexical shade option; JEXL-307: added lexical feature, controlling var redefinition at parsing time; JEXL-307: refactored option (JexlOption) and added feature to deal with lexical scope; JEXL-307: refactored test code to use new option classes; JEXL-307: added lexical scope and frame handling interpreting scripts, lambdas, for-loops; JEXL-314: changed JexlArithmetic/Interpreter to handle NullOperand exception when needed > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16942085#comment-16942085 ] Dmitri Blinov edited comment on JEXL-307 at 10/2/19 8:24 AM: - If new feature, through configuration on engine level, or via provided script compilation options, will trigger java-like local variable visibility rules, instead of existing ones, it would be great step in right direction. This, however, IMO, should not influence context variables in any way. We should be allowed to freely assign to new context variables from any point. So, we can declare that, under new option, the following is correct - every variable should have visibility inside the block where it is defined. Loop variables are visible until the end of loop: {code:java} for (var i : items) {}; return i;{code} Thus the above code should raise exception - undefined variable. Also, we need to agree what to do with hoisted variables. My vision is that hoisted variables should be allowed to be redefined. If we can draw parallels with java, in java this is a valid code {code:java} final String var1 = "3456"; Object x = new Object() { public String toString() { String m = var1; String var1 = "2346"; return var1; } }; {code} I'm not sure about pragmas though. The pragmas are a little underdeveloped now. For example, I would change the grammar to allow pragmas to be allowed only at the beginning of the script. Now they can be specified anywere in the middle, inside *if* or *while* loop, which is misleading, as they are not executed anyway, and their meaning relates to the whole script, not to the particular part. Plus, the debugger now does not reproduce them in the generated source code, thus they are get lost. Placing pragmas strictly at the beginning would allow to solve this problem, and allow them to be used for specifying any parsing options. was (Author: dmitri_blinov): If new feature, through configuration on engine level, or via provided script compilation options, will trigger java-like local variable visibility rules, instead of existing ones, it would be great step in right direction. This, however, IMO, should not influence context variables in any way. We should be allowed to freely assign to new context variables from any point. So, we can declare that, under new option, the following is correct - every variable should have visibility inside the block where it is defined. Loop variables are visible until the end of loop: {code:java} for (var i : items) {}; return i;{code} Thus the above code should raise exception - undefined variable. Also, we need to agree what to do with hoisted variables. My vision is that hoisted variables should be treated like function argumens, in other words, they should not be allowed to be redefined. This would guarantee the evaluation integrity. I'm not sure about pragmas though. The pragmas are a little underdeveloped now. For example, I would change the grammar to allow pragmas to be allowed only at the beginning of the script. Now they can be specified anywere in the middle, inside *if* or *while* loop, which is misleading, as they are not executed anyway, and their meaning relates to the whole script, not to the particular part. Plus, the debugger now does not reproduce them in the generated source code, thus they are get lost. Placing pragmas strictly at the beginning would allow to solve this problem, and allow them to be used for specifying any parsing options. > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16941873#comment-16941873 ] Henri Biestro edited comment on JEXL-307 at 10/1/19 1:54 PM: - Of course, the behaviour wrt local variables / parameters is what you describe (besides your penultimate example which is not allowed for the same reason the 2nd is not, if or no-if or for or while). I'll restate we only have 2 scopes today; global variables (JexlContext) and local variables whose scope is the whole script/function/lambda after their point of declaration. Locals so far have the weak(er) Javascript-like 'var' semantic. The idea is to allow turning gracefully to a 'let'-like one (aka lexical scope) without adding yet another keyword. Pretty much the same rules Java or C apply wrt to local variable definition in this mode. The solution will *not* change any existing behaviour, current code under current configuration will run the same way. Setting the lexical feature - at JexlEngine construction time - and/or the lexical option - plus at script evaluation time - will trigger the new semantic on variable scopes. Using the option, it will be even possible to turn it on/off in the script itself through a pragma. This allows existing users dealing with huge scripts to easily control the pace of deploying this lexical semantic. was (Author: henrib): Of course, the behaviour wrt local variables / parameters is what you describe (besides your penultimate example which is not allowed for the same reason the 2nd is not, if or no-if or for or while). I'll restate we only have 2 scopes today; global variables (JexlContext) and local variables whose scope is the whole function/lambda after their point of declaration. Locals so far have the weak(er) Javascript-like 'var' semantic. The idea is to allow turning gracefully to a 'let'-like one (aka lexical scope) without adding yet another keyword. Pretty much the same rules Java or C apply wrt to local variable definition in this mode. The solution will *not* change any existing behaviour, current code under current configuration will run the same way. Setting the lexical feature - at JexlEngine construction time - and/or the lexical option - plus at script evaluation time - will trigger the new semantic on variable scopes. Using the option, it will be even possible to turn it on/off in the script itself through a pragma. This allows existing users dealing with huge scripts to easily control the pace of deploying this lexical semantic. > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code} > This may lead to potential errors with misspelled names and clashed > variables. Checking for already defined variable is a common feature of many > languages. This feature can be implemented in JEXL as an additional option of > JexlFeatures class, enabled by default, thus allowing compatibility with > existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16941028#comment-16941028 ] Henri Biestro edited comment on JEXL-307 at 9/30/19 3:28 PM: - This leads to a feature / option that implements a script *lexical scope*. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a *feature* (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an *option* (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}d = 169; {code} should fail if the global (Jexl) context does not declares 'd'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. {code}{ var c = 42; ...} c + 157; {code} should fail with reporting an undefined variable 'c'. So should: {code}{ var c = 42; ...} c = 157; {code} Since {code}var c = 157; { var c = 42; ...}{code} will fail due to variable redefinition, assuming 'c' is declared in the global context, it would seem logical that {code} c = 157; { var c = 42; ...}{code} should fail due to variable redefinition as well. was (Author: henrib): This leads to a feature / option that implements a script *lexical scope*. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a *feature* (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an *option* (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}{ var c = 42; ...} d = 169; {code} should fail if the context does not declares 'd'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. {code}{ var c = 42; ...} c + 157; {code} should fail with reporting an undefined variable 'c'. So should: {code}{ var c = 42; ...} c = 157; {code} > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code}. This may lead to potential errors with > misspelled and names and clashed variables. Checking for already defined > variable is a common feature of many languages. This feature can be > implemented in JEXL as an additional option of JexlFeatures class, enabled by > default, thus allowing compatibility with existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16941028#comment-16941028 ] Henri Biestro edited comment on JEXL-307 at 9/30/19 3:21 PM: - This leads to a feature / option that implements a script *lexical scope*. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a *feature* (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an *option* (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}{ var c = 42; ...} d = 169; {code} should fail if the context does not declares 'd'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. {code}{ var c = 42; ...} c + 157; {code} should fail with reporting an undefined variable 'c'. So should: {code}{ var c = 42; ...} c = 157; {code} was (Author: henrib): This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}{ var c = 42; ...} d = 169; {code} should fail if the context does not declares 'd'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. {code}{ var c = 42; ...} c + 157; {code} should fail with reporting an undefined variable 'c'. So should: {code}{ var c = 42; ...} c = 157; {code} > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code}. This may lead to potential errors with > misspelled and names and clashed variables. Checking for already defined > variable is a common feature of many languages. This feature can be > implemented in JEXL as an additional option of JexlFeatures class, enabled by > default, thus allowing compatibility with existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16941028#comment-16941028 ] Henri Biestro edited comment on JEXL-307 at 9/30/19 3:20 PM: - This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}{ var c = 42; ...} d = 169; {code} should fail if the context does not declares 'd'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. {code}{ var c = 42; ...} c + 157; {code} should fail with reporting an undefined variable 'c'. So should: {code}{ var c = 42; ...} c = 157; {code} was (Author: henrib): This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}{ var c = 42; ...} c = 169; {code} should fail if the context does not declares 'c'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code}. This may lead to potential errors with > misspelled and names and clashed variables. Checking for already defined > variable is a common feature of many languages. This feature can be > implemented in JEXL as an additional option of JexlFeatures class, enabled by > default, thus allowing compatibility with existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16941028#comment-16941028 ] Henri Biestro edited comment on JEXL-307 at 9/30/19 3:20 PM: - This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}{ var c = 42; ...} d = 169; {code} should fail if the context does not declares 'd'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. {code}{ var c = 42; ...} c + 157; {code} should fail with reporting an undefined variable 'c'. So should: {code}{ var c = 42; ...} c = 157; {code} was (Author: henrib): This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}{ var c = 42; ...} d = 169; {code} should fail if the context does not declares 'd'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. {code}{ var c = 42; ...} c + 157; {code} should fail with reporting an undefined variable 'c'. So should: {code}{ var c = 42; ...} c = 157; {code} > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code}. This may lead to potential errors with > misspelled and names and clashed variables. Checking for already defined > variable is a common feature of many languages. This feature can be > implemented in JEXL as an additional option of JexlFeatures class, enabled by > default, thus allowing compatibility with existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16941028#comment-16941028 ] Henri Biestro edited comment on JEXL-307 at 9/30/19 3:17 PM: - This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. {code}{ var c = 42; ...} c = 169; {code} should fail if the context does not declares 'c'. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. was (Author: henrib): This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code}. This may lead to potential errors with > misspelled and names and clashed variables. Checking for already defined > variable is a common feature of many languages. This feature can be > implemented in JEXL as an additional option of JexlFeatures class, enabled by > default, thus allowing compatibility with existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)
[jira] [Comment Edited] (JEXL-307) Variable redeclaration option
[ https://issues.apache.org/jira/browse/JEXL-307?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16941028#comment-16941028 ] Henri Biestro edited comment on JEXL-307 at 9/30/19 3:13 PM: - This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). To be consistent with the intent - avoid variable misnaming -, global variables can no longer be defined in this mode; they must be declared (aka JexlContext has() method returns true) first. This can only be detected at runtime. This also implies that after a variable/parameter is declared and outside of its definition scope, references to that variable will generate an 'undefined variable' error. The effect is that a local variable can no longer be confused with a global one. was (Author: henrib): This leads to a feature / option that implements a script lexical scope. The canonical illustration is the difference between the JavaScript 'var' and 'let' with respect to parameters and local variable definitions. As a feature (JexlFeature), this 'lexical' mode will fail parsing when a variable/parameter redefinition is attempted in the same scope; from the point of definition within a block/function, a variable can not be redefined. An an option (JexlOption), the same lexical rule applies but whether an exception is thrown or logged is subject to the exception handling rules in effect. This runtime behaviour should be easily turned on or off (driven though pragma for instance) so that large existing scripts libraries can be converted to the new semantic through managed evolution (ie one script at a time). > Variable redeclaration option > - > > Key: JEXL-307 > URL: https://issues.apache.org/jira/browse/JEXL-307 > Project: Commons JEXL > Issue Type: New Feature >Affects Versions: 3.1 >Reporter: Dmitri Blinov >Assignee: Henri Biestro >Priority: Minor > Fix For: 3.2 > > > As of now, JEXL allows a script writer to redeclare a local variable during > script evaluation. > {code:java} > var a = 1; var a = 2;{code}. This may lead to potential errors with > misspelled and names and clashed variables. Checking for already defined > variable is a common feature of many languages. This feature can be > implemented in JEXL as an additional option of JexlFeatures class, enabled by > default, thus allowing compatibility with existing code. -- This message was sent by Atlassian Jira (v8.3.4#803005)