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]