This is an automated email from the ASF dual-hosted git repository.

tzimanyi pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-drools.git


The following commit(s) were added to refs/heads/main by this push:
     new d7c038ef19 Fix forloop variables scoping for closures (#5537)
d7c038ef19 is described below

commit d7c038ef194829512ad160fdf8dd28435ccf2bed
Author: Matteo Mortari <[email protected]>
AuthorDate: Thu Oct 5 09:09:33 2023 +0200

    Fix forloop variables scoping for closures (#5537)
---
 .../org/kie/dmn/feel/codegen/feel11/CompiledFEELSupport.java     | 2 ++
 .../src/main/java/org/kie/dmn/feel/codegen/feel11/Functions.java | 2 +-
 .../main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java   | 9 +++++++++
 .../java/org/kie/dmn/feel/runtime/FEEL12ExtendedForLoopTest.java | 2 ++
 4 files changed, 14 insertions(+), 1 deletion(-)

diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompiledFEELSupport.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompiledFEELSupport.java
index 9761b6d673..99785c4508 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompiledFEELSupport.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/CompiledFEELSupport.java
@@ -262,6 +262,7 @@ public class CompiledFEELSupport {
                 while (ForExpressionNode.nextIteration(ctx, ictx)) {
                     Object result = expression.apply(ctx);
                     results.add(result);
+                    ctx.exitFrame(); // last i-th scope unrolled, see also 
ForExpressionNode.nextIteration(...)
                 }
                 return results;
             } catch (EndpointOfRangeNotOfNumberException e) {
@@ -278,6 +279,7 @@ public class CompiledFEELSupport {
             for (IterationContextCompiled icn : iterationContexts) {
                 ictx[i] = createQuantifiedExpressionIterationContext(ctx, icn);
                 if (i < iterationContexts.size() - 1 && 
ictx[i].hasNextValue()) {
+                    ctx.enterFrame(); // open loop scope frame, for every iter 
ctx, except last one as guarded by if clause above
                     ForExpressionNode.setValueIntoContext(ctx, ictx[i]);
                 }
                 i++;
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Functions.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Functions.java
index da0e1e1443..1bdae213f2 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Functions.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/codegen/feel11/Functions.java
@@ -79,7 +79,7 @@ public class Functions {
 
     public static DirectCompilerResult declaration(FunctionDefNode n, 
MethodCallExpr list, Expression fnBody) {
         LambdaExpr lambda = Expressions.lambda(fnBody);
-        String fnName = Constants.functionName(n.getBody().getText());
+        String fnName = Constants.functionName("FNBODY_" + 
n.getBody().getText());
         DirectCompilerResult r = DirectCompilerResult.of(
                 Functions.internal(list, new NameExpr(fnName)),
                 BuiltInType.FUNCTION);
diff --git 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java
 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java
index f588362a0e..d92fed9c19 100644
--- 
a/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java
+++ 
b/kie-dmn/kie-dmn-feel/src/main/java/org/kie/dmn/feel/lang/ast/ForExpressionNode.java
@@ -76,6 +76,7 @@ public class ForExpressionNode
             while ( nextIteration( ctx, ictx ) ) {
                 Object result = expression.evaluate( ctx );
                 results.add( result );
+                ctx.exitFrame(); // last i-th scope unrolled, see also 
ForExpressionNode.nextIteration(...)
             }
             return results;
         } catch (EndpointOfRangeNotOfNumberException e) {
@@ -90,9 +91,16 @@ public class ForExpressionNode
         int i = ictx.length-1;
         while ( i >= 0 && i < ictx.length ) {
             if ( ictx[i].hasNextValue() ) {
+                ctx.enterFrame(); // on first iter, open last scope frame; or 
new ones when prev unrolled
                 setValueIntoContext( ctx, ictx[i] );
                 i++;
             } else {
+                if ( i > 0 ) {
+                    // end of iter loop for this i-th scope; i-th scope is 
always unrolled as part of the 
+                    // for-loop cycle, so here must unroll the _prev_ scope;
+                    // the if-guard for this code block makes sure NOT to 
unroll bottom one.
+                    ctx.exitFrame();         
+                }
                 i--;
             }
         }
@@ -114,6 +122,7 @@ public class ForExpressionNode
         for ( IterationContextNode icn : iterationContexts ) {
             ictx[i] = createQuantifiedExpressionIterationContext( ctx, icn );
             if( i < iterationContexts.size()-1 && ictx[i].hasNextValue() ) {
+                ctx.enterFrame(); // open loop scope frame, for every iter 
ctx, except last one as guarded by if clause above
                 setValueIntoContext( ctx, ictx[i] );
             }
             i++;
diff --git 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/FEEL12ExtendedForLoopTest.java
 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/FEEL12ExtendedForLoopTest.java
index 5c7c37852f..fb06b3174f 100644
--- 
a/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/FEEL12ExtendedForLoopTest.java
+++ 
b/kie-dmn/kie-dmn-feel/src/test/java/org/kie/dmn/feel/runtime/FEEL12ExtendedForLoopTest.java
@@ -23,6 +23,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.stream.Collectors;
+import java.util.stream.IntStream;
 import java.util.stream.Stream;
 
 import org.junit.runners.Parameterized;
@@ -50,6 +51,7 @@ public class FEEL12ExtendedForLoopTest extends BaseFEELTest {
             {"{ a: 1, b : 3, c : for x in a+2..b-2 return x+1}", 
mapOf(entry("a", BigDecimal.valueOf(1)), entry("b", BigDecimal.valueOf(3)),  
entry("c", Stream.of(3, 2, 1 ).map(x -> BigDecimal.valueOf(x + 1 ) 
).collect(Collectors.toList() )) ), null},
             {"{ a: \"ciao\", b : 3, c : for x in a..b return x+1}", 
mapOf(entry("a", "ciao"), entry("b", BigDecimal.valueOf(3)),  entry("c", 
null)), FEELEvent.Severity.ERROR},
             {"for i in 0..10 return if i = 0 then 1 else i * partial[-1]", 
Stream.of(1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800 
).map(BigDecimal::valueOf).collect(Collectors.toList() ), null},
+            {"{xs: for i in 1..10 return function() i, ys: for f in xs return 
f()}.ys", IntStream.range(1, 
11).boxed().map(BigDecimal::valueOf).collect(Collectors.toList()), null},
 
         };
         return addAdditionalParameters(cases, false);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to