Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import dev.cel.optimizer.AstMutator;
import dev.cel.optimizer.CelAstOptimizer;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.stream.Stream;
Expand All @@ -51,21 +52,53 @@ public final class InliningOptimizer implements CelAstOptimizer {
private final ImmutableList<InlineVariable> inlineVariables;
private final AstMutator astMutator;

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

public static InliningOptimizer newInstance(Iterable<InlineVariable> inlineVariables) {
/**
* Creates a new {@code InliningOptimizer}.
*
* @see #newInstance(InlineVariable...)
*/
public static InliningOptimizer newInstance(List<InlineVariable> inlineVariables) {
return newInstance(InliningOptions.newBuilder().build(), ImmutableList.copyOf(inlineVariables));
}

/**
* Creates a new {@code InliningOptimizer}.
*
* @see #newInstance(InlineVariable...)
* @param options {@link InliningOptions} to customize the inlining behavior with.
*/
public static InliningOptimizer newInstance(
InliningOptions options, InlineVariable... inlineVariables) {
return newInstance(options, ImmutableList.copyOf(inlineVariables));
}

/**
* Creates a new {@code InliningOptimizer}.
*
* @see #newInstance(InlineVariable...)
* @param options {@link InliningOptions} to customize the inlining behavior with.
*/
public static InliningOptimizer newInstance(
InliningOptions options, Iterable<InlineVariable> inlineVariables) {
InliningOptions options, List<InlineVariable> inlineVariables) {
return new InliningOptimizer(options, ImmutableList.copyOf(inlineVariables));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,4 +268,43 @@ public void inline_then_cse() throws Exception {
"cel.@block([[1, 2, 3].map(@it:0:0, @it:0:0 * 2)], "
+ "(@index0.size() != 0) ? (@index0.map(@it:1:0, @it:1:0 * 2)[0]) : 42)");
}

@Test
public void allowInliningDependentVariables_inOrder_dependentVariablesInlined() throws Exception {
String source = "int_var + dyn_var";
CelAbstractSyntaxTree astToInline = CEL.compile(source).getAst();

CelOptimizer optimizer =
CelOptimizerFactory.standardCelOptimizerBuilder(CEL)
.addAstOptimizers(
InliningOptimizer.newInstance(
InlineVariable.of("int_var", CEL.compile("dyn_var").getAst()),
InlineVariable.of("dyn_var", CEL.compile("2").getAst())))
.build();

CelAbstractSyntaxTree optimized = optimizer.optimize(astToInline);

String unparsed = CelUnparserFactory.newUnparser().unparse(optimized);
assertThat(unparsed).isEqualTo("2 + 2");
}

@Test
public void allowInliningDependentVariables_reverseOrder_inliningIsIndependent()
throws Exception {
String source = "int_var + dyn_var";
CelAbstractSyntaxTree astToInline = CEL.compile(source).getAst();

CelOptimizer optimizer =
CelOptimizerFactory.standardCelOptimizerBuilder(CEL)
.addAstOptimizers(
InliningOptimizer.newInstance(
InlineVariable.of("dyn_var", CEL.compile("2").getAst()),
InlineVariable.of("int_var", CEL.compile("dyn_var").getAst())))
.build();

CelAbstractSyntaxTree optimized = optimizer.optimize(astToInline);

String unparsed = CelUnparserFactory.newUnparser().unparse(optimized);
assertThat(unparsed).isEqualTo("dyn_var + 2");
}
}
Loading