Add tests for constant expressions.
diff --git a/src/test/java/net/hydromatic/linq4j/test/DeterministicTest.java b/src/test/java/net/hydromatic/linq4j/test/DeterministicTest.java
index bda6599..ab4b3f9 100644
--- a/src/test/java/net/hydromatic/linq4j/test/DeterministicTest.java
+++ b/src/test/java/net/hydromatic/linq4j/test/DeterministicTest.java
@@ -24,6 +24,7 @@
import org.junit.Test;
+import java.lang.reflect.Method;
import java.math.BigInteger;
import java.util.Collections;
import java.util.concurrent.Callable;
@@ -66,6 +67,58 @@
}
}
+ private boolean isAtomic(Expression e) {
+ /** Subclass to make a protected method public. */
+ class MyDeterministicCodeOptimizer extends DeterministicCodeOptimizer {
+ public MyDeterministicCodeOptimizer() {
+ super(ClassDeclarationFinder.create());
+ }
+
+ @Override public boolean isConstant(Expression expression) {
+ return super.isConstant(expression);
+ }
+ }
+ return new MyDeterministicCodeOptimizer().isConstant(e);
+ }
+
+ private static Method getMethod(Class<?> thisClass, String methodName,
+ Class<?>... paramClasses) {
+ try {
+ return thisClass.getMethod(methodName, paramClasses);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private boolean isConstant(Expression e) {
+ Expression e2 =
+ e.accept(
+ new DeterministicCodeOptimizer(ClassDeclarationFinder.create()));
+ return !e.equals(e2);
+ }
+
+ @Test public void testConstantIsConstant() {
+ // Small expressions are atomic.
+ assertThat(isAtomic(Expressions.constant(0)), is(true));
+ assertThat(isAtomic(Expressions.constant("xxx")), is(true));
+ assertThat(isAtomic(Expressions.constant(null)), is(true));
+
+ Expression e =
+ Expressions.call(getMethod(Integer.class, "valueOf", int.class),
+ Expressions.constant(-100));
+ assertThat(isAtomic(e), is(false));
+ assertThat(isConstant(e), is(true));
+
+ e = Expressions.call(
+ Integer.class, "valueOf", Expressions.constant(0));
+ assertThat(isAtomic(e), is(false));
+ assertThat(isConstant(e), is(true));
+
+ e = Expressions.call(Expressions.constant("xxx"), "length");
+ assertThat(isAtomic(e), is(false));
+ assertThat(isConstant(e), is(true));
+ }
+
@Test public void testFactorOutBinaryAdd() {
assertThat(
optimize(
@@ -90,7 +143,7 @@
+ "}\n"));
}
- @Test public void testFactorOutBinaryAddSurviesMultipleOptimizations() {
+ @Test public void testFactorOutBinaryAddSurvivesMultipleOptimizations() {
assertThat(
optimize(optimizeExpression(
Expressions.new_(
@@ -290,6 +343,29 @@
+ "}\n"));
}
+ @Test public void testIntegerValueOfZeroComplexTest() {
+ // Integer.valueOf(0) is optimized in complex expressions
+ assertThat(
+ optimize(
+ Expressions.new_(Runnable.class,
+ Collections.<Expression>emptyList(),
+ Expressions.methodDecl(0, int.class, "test",
+ Collections.<ParameterExpression>emptyList(),
+ Blocks.toFunctionBlock(
+ Expressions.call(
+ getMethod(Integer.class, "valueOf", int.class),
+ Expressions.constant(0)))))),
+ equalTo("{\n"
+ + " return new Runnable(){\n"
+ + " int test() {\n"
+ + " return $L4J$C$Integer_valueOf_0_;\n"
+ + " }\n"
+ + "\n"
+ + " static final Integer $L4J$C$Integer_valueOf_0_ = Integer.valueOf(0);\n"
+ + " };\n"
+ + "}\n"));
+ }
+
@Test public void testStaticField() {
// instanceof is optimized in complex expressions
assertThat(