From f3d6f7d2603ec83aa79081dcaf477dc63bc3651a Mon Sep 17 00:00:00 2001 From: Jonathan Tatum Date: Wed, 18 Dec 2024 11:04:02 -0800 Subject: [PATCH] Draft: default enable updated accumulator variable. PiperOrigin-RevId: 707607511 --- checker/src/test/resources/mapExpr.baseline | 28 +- .../src/test/resources/mapFilterExpr.baseline | 24 +- .../resources/namespacedFunctions.baseline | 14 +- .../src/test/resources/quantifiers.baseline | 26 +- checker/src/test/resources/types.baseline | 6 +- .../main/java/dev/cel/common/CelOptions.java | 13 + .../cel/common/ast/CelExprFormatterTest.java | 8 +- .../cel/common/ast/CelExprVisitorTest.java | 2 +- .../CelNavigableExprVisitorTest.java | 32 +- .../dev/cel/parser/CelMacroExprFactory.java | 3 + .../java/dev/cel/parser/CelStandardMacro.java | 66 +++-- .../src/main/java/dev/cel/parser/Parser.java | 21 +- .../cel/parser/CelMacroExprFactoryTest.java | 5 + .../parser/CelParserParameterizedTest.java | 21 ++ parser/src/test/resources/parser.baseline | 160 +++++----- .../resources/parser_updatedAccuVar.baseline | 280 ++++++++++++++++++ 16 files changed, 535 insertions(+), 174 deletions(-) create mode 100644 parser/src/test/resources/parser_updatedAccuVar.baseline diff --git a/checker/src/test/resources/mapExpr.baseline b/checker/src/test/resources/mapExpr.baseline index 4ddb9061..2f7964bc 100644 --- a/checker/src/test/resources/mapExpr.baseline +++ b/checker/src/test/resources/mapExpr.baseline @@ -9,14 +9,14 @@ __comprehension__( // Target x~cel.expr.conformance.proto3.TestAllTypes^x.repeated_int64~list(int), // Accumulator - __result__, + @result, // Init []~list(double), // LoopCondition true~bool, // LoopStep _+_( - __result__~list(double)^__result__, + @result~list(double)^@result, [ double( x~int^x @@ -24,7 +24,7 @@ __comprehension__( ]~list(double) )~list(double)^add_list, // Result - __result__~list(double)^__result__)~list(double) + @result~list(double)^@result)~list(double) Source: [].map(x, [].map(y, x in y && y in x)) declare x { @@ -32,8 +32,8 @@ declare x { } =====> ERROR: test_location:1:33: found no matching overload for '@in' applied to '(list(%elem0), %elem0)' (candidates: (%A7, list(%A7)),(%A8, map(%A8, %B9))) - | [].map(x, [].map(y, x in y && y in x)) - | ................................^ + | [].map(x, [].map(y, x in y && y in x)) + | ................................^ Source: [{}.map(c,c,c)]+[{}.map(c,c,c)] declare x { @@ -48,7 +48,7 @@ _+_( // Target {}~map(bool, dyn), // Accumulator - __result__, + @result, // Init []~list(bool), // LoopCondition @@ -57,15 +57,15 @@ _+_( _?_:_( c~bool^c, _+_( - __result__~list(bool)^__result__, + @result~list(bool)^@result, [ c~bool^c ]~list(bool) )~list(bool)^add_list, - __result__~list(bool)^__result__ + @result~list(bool)^@result )~list(bool)^conditional, // Result - __result__~list(bool)^__result__)~list(bool) + @result~list(bool)^@result)~list(bool) ]~list(list(bool)), [ __comprehension__( @@ -74,7 +74,7 @@ _+_( // Target {}~map(bool, dyn), // Accumulator - __result__, + @result, // Init []~list(bool), // LoopCondition @@ -83,14 +83,14 @@ _+_( _?_:_( c~bool^c, _+_( - __result__~list(bool)^__result__, + @result~list(bool)^@result, [ c~bool^c ]~list(bool) )~list(bool)^add_list, - __result__~list(bool)^__result__ + @result~list(bool)^@result )~list(bool)^conditional, // Result - __result__~list(bool)^__result__)~list(bool) + @result~list(bool)^@result)~list(bool) ]~list(list(bool)) -)~list(list(bool))^add_list +)~list(list(bool))^add_list \ No newline at end of file diff --git a/checker/src/test/resources/mapFilterExpr.baseline b/checker/src/test/resources/mapFilterExpr.baseline index 1a9fd224..1a66e493 100644 --- a/checker/src/test/resources/mapFilterExpr.baseline +++ b/checker/src/test/resources/mapFilterExpr.baseline @@ -9,7 +9,7 @@ __comprehension__( // Target x~cel.expr.conformance.proto3.TestAllTypes^x.repeated_int64~list(int), // Accumulator - __result__, + @result, // Init []~list(double), // LoopCondition @@ -21,17 +21,17 @@ __comprehension__( 0~int )~bool^greater_int64, _+_( - __result__~list(double)^__result__, + @result~list(double)^@result, [ double( x~int^x )~double^int64_to_double ]~list(double) )~list(double)^add_list, - __result__~list(double)^__result__ + @result~list(double)^@result )~list(double)^conditional, // Result - __result__~list(double)^__result__)~list(double) + @result~list(double)^@result)~list(double) Source: lists.filter(x, x > 1.5) declare x { @@ -47,7 +47,7 @@ __comprehension__( // Target lists~dyn^lists, // Accumulator - __result__, + @result, // Init []~list(dyn), // LoopCondition @@ -59,15 +59,15 @@ __comprehension__( 1.5~double )~bool^greater_double|greater_int64_double|greater_uint64_double, _+_( - __result__~list(dyn)^__result__, + @result~list(dyn)^@result, [ x~dyn^x ]~list(dyn) )~list(dyn)^add_list, - __result__~list(dyn)^__result__ + @result~list(dyn)^@result )~list(dyn)^conditional, // Result - __result__~list(dyn)^__result__)~list(dyn) + @result~list(dyn)^@result)~list(dyn) Source: args.user["myextension"].customAttributes.filter(x, x.name == "hobbies") declare x { @@ -89,7 +89,7 @@ __comprehension__( "myextension"~string )~dyn^index_map.customAttributes~dyn, // Accumulator - __result__, + @result, // Init []~list(dyn), // LoopCondition @@ -101,12 +101,12 @@ __comprehension__( "hobbies"~string )~bool^equals, _+_( - __result__~list(dyn)^__result__, + @result~list(dyn)^@result, [ x~dyn^x ]~list(dyn) )~list(dyn)^add_list, - __result__~list(dyn)^__result__ + @result~list(dyn)^@result )~list(dyn)^conditional, // Result - __result__~list(dyn)^__result__)~list(dyn) + @result~list(dyn)^@result)~list(dyn) \ No newline at end of file diff --git a/checker/src/test/resources/namespacedFunctions.baseline b/checker/src/test/resources/namespacedFunctions.baseline index 449ea511..b6ace0e3 100644 --- a/checker/src/test/resources/namespacedFunctions.baseline +++ b/checker/src/test/resources/namespacedFunctions.baseline @@ -84,14 +84,14 @@ __comprehension__( )~int^ns_func_overload ]~list(int), // Accumulator - __result__, + @result, // Init []~list(int), // LoopCondition true~bool, // LoopStep _+_( - __result__~list(int)^__result__, + @result~list(int)^@result, [ _*_( x~int^x, @@ -100,7 +100,7 @@ __comprehension__( ]~list(int) )~list(int)^add_list, // Result - __result__~list(int)^__result__)~list(int) + @result~list(int)^@result)~list(int) Source: [1, 2].map(x, x * ns.func('test')) declare ns.func { @@ -119,14 +119,14 @@ __comprehension__( 2~int ]~list(int), // Accumulator - __result__, + @result, // Init []~list(int), // LoopCondition true~bool, // LoopStep _+_( - __result__~list(int)^__result__, + @result~list(int)^@result, [ _*_( x~int^x, @@ -137,7 +137,7 @@ __comprehension__( ]~list(int) )~list(int)^add_list, // Result - __result__~list(int)^__result__)~list(int) + @result~list(int)^@result)~list(int) Source: func('hello') declare ns.func { @@ -165,4 +165,4 @@ ns.func( ns.func( "test"~string )~int^ns_func_overload -)~int^ns_member_overload +)~int^ns_member_overload \ No newline at end of file diff --git a/checker/src/test/resources/quantifiers.baseline b/checker/src/test/resources/quantifiers.baseline index 2573ca27..3f204a6f 100644 --- a/checker/src/test/resources/quantifiers.baseline +++ b/checker/src/test/resources/quantifiers.baseline @@ -11,48 +11,48 @@ _&&_( // Target x~cel.expr.conformance.proto3.TestAllTypes^x.repeated_int64~list(int), // Accumulator - __result__, + @result, // Init true~bool, // LoopCondition @not_strictly_false( - __result__~bool^__result__ + @result~bool^@result )~bool^not_strictly_false, // LoopStep _&&_( - __result__~bool^__result__, + @result~bool^@result, _>_( e~int^e, 0~int )~bool^greater_int64 )~bool^logical_and, // Result - __result__~bool^__result__)~bool, + @result~bool^@result)~bool, __comprehension__( // Variable e, // Target x~cel.expr.conformance.proto3.TestAllTypes^x.repeated_int64~list(int), // Accumulator - __result__, + @result, // Init false~bool, // LoopCondition @not_strictly_false( !_( - __result__~bool^__result__ + @result~bool^@result )~bool^logical_not )~bool^not_strictly_false, // LoopStep _||_( - __result__~bool^__result__, + @result~bool^@result, _<_( e~int^e, 0~int )~bool^less_int64 )~bool^logical_or, // Result - __result__~bool^__result__)~bool + @result~bool^@result)~bool )~bool^logical_and, __comprehension__( // Variable @@ -60,7 +60,7 @@ _&&_( // Target x~cel.expr.conformance.proto3.TestAllTypes^x.repeated_int64~list(int), // Accumulator - __result__, + @result, // Init 0~int, // LoopCondition @@ -72,14 +72,14 @@ _&&_( 0~int )~bool^equals, _+_( - __result__~int^__result__, + @result~int^@result, 1~int )~int^add_int64, - __result__~int^__result__ + @result~int^@result )~int^conditional, // Result _==_( - __result__~int^__result__, + @result~int^@result, 1~int )~bool^equals)~bool -)~bool^logical_and +)~bool^logical_and \ No newline at end of file diff --git a/checker/src/test/resources/types.baseline b/checker/src/test/resources/types.baseline index 61f3f442..939e0ed9 100644 --- a/checker/src/test/resources/types.baseline +++ b/checker/src/test/resources/types.baseline @@ -27,14 +27,14 @@ __comprehension__( // Target {}~map(dyn, dyn), // Accumulator - __result__, + @result, // Init []~list(list(dyn)), // LoopCondition true~bool, // LoopStep _+_( - __result__~list(list(dyn))^__result__, + @result~list(list(dyn))^@result, [ [ c~dyn^c, @@ -45,4 +45,4 @@ __comprehension__( ]~list(list(dyn)) )~list(list(dyn))^add_list, // Result - __result__~list(list(dyn))^__result__)~list(list(dyn)) + @result~list(list(dyn))^@result)~list(list(dyn)) \ No newline at end of file diff --git a/common/src/main/java/dev/cel/common/CelOptions.java b/common/src/main/java/dev/cel/common/CelOptions.java index 5c49936d..317ae0a7 100644 --- a/common/src/main/java/dev/cel/common/CelOptions.java +++ b/common/src/main/java/dev/cel/common/CelOptions.java @@ -67,6 +67,8 @@ public enum ProtoUnsetFieldOptions { public abstract boolean retainUnbalancedLogicalExpressions(); + public abstract boolean enableHiddenAccumulatorVar(); + // Type-Checker related options public abstract boolean enableCompileTimeOverloadResolution(); @@ -188,6 +190,7 @@ public static Builder newBuilder() { .populateMacroCalls(false) .retainRepeatedUnaryOperators(false) .retainUnbalancedLogicalExpressions(false) + .enableHiddenAccumulatorVar(true) // Type-Checker options .enableCompileTimeOverloadResolution(false) .enableHomogeneousLiterals(false) @@ -319,6 +322,16 @@ public abstract static class Builder { */ public abstract Builder retainUnbalancedLogicalExpressions(boolean value); + /** + * Enable the use of a hidden accumulator variable name. + * + *

This is a temporary option to transition to using an internal identifier for the + * accumulator variable used by builtin comprehension macros. When enabled, parses result in a + * semantically equivalent AST, but with a different accumulator variable that can't be directly + * referenced in the source expression. + */ + public abstract Builder enableHiddenAccumulatorVar(boolean value); + // Type-Checker related options /** diff --git a/common/src/test/java/dev/cel/common/ast/CelExprFormatterTest.java b/common/src/test/java/dev/cel/common/ast/CelExprFormatterTest.java index 002d9d2a..6fe8f83e 100644 --- a/common/src/test/java/dev/cel/common/ast/CelExprFormatterTest.java +++ b/common/src/test/java/dev/cel/common/ast/CelExprFormatterTest.java @@ -291,7 +291,7 @@ public void comprehension() throws Exception { + " }\n" + " }\n" + " }\n" - + " accu_var: __result__\n" + + " accu_var: @result\n" + " accu_init: {\n" + " CONSTANT [10] { value: false }\n" + " }\n" @@ -303,7 +303,7 @@ public void comprehension() throws Exception { + " function: !_\n" + " args: {\n" + " IDENT [11] {\n" - + " name: __result__\n" + + " name: @result\n" + " }\n" + " }\n" + " }\n" @@ -315,7 +315,7 @@ public void comprehension() throws Exception { + " function: _||_\n" + " args: {\n" + " IDENT [14] {\n" - + " name: __result__\n" + + " name: @result\n" + " }\n" + " CALL [8] {\n" + " function: _>_\n" @@ -331,7 +331,7 @@ public void comprehension() throws Exception { + " }\n" + " result: {\n" + " IDENT [16] {\n" - + " name: __result__\n" + + " name: @result\n" + " }\n" + " }\n" + "}"); diff --git a/common/src/test/java/dev/cel/common/ast/CelExprVisitorTest.java b/common/src/test/java/dev/cel/common/ast/CelExprVisitorTest.java index ef1188ee..104a2872 100644 --- a/common/src/test/java/dev/cel/common/ast/CelExprVisitorTest.java +++ b/common/src/test/java/dev/cel/common/ast/CelExprVisitorTest.java @@ -343,7 +343,7 @@ public void visitComprehension() throws Exception { assertThat(comprehension.loopStep().call().args()).hasSize(2); assertThat(visitedReference.list().get().elements()).isEqualTo(iterRangeElements); assertThat(visitedReference.identifier()) - .hasValue(CelIdent.newBuilder().setName("__result__").build()); + .hasValue(CelIdent.newBuilder().setName("@result").build()); assertThat(visitedReference.arguments()).hasSize(10); } diff --git a/common/src/test/java/dev/cel/common/navigation/CelNavigableExprVisitorTest.java b/common/src/test/java/dev/cel/common/navigation/CelNavigableExprVisitorTest.java index 2dddb515..e1cc88f8 100644 --- a/common/src/test/java/dev/cel/common/navigation/CelNavigableExprVisitorTest.java +++ b/common/src/test/java/dev/cel/common/navigation/CelNavigableExprVisitorTest.java @@ -825,7 +825,7 @@ public void comprehension_preOrder_allNodesReturned() throws Exception { CelExpr iterRangeConstExpr = CelExpr.ofConstant(2, CelConstant.ofValue(true)); CelExpr iterRange = CelExpr.ofList(1, ImmutableList.of(iterRangeConstExpr), ImmutableList.of()); CelExpr accuInit = CelExpr.ofConstant(6, CelConstant.ofValue(false)); - CelExpr loopConditionIdentExpr = CelExpr.ofIdent(7, "__result__"); + CelExpr loopConditionIdentExpr = CelExpr.ofIdent(7, "@result"); CelExpr loopConditionCallExpr = CelExpr.ofCall( 8, @@ -838,7 +838,7 @@ public void comprehension_preOrder_allNodesReturned() throws Exception { Optional.empty(), Operator.NOT_STRICTLY_FALSE.getFunction(), ImmutableList.of(loopConditionCallExpr)); - CelExpr loopStepResultExpr = CelExpr.ofIdent(10, "__result__"); + CelExpr loopStepResultExpr = CelExpr.ofIdent(10, "@result"); CelExpr loopStepVarExpr = CelExpr.ofIdent(5, "i"); CelExpr loopStep = CelExpr.ofCall( @@ -846,10 +846,10 @@ public void comprehension_preOrder_allNodesReturned() throws Exception { Optional.empty(), Operator.LOGICAL_OR.getFunction(), ImmutableList.of(loopStepResultExpr, loopStepVarExpr)); - CelExpr result = CelExpr.ofIdent(12, "__result__"); + CelExpr result = CelExpr.ofIdent(12, "@result"); CelExpr comprehension = CelExpr.ofComprehension( - 13, "i", iterRange, "__result__", accuInit, loopCondition, loopStep, result); + 13, "i", iterRange, "@result", accuInit, loopCondition, loopStep, result); assertThat(allNodes).hasSize(11); assertThat(allNodes) .containsExactly( @@ -886,7 +886,7 @@ public void comprehension_postOrder_allNodesReturned() throws Exception { CelExpr iterRangeConstExpr = CelExpr.ofConstant(2, CelConstant.ofValue(true)); CelExpr iterRange = CelExpr.ofList(1, ImmutableList.of(iterRangeConstExpr), ImmutableList.of()); CelExpr accuInit = CelExpr.ofConstant(6, CelConstant.ofValue(false)); - CelExpr loopConditionIdentExpr = CelExpr.ofIdent(7, "__result__"); + CelExpr loopConditionIdentExpr = CelExpr.ofIdent(7, "@result"); CelExpr loopConditionCallExpr = CelExpr.ofCall( 8, @@ -899,7 +899,7 @@ public void comprehension_postOrder_allNodesReturned() throws Exception { Optional.empty(), Operator.NOT_STRICTLY_FALSE.getFunction(), ImmutableList.of(loopConditionCallExpr)); - CelExpr loopStepResultExpr = CelExpr.ofIdent(10, "__result__"); + CelExpr loopStepResultExpr = CelExpr.ofIdent(10, "@result"); CelExpr loopStepVarExpr = CelExpr.ofIdent(5, "i"); CelExpr loopStep = CelExpr.ofCall( @@ -907,10 +907,10 @@ public void comprehension_postOrder_allNodesReturned() throws Exception { Optional.empty(), Operator.LOGICAL_OR.getFunction(), ImmutableList.of(loopStepResultExpr, loopStepVarExpr)); - CelExpr result = CelExpr.ofIdent(12, "__result__"); + CelExpr result = CelExpr.ofIdent(12, "@result"); CelExpr comprehension = CelExpr.ofComprehension( - 13, "i", iterRange, "__result__", accuInit, loopCondition, loopStep, result); + 13, "i", iterRange, "@result", accuInit, loopCondition, loopStep, result); assertThat(allNodes).hasSize(11); assertThat(allNodes) .containsExactly( @@ -1018,7 +1018,7 @@ public void comprehension_allNodes_parentsPopulated() throws Exception { CelExpr iterRangeConstExpr = CelExpr.ofConstant(2, CelConstant.ofValue(true)); CelExpr iterRange = CelExpr.ofList(1, ImmutableList.of(iterRangeConstExpr), ImmutableList.of()); CelExpr accuInit = CelExpr.ofConstant(6, CelConstant.ofValue(false)); - CelExpr loopConditionIdentExpr = CelExpr.ofIdent(7, "__result__"); + CelExpr loopConditionIdentExpr = CelExpr.ofIdent(7, "@result"); CelExpr loopConditionCallExpr = CelExpr.ofCall( 8, @@ -1031,7 +1031,7 @@ public void comprehension_allNodes_parentsPopulated() throws Exception { Optional.empty(), Operator.NOT_STRICTLY_FALSE.getFunction(), ImmutableList.of(loopConditionCallExpr)); - CelExpr loopStepResultExpr = CelExpr.ofIdent(10, "__result__"); + CelExpr loopStepResultExpr = CelExpr.ofIdent(10, "@result"); CelExpr loopStepVarExpr = CelExpr.ofIdent(5, "i"); CelExpr loopStep = CelExpr.ofCall( @@ -1039,10 +1039,10 @@ public void comprehension_allNodes_parentsPopulated() throws Exception { Optional.empty(), Operator.LOGICAL_OR.getFunction(), ImmutableList.of(loopStepResultExpr, loopStepVarExpr)); - CelExpr result = CelExpr.ofIdent(12, "__result__"); + CelExpr result = CelExpr.ofIdent(12, "@result"); CelExpr comprehension = CelExpr.ofComprehension( - 13, "i", iterRange, "__result__", accuInit, loopCondition, loopStep, result); + 13, "i", iterRange, "@result", accuInit, loopCondition, loopStep, result); assertThat(allNodes).hasSize(11); assertThat(allNodes.get(0).parent()).isEmpty(); // comprehension assertThat(allNodes.get(1).parent().get().expr()).isEqualTo(comprehension); // iter_range @@ -1081,7 +1081,7 @@ public void comprehension_filterComprehension_allNodesReturned() throws Exceptio CelExpr iterRangeConstExpr = CelExpr.ofConstant(2, CelConstant.ofValue(true)); CelExpr iterRange = CelExpr.ofList(1, ImmutableList.of(iterRangeConstExpr), ImmutableList.of()); CelExpr accuInit = CelExpr.ofConstant(6, CelConstant.ofValue(false)); - CelExpr loopConditionIdentExpr = CelExpr.ofIdent(7, "__result__"); + CelExpr loopConditionIdentExpr = CelExpr.ofIdent(7, "@result"); CelExpr loopConditionCallExpr = CelExpr.ofCall( 8, @@ -1094,7 +1094,7 @@ public void comprehension_filterComprehension_allNodesReturned() throws Exceptio Optional.empty(), Operator.NOT_STRICTLY_FALSE.getFunction(), ImmutableList.of(loopConditionCallExpr)); - CelExpr loopStepResultExpr = CelExpr.ofIdent(10, "__result__"); + CelExpr loopStepResultExpr = CelExpr.ofIdent(10, "@result"); CelExpr loopStepVarExpr = CelExpr.ofIdent(5, "i"); CelExpr loopStep = CelExpr.ofCall( @@ -1102,10 +1102,10 @@ public void comprehension_filterComprehension_allNodesReturned() throws Exceptio Optional.empty(), Operator.LOGICAL_OR.getFunction(), ImmutableList.of(loopStepResultExpr, loopStepVarExpr)); - CelExpr result = CelExpr.ofIdent(12, "__result__"); + CelExpr result = CelExpr.ofIdent(12, "@result"); CelExpr comprehension = CelExpr.ofComprehension( - 13, "i", iterRange, "__result__", accuInit, loopCondition, loopStep, result); + 13, "i", iterRange, "@result", accuInit, loopCondition, loopStep, result); assertThat(allNodes).hasSize(1); assertThat(allNodes.get(0).expr()).isEqualTo(comprehension); } diff --git a/parser/src/main/java/dev/cel/parser/CelMacroExprFactory.java b/parser/src/main/java/dev/cel/parser/CelMacroExprFactory.java index d7c917c2..2363bd51 100644 --- a/parser/src/main/java/dev/cel/parser/CelMacroExprFactory.java +++ b/parser/src/main/java/dev/cel/parser/CelMacroExprFactory.java @@ -51,6 +51,9 @@ public final CelExpr reportError(String message) { /** Reports a {@link CelIssue} and returns a sentinel {@link CelExpr} that indicates an error. */ public abstract CelExpr reportError(CelIssue error); + /** Returns the default accumulator variable name used by macros implementing comprehensions. */ + public abstract String getAccumulatorVarName(); + /** Retrieves the source location for the given {@link CelExpr} ID. */ public final CelSourceLocation getSourceLocation(CelExpr expr) { return getSourceLocation(expr.id()); diff --git a/parser/src/main/java/dev/cel/parser/CelStandardMacro.java b/parser/src/main/java/dev/cel/parser/CelStandardMacro.java index 3ea54f9e..0dce8b29 100644 --- a/parser/src/main/java/dev/cel/parser/CelStandardMacro.java +++ b/parser/src/main/java/dev/cel/parser/CelStandardMacro.java @@ -78,8 +78,6 @@ public enum CelStandardMacro { public static final ImmutableSet STANDARD_MACROS = ImmutableSet.of(HAS, ALL, EXISTS, EXISTS_ONE, MAP, MAP_FILTER, FILTER); - private static final String ACCUMULATOR_VAR = "__result__"; - private final CelMacro macro; CelStandardMacro(CelMacro macro) { @@ -123,14 +121,23 @@ private static Optional expandAllMacro( CelExpr accuInit = exprFactory.newBoolLiteral(true); CelExpr condition = exprFactory.newGlobalCall( - Operator.NOT_STRICTLY_FALSE.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR)); + Operator.NOT_STRICTLY_FALSE.getFunction(), + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName())); CelExpr step = exprFactory.newGlobalCall( - Operator.LOGICAL_AND.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR), arg1); - CelExpr result = exprFactory.newIdentifier(ACCUMULATOR_VAR); + Operator.LOGICAL_AND.getFunction(), + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()), + arg1); + CelExpr result = exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()); return Optional.of( exprFactory.fold( - arg0.ident().name(), target, ACCUMULATOR_VAR, accuInit, condition, step, result)); + arg0.ident().name(), + target, + exprFactory.getAccumulatorVarName(), + accuInit, + condition, + step, + result)); } // CelMacroExpander implementation for CEL's exists() macro. @@ -149,14 +156,23 @@ private static Optional expandExistsMacro( exprFactory.newGlobalCall( Operator.NOT_STRICTLY_FALSE.getFunction(), exprFactory.newGlobalCall( - Operator.LOGICAL_NOT.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR))); + Operator.LOGICAL_NOT.getFunction(), + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()))); CelExpr step = exprFactory.newGlobalCall( - Operator.LOGICAL_OR.getFunction(), exprFactory.newIdentifier(ACCUMULATOR_VAR), arg1); - CelExpr result = exprFactory.newIdentifier(ACCUMULATOR_VAR); + Operator.LOGICAL_OR.getFunction(), + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()), + arg1); + CelExpr result = exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()); return Optional.of( exprFactory.fold( - arg0.ident().name(), target, ACCUMULATOR_VAR, accuInit, condition, step, result)); + arg0.ident().name(), + target, + exprFactory.getAccumulatorVarName(), + accuInit, + condition, + step, + result)); } // CelMacroExpander implementation for CEL's exists_one() macro. @@ -178,17 +194,23 @@ private static Optional expandExistsOneMacro( arg1, exprFactory.newGlobalCall( Operator.ADD.getFunction(), - exprFactory.newIdentifier(ACCUMULATOR_VAR), + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()), exprFactory.newIntLiteral(1)), - exprFactory.newIdentifier(ACCUMULATOR_VAR)); + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName())); CelExpr result = exprFactory.newGlobalCall( Operator.EQUALS.getFunction(), - exprFactory.newIdentifier(ACCUMULATOR_VAR), + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()), exprFactory.newIntLiteral(1)); return Optional.of( exprFactory.fold( - arg0.ident().name(), target, ACCUMULATOR_VAR, accuInit, condition, step, result)); + arg0.ident().name(), + target, + exprFactory.getAccumulatorVarName(), + accuInit, + condition, + step, + result)); } // CelMacroExpander implementation for CEL's map() macro. @@ -218,7 +240,7 @@ private static Optional expandMapMacro( CelExpr step = exprFactory.newGlobalCall( Operator.ADD.getFunction(), - exprFactory.newIdentifier(ACCUMULATOR_VAR), + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()), exprFactory.newList(arg1)); if (arg2 != null) { step = @@ -226,17 +248,17 @@ private static Optional expandMapMacro( Operator.CONDITIONAL.getFunction(), arg2, step, - exprFactory.newIdentifier(ACCUMULATOR_VAR)); + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName())); } return Optional.of( exprFactory.fold( arg0.ident().name(), target, - ACCUMULATOR_VAR, + exprFactory.getAccumulatorVarName(), accuInit, condition, step, - exprFactory.newIdentifier(ACCUMULATOR_VAR))); + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()))); } // CelMacroExpander implementation for CEL's filter() macro. @@ -255,23 +277,23 @@ private static Optional expandFilterMacro( CelExpr step = exprFactory.newGlobalCall( Operator.ADD.getFunction(), - exprFactory.newIdentifier(ACCUMULATOR_VAR), + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()), exprFactory.newList(arg0)); step = exprFactory.newGlobalCall( Operator.CONDITIONAL.getFunction(), arg1, step, - exprFactory.newIdentifier(ACCUMULATOR_VAR)); + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName())); return Optional.of( exprFactory.fold( arg0.ident().name(), target, - ACCUMULATOR_VAR, + exprFactory.getAccumulatorVarName(), accuInit, condition, step, - exprFactory.newIdentifier(ACCUMULATOR_VAR))); + exprFactory.newIdentifier(exprFactory.getAccumulatorVarName()))); } private static CelExpr reportArgumentError(CelMacroExprFactory exprFactory, CelExpr argument) { diff --git a/parser/src/main/java/dev/cel/parser/Parser.java b/parser/src/main/java/dev/cel/parser/Parser.java index 61caff01..52ba6db3 100644 --- a/parser/src/main/java/dev/cel/parser/Parser.java +++ b/parser/src/main/java/dev/cel/parser/Parser.java @@ -125,6 +125,8 @@ final class Parser extends CELBaseVisitor { "var", "void", "while"); + private static final String ACCUMULATOR_NAME = "__result__"; + private static final String HIDDEN_ACCUMULATOR_NAME = "@result"; static CelValidationResult parse(CelParserImpl parser, CelSource source, CelOptions options) { if (source.getContent().size() > options.maxExpressionCodePointSize()) { @@ -142,7 +144,11 @@ static CelValidationResult parse(CelParserImpl parser, CelSource source, CelOpti CELParser antlrParser = new CELParser(new CommonTokenStream(antlrLexer)); CelSource.Builder sourceInfo = source.toBuilder(); sourceInfo.setDescription(source.getDescription()); - ExprFactory exprFactory = new ExprFactory(antlrParser, sourceInfo); + ExprFactory exprFactory = + new ExprFactory( + antlrParser, + sourceInfo, + options.enableHiddenAccumulatorVar() ? HIDDEN_ACCUMULATOR_NAME : ACCUMULATOR_NAME); Parser parserImpl = new Parser(parser, options, sourceInfo, exprFactory); ErrorListener errorListener = new ErrorListener(exprFactory); antlrLexer.removeErrorListeners(); @@ -1033,12 +1039,17 @@ private static final class ExprFactory extends CelMacroExprFactory { private final CelSource.Builder sourceInfo; private final ArrayList issues; private final ArrayDeque positions; + private final String accumulatorVarName; - private ExprFactory(org.antlr.v4.runtime.Parser recognizer, CelSource.Builder sourceInfo) { + private ExprFactory( + org.antlr.v4.runtime.Parser recognizer, + CelSource.Builder sourceInfo, + String accumulatorVarName) { this.recognizer = recognizer; this.sourceInfo = sourceInfo; this.issues = new ArrayList<>(); this.positions = new ArrayDeque<>(1); // Currently this usually contains at most 1 position. + this.accumulatorVarName = accumulatorVarName; } // Implementation of CelExprFactory. @@ -1062,6 +1073,11 @@ public CelExpr reportError(CelIssue error) { return ERROR; } + @Override + public String getAccumulatorVarName() { + return accumulatorVarName; + } + // Internal methods used by the parser but not part of the public API. @FormatMethod @CanIgnoreReturnValue @@ -1079,6 +1095,7 @@ private CelExpr reportError(ParserRuleContext context, String message) { private CelExpr reportError(Token token, String message) { return reportError(CelIssue.formatError(getLocation(token), message)); } + // Implementation of CelExprFactory. diff --git a/parser/src/test/java/dev/cel/parser/CelMacroExprFactoryTest.java b/parser/src/test/java/dev/cel/parser/CelMacroExprFactoryTest.java index 4d110b79..daac056d 100644 --- a/parser/src/test/java/dev/cel/parser/CelMacroExprFactoryTest.java +++ b/parser/src/test/java/dev/cel/parser/CelMacroExprFactoryTest.java @@ -61,6 +61,11 @@ public CelExpr reportError(CelIssue issue) { return CelExpr.newBuilder().setId(nextExprId()).setConstant(Constants.ERROR).build(); } + @Override + public String getAccumulatorVarName() { + return "__result__"; + } + @Override protected CelSourceLocation getSourceLocation(long exprId) { return CelSourceLocation.NONE; diff --git a/parser/src/test/java/dev/cel/parser/CelParserParameterizedTest.java b/parser/src/test/java/dev/cel/parser/CelParserParameterizedTest.java index a091cc60..073b548b 100644 --- a/parser/src/test/java/dev/cel/parser/CelParserParameterizedTest.java +++ b/parser/src/test/java/dev/cel/parser/CelParserParameterizedTest.java @@ -72,6 +72,16 @@ public final class CelParserParameterizedTest extends BaselineTestCase { .setOptions(CelOptions.current().populateMacroCalls(true).build()) .build(); + private static final CelParser PARSER_WITH_UPDATED_ACCU_VAR = + PARSER + .toParserBuilder() + .setOptions( + CelOptions.current() + .populateMacroCalls(true) + .enableHiddenAccumulatorVar(true) + .build()) + .build(); + @Test public void parser() { runTest(PARSER, "x * 2"); @@ -193,6 +203,17 @@ public void parser() { "while"); } + @Test + public void parser_updatedAccuVar() { + runTest(PARSER_WITH_UPDATED_ACCU_VAR, "x * 2"); + runTest(PARSER_WITH_UPDATED_ACCU_VAR, "has(m.f)"); + runTest(PARSER_WITH_UPDATED_ACCU_VAR, "m.exists_one(v, f)"); + runTest(PARSER_WITH_UPDATED_ACCU_VAR, "m.all(v, f)"); + runTest(PARSER_WITH_UPDATED_ACCU_VAR, "m.map(v, f)"); + runTest(PARSER_WITH_UPDATED_ACCU_VAR, "m.map(v, p, f)"); + runTest(PARSER_WITH_UPDATED_ACCU_VAR, "m.filter(v, p)"); + } + @Test public void parser_errors() { runTest(PARSER, "*@a | b"); diff --git a/parser/src/test/resources/parser.baseline b/parser/src/test/resources/parser.baseline index 455cf24d..5a25ffd2 100644 --- a/parser/src/test/resources/parser.baseline +++ b/parser/src/test/resources/parser.baseline @@ -306,7 +306,7 @@ L: _||_( b^#3[1,5]# )^#2[1,2]# -I: a || b || c || d || e || f +I: a || b || c || d || e || f =====> P: _||_( _||_( @@ -735,7 +735,7 @@ P: __comprehension__( // Target m^#1:Expr.Ident#, // Accumulator - __result__, + @result, // Init 0^#5:int64#, // LoopCondition @@ -744,14 +744,14 @@ P: __comprehension__( _?_:_( f^#4:Expr.Ident#, _+_( - __result__^#7:Expr.Ident#, + @result^#7:Expr.Ident#, 1^#8:int64# )^#9:Expr.Call#, - __result__^#10:Expr.Ident# + @result^#10:Expr.Ident# )^#11:Expr.Call#, // Result _==_( - __result__^#12:Expr.Ident#, + @result^#12:Expr.Ident#, 1^#13:int64# )^#14:Expr.Call#)^#15:Expr.Comprehension# L: __comprehension__( @@ -760,7 +760,7 @@ L: __comprehension__( // Target m^#1[1,0]#, // Accumulator - __result__, + @result, // Init 0^#5[1,12]#, // LoopCondition @@ -769,14 +769,14 @@ L: __comprehension__( _?_:_( f^#4[1,16]#, _+_( - __result__^#7[1,12]#, + @result^#7[1,12]#, 1^#8[1,12]# )^#9[1,12]#, - __result__^#10[1,12]# + @result^#10[1,12]# )^#11[1,12]#, // Result _==_( - __result__^#12[1,12]#, + @result^#12[1,12]#, 1^#13[1,12]# )^#14[1,12]#)^#15[1,12]# M: m^#1:Expr.Ident#.exists_one( @@ -792,40 +792,40 @@ P: __comprehension__( // Target m^#1:Expr.Ident#, // Accumulator - __result__, + @result, // Init []^#5:Expr.CreateList#, // LoopCondition true^#6:bool#, // LoopStep _+_( - __result__^#7:Expr.Ident#, + @result^#7:Expr.Ident#, [ f^#4:Expr.Ident# ]^#8:Expr.CreateList# )^#9:Expr.Call#, // Result - __result__^#10:Expr.Ident#)^#11:Expr.Comprehension# + @result^#10:Expr.Ident#)^#11:Expr.Comprehension# L: __comprehension__( // Variable v, // Target m^#1[1,0]#, // Accumulator - __result__, + @result, // Init []^#5[1,5]#, // LoopCondition true^#6[1,5]#, // LoopStep _+_( - __result__^#7[1,5]#, + @result^#7[1,5]#, [ f^#4[1,9]# ]^#8[1,5]# )^#9[1,5]#, // Result - __result__^#10[1,5]#)^#11[1,5]# + @result^#10[1,5]#)^#11[1,5]# M: m^#1:Expr.Ident#.map( v^#3:Expr.Ident#, f^#4:Expr.Ident# @@ -839,7 +839,7 @@ P: __comprehension__( // Target m^#1:Expr.Ident#, // Accumulator - __result__, + @result, // Init []^#6:Expr.CreateList#, // LoopCondition @@ -848,22 +848,22 @@ P: __comprehension__( _?_:_( p^#4:Expr.Ident#, _+_( - __result__^#8:Expr.Ident#, + @result^#8:Expr.Ident#, [ f^#5:Expr.Ident# ]^#9:Expr.CreateList# )^#10:Expr.Call#, - __result__^#11:Expr.Ident# + @result^#11:Expr.Ident# )^#12:Expr.Call#, // Result - __result__^#13:Expr.Ident#)^#14:Expr.Comprehension# + @result^#13:Expr.Ident#)^#14:Expr.Comprehension# L: __comprehension__( // Variable v, // Target m^#1[1,0]#, // Accumulator - __result__, + @result, // Init []^#6[1,5]#, // LoopCondition @@ -872,15 +872,15 @@ L: __comprehension__( _?_:_( p^#4[1,9]#, _+_( - __result__^#8[1,5]#, + @result^#8[1,5]#, [ f^#5[1,12]# ]^#9[1,5]# )^#10[1,5]#, - __result__^#11[1,5]# + @result^#11[1,5]# )^#12[1,5]#, // Result - __result__^#13[1,5]#)^#14[1,5]# + @result^#13[1,5]#)^#14[1,5]# M: m^#1:Expr.Ident#.map( v^#3:Expr.Ident#, p^#4:Expr.Ident#, @@ -895,7 +895,7 @@ P: __comprehension__( // Target m^#1:Expr.Ident#, // Accumulator - __result__, + @result, // Init []^#5:Expr.CreateList#, // LoopCondition @@ -904,22 +904,22 @@ P: __comprehension__( _?_:_( p^#4:Expr.Ident#, _+_( - __result__^#7:Expr.Ident#, + @result^#7:Expr.Ident#, [ v^#3:Expr.Ident# ]^#8:Expr.CreateList# )^#9:Expr.Call#, - __result__^#10:Expr.Ident# + @result^#10:Expr.Ident# )^#11:Expr.Call#, // Result - __result__^#12:Expr.Ident#)^#13:Expr.Comprehension# + @result^#12:Expr.Ident#)^#13:Expr.Comprehension# L: __comprehension__( // Variable v, // Target m^#1[1,0]#, // Accumulator - __result__, + @result, // Init []^#5[1,8]#, // LoopCondition @@ -928,15 +928,15 @@ L: __comprehension__( _?_:_( p^#4[1,12]#, _+_( - __result__^#7[1,8]#, + @result^#7[1,8]#, [ v^#3[1,9]# ]^#8[1,8]# )^#9[1,8]#, - __result__^#10[1,8]# + @result^#10[1,8]# )^#11[1,8]#, // Result - __result__^#12[1,8]#)^#13[1,8]# + @result^#12[1,8]#)^#13[1,8]# M: m^#1:Expr.Ident#.filter( v^#3:Expr.Ident#, p^#4:Expr.Ident# @@ -1205,7 +1205,7 @@ P: __comprehension__( // Target x^#1:Expr.Ident#, // Accumulator - __result__, + @result, // Init []^#19:Expr.CreateList#, // LoopCondition @@ -1218,7 +1218,7 @@ P: __comprehension__( // Target y^#4:Expr.Ident#, // Accumulator - __result__, + @result, // Init []^#10:Expr.CreateList#, // LoopCondition @@ -1230,32 +1230,32 @@ P: __comprehension__( 0^#9:int64# )^#8:Expr.Call#, _+_( - __result__^#12:Expr.Ident#, + @result^#12:Expr.Ident#, [ z^#6:Expr.Ident# ]^#13:Expr.CreateList# )^#14:Expr.Call#, - __result__^#15:Expr.Ident# + @result^#15:Expr.Ident# )^#16:Expr.Call#, // Result - __result__^#17:Expr.Ident#)^#18:Expr.Comprehension#, + @result^#17:Expr.Ident#)^#18:Expr.Comprehension#, _+_( - __result__^#21:Expr.Ident#, + @result^#21:Expr.Ident#, [ y^#3:Expr.Ident# ]^#22:Expr.CreateList# )^#23:Expr.Call#, - __result__^#24:Expr.Ident# + @result^#24:Expr.Ident# )^#25:Expr.Call#, // Result - __result__^#26:Expr.Ident#)^#27:Expr.Comprehension# + @result^#26:Expr.Ident#)^#27:Expr.Comprehension# L: __comprehension__( // Variable y, // Target x^#1[1,0]#, // Accumulator - __result__, + @result, // Init []^#19[1,8]#, // LoopCondition @@ -1268,7 +1268,7 @@ L: __comprehension__( // Target y^#4[1,12]#, // Accumulator - __result__, + @result, // Init []^#10[1,20]#, // LoopCondition @@ -1280,25 +1280,25 @@ L: __comprehension__( 0^#9[1,28]# )^#8[1,26]#, _+_( - __result__^#12[1,20]#, + @result^#12[1,20]#, [ z^#6[1,21]# ]^#13[1,20]# )^#14[1,20]#, - __result__^#15[1,20]# + @result^#15[1,20]# )^#16[1,20]#, // Result - __result__^#17[1,20]#)^#18[1,20]#, + @result^#17[1,20]#)^#18[1,20]#, _+_( - __result__^#21[1,8]#, + @result^#21[1,8]#, [ y^#3[1,9]# ]^#22[1,8]# )^#23[1,8]#, - __result__^#24[1,8]# + @result^#24[1,8]# )^#25[1,8]#, // Result - __result__^#26[1,8]#)^#27[1,8]# + @result^#26[1,8]#)^#27[1,8]# M: x^#1:Expr.Ident#.filter( y^#3:Expr.Ident#, ^#18:filter# @@ -1319,7 +1319,7 @@ P: __comprehension__( // Target a^#2:Expr.Ident#.b~test-only~^#4:Expr.Select#, // Accumulator - __result__, + @result, // Init []^#8:Expr.CreateList#, // LoopCondition @@ -1328,22 +1328,22 @@ P: __comprehension__( _?_:_( c^#7:Expr.Ident#, _+_( - __result__^#10:Expr.Ident#, + @result^#10:Expr.Ident#, [ c^#6:Expr.Ident# ]^#11:Expr.CreateList# )^#12:Expr.Call#, - __result__^#13:Expr.Ident# + @result^#13:Expr.Ident# )^#14:Expr.Call#, // Result - __result__^#15:Expr.Ident#)^#16:Expr.Comprehension# + @result^#15:Expr.Ident#)^#16:Expr.Comprehension# L: __comprehension__( // Variable c, // Target a^#2[1,4]#.b~test-only~^#4[1,3]#, // Accumulator - __result__, + @result, // Init []^#8[1,15]#, // LoopCondition @@ -1352,15 +1352,15 @@ L: __comprehension__( _?_:_( c^#7[1,19]#, _+_( - __result__^#10[1,15]#, + @result^#10[1,15]#, [ c^#6[1,16]# ]^#11[1,15]# )^#12[1,15]#, - __result__^#13[1,15]# + @result^#13[1,15]# )^#14[1,15]#, // Result - __result__^#15[1,15]#)^#16[1,15]# + @result^#15[1,15]#)^#16[1,15]# M: ^#4:has#.filter( c^#6:Expr.Ident#, c^#7:Expr.Ident# @@ -1377,7 +1377,7 @@ P: __comprehension__( // Target x^#1:Expr.Ident#, // Accumulator - __result__, + @result, // Init []^#35:Expr.CreateList#, // LoopCondition @@ -1391,62 +1391,62 @@ P: __comprehension__( // Target y^#4:Expr.Ident#, // Accumulator - __result__, + @result, // Init false^#11:bool#, // LoopCondition @not_strictly_false( !_( - __result__^#12:Expr.Ident# + @result^#12:Expr.Ident# )^#13:Expr.Call# )^#14:Expr.Call#, // LoopStep _||_( - __result__^#15:Expr.Ident#, + @result^#15:Expr.Ident#, z^#8:Expr.Ident#.a~test-only~^#10:Expr.Select# )^#16:Expr.Call#, // Result - __result__^#17:Expr.Ident#)^#18:Expr.Comprehension#, + @result^#17:Expr.Ident#)^#18:Expr.Comprehension#, __comprehension__( // Variable z, // Target y^#20:Expr.Ident#, // Accumulator - __result__, + @result, // Init false^#27:bool#, // LoopCondition @not_strictly_false( !_( - __result__^#28:Expr.Ident# + @result^#28:Expr.Ident# )^#29:Expr.Call# )^#30:Expr.Call#, // LoopStep _||_( - __result__^#31:Expr.Ident#, + @result^#31:Expr.Ident#, z^#24:Expr.Ident#.b~test-only~^#26:Expr.Select# )^#32:Expr.Call#, // Result - __result__^#33:Expr.Ident#)^#34:Expr.Comprehension# + @result^#33:Expr.Ident#)^#34:Expr.Comprehension# )^#19:Expr.Call#, _+_( - __result__^#37:Expr.Ident#, + @result^#37:Expr.Ident#, [ y^#3:Expr.Ident# ]^#38:Expr.CreateList# )^#39:Expr.Call#, - __result__^#40:Expr.Ident# + @result^#40:Expr.Ident# )^#41:Expr.Call#, // Result - __result__^#42:Expr.Ident#)^#43:Expr.Comprehension# + @result^#42:Expr.Ident#)^#43:Expr.Comprehension# L: __comprehension__( // Variable y, // Target x^#1[1,0]#, // Accumulator - __result__, + @result, // Init []^#35[1,8]#, // LoopCondition @@ -1460,55 +1460,55 @@ L: __comprehension__( // Target y^#4[1,12]#, // Accumulator - __result__, + @result, // Init false^#11[1,20]#, // LoopCondition @not_strictly_false( !_( - __result__^#12[1,20]# + @result^#12[1,20]# )^#13[1,20]# )^#14[1,20]#, // LoopStep _||_( - __result__^#15[1,20]#, + @result^#15[1,20]#, z^#8[1,28]#.a~test-only~^#10[1,27]# )^#16[1,20]#, // Result - __result__^#17[1,20]#)^#18[1,20]#, + @result^#17[1,20]#)^#18[1,20]#, __comprehension__( // Variable z, // Target y^#20[1,37]#, // Accumulator - __result__, + @result, // Init false^#27[1,45]#, // LoopCondition @not_strictly_false( !_( - __result__^#28[1,45]# + @result^#28[1,45]# )^#29[1,45]# )^#30[1,45]#, // LoopStep _||_( - __result__^#31[1,45]#, + @result^#31[1,45]#, z^#24[1,53]#.b~test-only~^#26[1,52]# )^#32[1,45]#, // Result - __result__^#33[1,45]#)^#34[1,45]# + @result^#33[1,45]#)^#34[1,45]# )^#19[1,34]#, _+_( - __result__^#37[1,8]#, + @result^#37[1,8]#, [ y^#3[1,9]# ]^#38[1,8]# )^#39[1,8]#, - __result__^#40[1,8]# + @result^#40[1,8]# )^#41[1,8]#, // Result - __result__^#42[1,8]#)^#43[1,8]# + @result^#42[1,8]#)^#43[1,8]# M: x^#1:Expr.Ident#.filter( y^#3:Expr.Ident#, _&&_( @@ -1622,4 +1622,4 @@ L: [ I: while =====> P: while^#1:Expr.Ident# -L: while^#1[1,0]# +L: while^#1[1,0]# \ No newline at end of file diff --git a/parser/src/test/resources/parser_updatedAccuVar.baseline b/parser/src/test/resources/parser_updatedAccuVar.baseline new file mode 100644 index 00000000..e2d198fc --- /dev/null +++ b/parser/src/test/resources/parser_updatedAccuVar.baseline @@ -0,0 +1,280 @@ +I: x * 2 +=====> +P: _*_( + x^#1:Expr.Ident#, + 2^#3:int64# +)^#2:Expr.Call# +L: _*_( + x^#1[1,0]#, + 2^#3[1,4]# +)^#2[1,2]# + +I: has(m.f) +=====> +P: m^#2:Expr.Ident#.f~test-only~^#4:Expr.Select# +L: m^#2[1,4]#.f~test-only~^#4[1,3]# +M: has( + m^#2:Expr.Ident#.f^#3:Expr.Select# +)^#0:Expr.Call# + +I: m.exists_one(v, f) +=====> +P: __comprehension__( + // Variable + v, + // Target + m^#1:Expr.Ident#, + // Accumulator + @result, + // Init + 0^#5:int64#, + // LoopCondition + true^#6:bool#, + // LoopStep + _?_:_( + f^#4:Expr.Ident#, + _+_( + @result^#7:Expr.Ident#, + 1^#8:int64# + )^#9:Expr.Call#, + @result^#10:Expr.Ident# + )^#11:Expr.Call#, + // Result + _==_( + @result^#12:Expr.Ident#, + 1^#13:int64# + )^#14:Expr.Call#)^#15:Expr.Comprehension# +L: __comprehension__( + // Variable + v, + // Target + m^#1[1,0]#, + // Accumulator + @result, + // Init + 0^#5[1,12]#, + // LoopCondition + true^#6[1,12]#, + // LoopStep + _?_:_( + f^#4[1,16]#, + _+_( + @result^#7[1,12]#, + 1^#8[1,12]# + )^#9[1,12]#, + @result^#10[1,12]# + )^#11[1,12]#, + // Result + _==_( + @result^#12[1,12]#, + 1^#13[1,12]# + )^#14[1,12]#)^#15[1,12]# +M: m^#1:Expr.Ident#.exists_one( + v^#3:Expr.Ident#, + f^#4:Expr.Ident# +)^#0:Expr.Call# + +I: m.all(v, f) +=====> +P: __comprehension__( + // Variable + v, + // Target + m^#1:Expr.Ident#, + // Accumulator + @result, + // Init + true^#5:bool#, + // LoopCondition + @not_strictly_false( + @result^#6:Expr.Ident# + )^#7:Expr.Call#, + // LoopStep + _&&_( + @result^#8:Expr.Ident#, + f^#4:Expr.Ident# + )^#9:Expr.Call#, + // Result + @result^#10:Expr.Ident#)^#11:Expr.Comprehension# +L: __comprehension__( + // Variable + v, + // Target + m^#1[1,0]#, + // Accumulator + @result, + // Init + true^#5[1,5]#, + // LoopCondition + @not_strictly_false( + @result^#6[1,5]# + )^#7[1,5]#, + // LoopStep + _&&_( + @result^#8[1,5]#, + f^#4[1,9]# + )^#9[1,5]#, + // Result + @result^#10[1,5]#)^#11[1,5]# +M: m^#1:Expr.Ident#.all( + v^#3:Expr.Ident#, + f^#4:Expr.Ident# +)^#0:Expr.Call# + +I: m.map(v, f) +=====> +P: __comprehension__( + // Variable + v, + // Target + m^#1:Expr.Ident#, + // Accumulator + @result, + // Init + []^#5:Expr.CreateList#, + // LoopCondition + true^#6:bool#, + // LoopStep + _+_( + @result^#7:Expr.Ident#, + [ + f^#4:Expr.Ident# + ]^#8:Expr.CreateList# + )^#9:Expr.Call#, + // Result + @result^#10:Expr.Ident#)^#11:Expr.Comprehension# +L: __comprehension__( + // Variable + v, + // Target + m^#1[1,0]#, + // Accumulator + @result, + // Init + []^#5[1,5]#, + // LoopCondition + true^#6[1,5]#, + // LoopStep + _+_( + @result^#7[1,5]#, + [ + f^#4[1,9]# + ]^#8[1,5]# + )^#9[1,5]#, + // Result + @result^#10[1,5]#)^#11[1,5]# +M: m^#1:Expr.Ident#.map( + v^#3:Expr.Ident#, + f^#4:Expr.Ident# +)^#0:Expr.Call# + +I: m.map(v, p, f) +=====> +P: __comprehension__( + // Variable + v, + // Target + m^#1:Expr.Ident#, + // Accumulator + @result, + // Init + []^#6:Expr.CreateList#, + // LoopCondition + true^#7:bool#, + // LoopStep + _?_:_( + p^#4:Expr.Ident#, + _+_( + @result^#8:Expr.Ident#, + [ + f^#5:Expr.Ident# + ]^#9:Expr.CreateList# + )^#10:Expr.Call#, + @result^#11:Expr.Ident# + )^#12:Expr.Call#, + // Result + @result^#13:Expr.Ident#)^#14:Expr.Comprehension# +L: __comprehension__( + // Variable + v, + // Target + m^#1[1,0]#, + // Accumulator + @result, + // Init + []^#6[1,5]#, + // LoopCondition + true^#7[1,5]#, + // LoopStep + _?_:_( + p^#4[1,9]#, + _+_( + @result^#8[1,5]#, + [ + f^#5[1,12]# + ]^#9[1,5]# + )^#10[1,5]#, + @result^#11[1,5]# + )^#12[1,5]#, + // Result + @result^#13[1,5]#)^#14[1,5]# +M: m^#1:Expr.Ident#.map( + v^#3:Expr.Ident#, + p^#4:Expr.Ident#, + f^#5:Expr.Ident# +)^#0:Expr.Call# + +I: m.filter(v, p) +=====> +P: __comprehension__( + // Variable + v, + // Target + m^#1:Expr.Ident#, + // Accumulator + @result, + // Init + []^#5:Expr.CreateList#, + // LoopCondition + true^#6:bool#, + // LoopStep + _?_:_( + p^#4:Expr.Ident#, + _+_( + @result^#7:Expr.Ident#, + [ + v^#3:Expr.Ident# + ]^#8:Expr.CreateList# + )^#9:Expr.Call#, + @result^#10:Expr.Ident# + )^#11:Expr.Call#, + // Result + @result^#12:Expr.Ident#)^#13:Expr.Comprehension# +L: __comprehension__( + // Variable + v, + // Target + m^#1[1,0]#, + // Accumulator + @result, + // Init + []^#5[1,8]#, + // LoopCondition + true^#6[1,8]#, + // LoopStep + _?_:_( + p^#4[1,12]#, + _+_( + @result^#7[1,8]#, + [ + v^#3[1,9]# + ]^#8[1,8]# + )^#9[1,8]#, + @result^#10[1,8]# + )^#11[1,8]#, + // Result + @result^#12[1,8]#)^#13[1,8]# +M: m^#1:Expr.Ident#.filter( + v^#3:Expr.Ident#, + p^#4:Expr.Ident# +)^#0:Expr.Call# \ No newline at end of file