Skip to content

Commit 38fe141

Browse files
l46kokcopybara-github
authored andcommitted
Document variable dependency behavior in InliningOptimizer
PiperOrigin-RevId: 869919231
1 parent f748e2d commit 38fe141

File tree

2 files changed

+74
-2
lines changed

2 files changed

+74
-2
lines changed

optimizer/src/main/java/dev/cel/optimizer/optimizers/InliningOptimizer.java

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import dev.cel.optimizer.AstMutator;
3939
import dev.cel.optimizer.CelAstOptimizer;
4040
import java.util.ArrayList;
41+
import java.util.List;
4142
import java.util.NoSuchElementException;
4243
import java.util.Optional;
4344
import java.util.stream.Stream;
@@ -51,21 +52,53 @@ public final class InliningOptimizer implements CelAstOptimizer {
5152
private final ImmutableList<InlineVariable> inlineVariables;
5253
private final AstMutator astMutator;
5354

55+
/**
56+
* Creates a new {@code InliningOptimizer} with one or more {@link InlineVariable}s.
57+
*
58+
* <p>Note that the variables to be inlined can be a dependency to one other based on the supplied
59+
* ordering. This allows for recursive inlining where a replacement value might itself contain
60+
* variables that need to be inlined.
61+
*
62+
* <p>For example, given a source expression {@code "a + b"} and inline variables in the following
63+
* order:
64+
*
65+
* <ul>
66+
* <li>{@code {a: b, b: 2}}, result: {@code 2 + 2}.
67+
* <li>{@code {b: 2, a: b}}, result: {@code b + 2}.
68+
* </ul>
69+
*/
5470
public static InliningOptimizer newInstance(InlineVariable... inlineVariables) {
5571
return newInstance(ImmutableList.copyOf(inlineVariables));
5672
}
5773

58-
public static InliningOptimizer newInstance(Iterable<InlineVariable> inlineVariables) {
74+
/**
75+
* Creates a new {@code InliningOptimizer}.
76+
*
77+
* @see #newInstance(InlineVariable...)
78+
*/
79+
public static InliningOptimizer newInstance(List<InlineVariable> inlineVariables) {
5980
return newInstance(InliningOptions.newBuilder().build(), ImmutableList.copyOf(inlineVariables));
6081
}
6182

83+
/**
84+
* Creates a new {@code InliningOptimizer}.
85+
*
86+
* @see #newInstance(InlineVariable...)
87+
* @param options {@link InliningOptions} to customize the inlining behavior with.
88+
*/
6289
public static InliningOptimizer newInstance(
6390
InliningOptions options, InlineVariable... inlineVariables) {
6491
return newInstance(options, ImmutableList.copyOf(inlineVariables));
6592
}
6693

94+
/**
95+
* Creates a new {@code InliningOptimizer}.
96+
*
97+
* @see #newInstance(InlineVariable...)
98+
* @param options {@link InliningOptions} to customize the inlining behavior with.
99+
*/
67100
public static InliningOptimizer newInstance(
68-
InliningOptions options, Iterable<InlineVariable> inlineVariables) {
101+
InliningOptions options, List<InlineVariable> inlineVariables) {
69102
return new InliningOptimizer(options, ImmutableList.copyOf(inlineVariables));
70103
}
71104

optimizer/src/test/java/dev/cel/optimizer/optimizers/InliningOptimizerTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,4 +268,43 @@ public void inline_then_cse() throws Exception {
268268
"cel.@block([[1, 2, 3].map(@it:0:0, @it:0:0 * 2)], "
269269
+ "(@index0.size() != 0) ? (@index0.map(@it:1:0, @it:1:0 * 2)[0]) : 42)");
270270
}
271+
272+
@Test
273+
public void allowInliningDependentVariables_inOrder_dependentVariablesInlined() throws Exception {
274+
String source = "int_var + dyn_var";
275+
CelAbstractSyntaxTree astToInline = CEL.compile(source).getAst();
276+
277+
CelOptimizer optimizer =
278+
CelOptimizerFactory.standardCelOptimizerBuilder(CEL)
279+
.addAstOptimizers(
280+
InliningOptimizer.newInstance(
281+
InlineVariable.of("int_var", CEL.compile("dyn_var").getAst()),
282+
InlineVariable.of("dyn_var", CEL.compile("2").getAst())))
283+
.build();
284+
285+
CelAbstractSyntaxTree optimized = optimizer.optimize(astToInline);
286+
287+
String unparsed = CelUnparserFactory.newUnparser().unparse(optimized);
288+
assertThat(unparsed).isEqualTo("2 + 2");
289+
}
290+
291+
@Test
292+
public void allowInliningDependentVariables_reverseOrder_inliningIsIndependent()
293+
throws Exception {
294+
String source = "int_var + dyn_var";
295+
CelAbstractSyntaxTree astToInline = CEL.compile(source).getAst();
296+
297+
CelOptimizer optimizer =
298+
CelOptimizerFactory.standardCelOptimizerBuilder(CEL)
299+
.addAstOptimizers(
300+
InliningOptimizer.newInstance(
301+
InlineVariable.of("dyn_var", CEL.compile("2").getAst()),
302+
InlineVariable.of("int_var", CEL.compile("dyn_var").getAst())))
303+
.build();
304+
305+
CelAbstractSyntaxTree optimized = optimizer.optimize(astToInline);
306+
307+
String unparsed = CelUnparserFactory.newUnparser().unparse(optimized);
308+
assertThat(unparsed).isEqualTo("dyn_var + 2");
309+
}
271310
}

0 commit comments

Comments
 (0)