/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.calcite.linq4j.test;

import org.apache.calcite.linq4j.function.Function1;
import org.apache.calcite.linq4j.tree.BlockBuilder;
import org.apache.calcite.linq4j.tree.BlockStatement;
import org.apache.calcite.linq4j.tree.Blocks;
import org.apache.calcite.linq4j.tree.ClassDeclaration;
import org.apache.calcite.linq4j.tree.DeclarationStatement;
import org.apache.calcite.linq4j.tree.Expression;
import org.apache.calcite.linq4j.tree.Expressions;
import org.apache.calcite.linq4j.tree.FieldDeclaration;
import org.apache.calcite.linq4j.tree.FunctionExpression;
import org.apache.calcite.linq4j.tree.MethodCallExpression;
import org.apache.calcite.linq4j.tree.NewExpression;
import org.apache.calcite.linq4j.tree.Node;
import org.apache.calcite.linq4j.tree.ParameterExpression;
import org.apache.calcite.linq4j.tree.Shuttle;
import org.apache.calcite.linq4j.tree.Types;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;

import org.junit.jupiter.api.Test;

import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import static org.apache.calcite.linq4j.test.BlockBuilderBase.ONE;
import static org.apache.calcite.linq4j.test.BlockBuilderBase.TWO;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.junit.jupiter.api.Assertions.assertEquals;

/**
 * Unit test for {@link org.apache.calcite.linq4j.tree.Expression}
 * and subclasses.
 */
public class ExpressionTest {

  @Test void testLambdaCallsBinaryOpInt() {
    // A parameter for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(Integer.TYPE, "arg");

    // This expression represents a lambda expression
    // that adds 1 to the parameter value.
    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.add(
            paramExpr,
            Expressions.constant(2)),
        Arrays.asList(paramExpr));

    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public int apply(int arg) {\n"
            + "    return arg + 2;\n"
            + "  }\n"
            + "  public Object apply(Integer arg) {\n"
            + "    return apply(\n"
            + "      arg.intValue());\n"
            + "  }\n"
            + "  public Object apply(Object arg) {\n"
            + "    return apply(\n"
            + "      (Integer) arg);\n"
            + "  }\n"
            + "}\n",
        s);

    // Compile and run the lambda expression.
    // The value of the parameter is 1
    Integer n = (Integer) lambdaExpr.compile().dynamicInvoke(1);

    // This code example produces the following output:
    //
    // arg => (arg +2)
    // 3
    assertEquals(3, n, 0);
  }

  @Test void testLambdaCallsBinaryOpShort() {
    // A parameter for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(Short.TYPE, "arg");

    // This expression represents a lambda expression
    // that adds 1 to the parameter value.
    Short a = 2;
    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.add(
            paramExpr,
            Expressions.constant(a)),
        Arrays.asList(paramExpr));

    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public int apply(short arg) {\n"
            + "    return arg + (short)2;\n"
            + "  }\n"
            + "  public Object apply(Short arg) {\n"
            + "    return apply(\n"
            + "      arg.shortValue());\n"
            + "  }\n"
            + "  public Object apply(Object arg) {\n"
            + "    return apply(\n"
            + "      (Short) arg);\n"
            + "  }\n"
            + "}\n",
        s);

    // Compile and run the lambda expression.
    // The value of the parameter is 1.
    Short b = 1;
    Integer n = (Integer) lambdaExpr.compile().dynamicInvoke(b);

    // This code example produces the following output:
    //
    // arg => (arg +2)
    // 3
    assertEquals(3, n, 0);
  }

  @Test void testLambdaCallsBinaryOpByte() {
    // A parameter for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(Byte.TYPE, "arg");

    // This expression represents a lambda expression
    // that adds 1 to the parameter value.
    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.add(
            paramExpr,
            Expressions.constant(Byte.valueOf("2"))),
        Arrays.asList(paramExpr));

    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public int apply(byte arg) {\n"
            + "    return arg + (byte)2;\n"
            + "  }\n"
            + "  public Object apply(Byte arg) {\n"
            + "    return apply(\n"
            + "      arg.byteValue());\n"
            + "  }\n"
            + "  public Object apply(Object arg) {\n"
            + "    return apply(\n"
            + "      (Byte) arg);\n"
            + "  }\n"
            + "}\n",
        s);

    // Compile and run the lambda expression.
    // The value of the parameter is 1.
    Integer n = (Integer) lambdaExpr.compile().dynamicInvoke(Byte.valueOf("1"));

    // This code example produces the following output:
    //
    // arg => (arg +2)
    // 3
    assertEquals(3, n, 0);
  }

  @Test void testLambdaCallsBinaryOpDouble() {
    // A parameter for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(Double.TYPE, "arg");

    // This expression represents a lambda expression
    // that adds 1 to the parameter value.
    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.add(
            paramExpr,
            Expressions.constant(2d)),
        Arrays.asList(paramExpr));

    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public double apply(double arg) {\n"
            + "    return arg + 2.0D;\n"
            + "  }\n"
            + "  public Object apply(Double arg) {\n"
            + "    return apply(\n"
            + "      arg.doubleValue());\n"
            + "  }\n"
            + "  public Object apply(Object arg) {\n"
            + "    return apply(\n"
            + "      (Double) arg);\n"
            + "  }\n"
            + "}\n",
        s);

    // Compile and run the lambda expression.
    // The value of the parameter is 1.5.
    double n = (Double) lambdaExpr.compile().dynamicInvoke(1.5d);

    // This code example produces the following output:
    //
    // arg => (arg +2)
    // 3.5
    assertEquals(3.5D, n, 0d);
  }

  @Test void testLambdaCallsBinaryOpLong() {
    // A parameter for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(Long.TYPE, "arg");

    // This expression represents a lambda expression
    // that adds 1L to the parameter value.
    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.add(
            paramExpr,
            Expressions.constant(2L)),
        Arrays.asList(paramExpr));
    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public long apply(long arg) {\n"
            + "    return arg + 2L;\n"
            + "  }\n"
            + "  public Object apply(Long arg) {\n"
            + "    return apply(\n"
            + "      arg.longValue());\n"
            + "  }\n"
            + "  public Object apply(Object arg) {\n"
            + "    return apply(\n"
            + "      (Long) arg);\n"
            + "  }\n"
            + "}\n",
        s);

    // Compile and run the lambda expression.
    // The value of the parameter is 1L.
    long n = (Long) lambdaExpr.compile().dynamicInvoke(1L);

    // This code example produces the following output:
    //
    // arg => (arg +2)
    // 3
    assertEquals(3L, n, 0d);
  }

  @Test void testLambdaCallsBinaryOpFloat() {
    // A parameter for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(Float.TYPE, "arg");

    // This expression represents a lambda expression
    // that adds 1f to the parameter value.
    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.add(
            paramExpr,
            Expressions.constant(2.0f)),
        Arrays.asList(paramExpr));
    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public float apply(float arg) {\n"
            + "    return arg + 2.0F;\n"
            + "  }\n"
            + "  public Object apply(Float arg) {\n"
            + "    return apply(\n"
            + "      arg.floatValue());\n"
            + "  }\n"
            + "  public Object apply(Object arg) {\n"
            + "    return apply(\n"
            + "      (Float) arg);\n"
            + "  }\n"
            + "}\n",
        s);

    // Compile and run the lambda expression.
    // The value of the parameter is 1f
    float n = (Float) lambdaExpr.compile().dynamicInvoke(1f);

    // This code example produces the following output:
    //
    // arg => (arg +2)
    // 3.0
    assertEquals(3.0f, n, 0f);
  }

  @Test void testLambdaCallsBinaryOpMixType() {
    // A parameter for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(Long.TYPE, "arg");

    // This expression represents a lambda expression
    // that adds (int)10 to the parameter value.
    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.add(
            paramExpr,
            Expressions.constant(10)),
        Arrays.asList(paramExpr));
    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public long apply(long arg) {\n"
            + "    return arg + 10;\n"
            + "  }\n"
            + "  public Object apply(Long arg) {\n"
            + "    return apply(\n"
            + "      arg.longValue());\n"
            + "  }\n"
            + "  public Object apply(Object arg) {\n"
            + "    return apply(\n"
            + "      (Long) arg);\n"
            + "  }\n"
            + "}\n",
        s);

    // Compile and run the lambda expression.
    // The value of the parameter is 5L.
    long n = (Long) lambdaExpr.compile().dynamicInvoke(5L);

    // This code example produces the following output:
    //
    // arg => (arg +10)
    // 15
    assertEquals(15L, n, 0d);
  }

  @Test void testLambdaCallsBinaryOpMixDoubleType() {
    // A parameter for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(Double.TYPE, "arg");

    // This expression represents a lambda expression
    // that adds 10.1d to the parameter value.
    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.add(
            paramExpr,
            Expressions.constant(10.1d)),
        Arrays.asList(paramExpr));
    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public double apply(double arg) {\n"
            + "    return arg + 10.1D;\n"
            + "  }\n"
            + "  public Object apply(Double arg) {\n"
            + "    return apply(\n"
            + "      arg.doubleValue());\n"
            + "  }\n"
            + "  public Object apply(Object arg) {\n"
            + "    return apply(\n"
            + "      (Double) arg);\n"
            + "  }\n"
            + "}\n",
        s);

    // Compile and run the lambda expression.
    // The value of the parameter is 5.0f.
    double n = (Double) lambdaExpr.compile().dynamicInvoke(5.0f);

    // This code example produces the following output:
    //
    // arg => (arg +10.1d)
    // 15.1d
    assertEquals(15.1d, n, 0d);
  }

  @Test void testLambdaPrimitiveTwoArgs() {
    // Parameters for the lambda expression.
    ParameterExpression paramExpr =
        Expressions.parameter(int.class, "key");
    ParameterExpression param2Expr =
        Expressions.parameter(int.class, "key2");

    FunctionExpression lambdaExpr = Expressions.lambda(
        Expressions.block(
            (Type) null,
            Expressions.return_(
                null, paramExpr)),
        Arrays.asList(paramExpr, param2Expr));

    // Print out the expression.
    String s = Expressions.toString(lambdaExpr);
    assertEquals("new org.apache.calcite.linq4j.function.Function2() {\n"
            + "  public int apply(int key, int key2) {\n"
            + "    return key;\n"
            + "  }\n"
            + "  public Integer apply(Integer key, Integer key2) {\n"
            + "    return apply(\n"
            + "      key.intValue(),\n"
            + "      key2.intValue());\n"
            + "  }\n"
            + "  public Integer apply(Object key, Object key2) {\n"
            + "    return apply(\n"
            + "      (Integer) key,\n"
            + "      (Integer) key2);\n"
            + "  }\n"
            + "}\n",
        s);
  }

  @Test void testLambdaCallsTwoArgMethod() throws NoSuchMethodException {
    // A parameter for the lambda expression.
    ParameterExpression paramS =
        Expressions.parameter(String.class, "s");
    ParameterExpression paramBegin =
        Expressions.parameter(Integer.TYPE, "begin");
    ParameterExpression paramEnd =
        Expressions.parameter(Integer.TYPE, "end");

    // This expression represents a lambda expression
    // that adds 1 to the parameter value.
    FunctionExpression lambdaExpr =
        Expressions.lambda(
            Expressions.call(
                paramS,
                String.class.getMethod(
                    "substring", Integer.TYPE, Integer.TYPE),
                paramBegin,
                paramEnd), paramS, paramBegin, paramEnd);

    // Compile and run the lambda expression.
    String s =
        (String) lambdaExpr.compile().dynamicInvoke("hello world", 3, 7);

    assertEquals("lo w", s);
  }

  @Test void testFoldAnd() {
    // empty list yields true
    final List<Expression> list0 = Collections.emptyList();
    assertEquals(
        "true",
        Expressions.toString(
            Expressions.foldAnd(list0)));
    assertEquals(
        "false",
        Expressions.toString(
            Expressions.foldOr(list0)));

    final List<Expression> list1 =
        Arrays.asList(
            Expressions.equal(Expressions.constant(1), Expressions.constant(2)),
            Expressions.equal(Expressions.constant(3), Expressions.constant(4)),
            Expressions.constant(true),
            Expressions.equal(Expressions.constant(5),
                Expressions.constant(6)));
    // true is eliminated from AND
    assertEquals(
        "1 == 2 && 3 == 4 && 5 == 6",
        Expressions.toString(
            Expressions.foldAnd(list1)));
    // a single true makes OR true
    assertEquals(
        "true",
        Expressions.toString(
            Expressions.foldOr(list1)));

    final List<Expression> list2 =
        Collections.singletonList(
            Expressions.constant(true));
    assertEquals(
        "true",
        Expressions.toString(
            Expressions.foldAnd(list2)));
    assertEquals(
        "true",
        Expressions.toString(
            Expressions.foldOr(list2)));

    final List<Expression> list3 =
        Arrays.asList(
            Expressions.equal(Expressions.constant(1), Expressions.constant(2)),
            Expressions.constant(false),
            Expressions.equal(Expressions.constant(5),
                Expressions.constant(6)));
    // false causes whole list to be false
    assertEquals(
        "false",
        Expressions.toString(
            Expressions.foldAnd(list3)));
    assertEquals(
        "1 == 2 || 5 == 6",
        Expressions.toString(
            Expressions.foldOr(list3)));
  }

  @Test void testWrite() {
    assertEquals(
        "1 + 2.0F + 3L + Long.valueOf(4L)",
        Expressions.toString(
            Expressions.add(
                Expressions.add(
                    Expressions.add(
                        Expressions.constant(1),
                        Expressions.constant(2F, Float.TYPE)),
                    Expressions.constant(3L, Long.TYPE)),
                Expressions.constant(4L, Long.class))));

    assertEquals(
        "java.math.BigDecimal.valueOf(31415926L, 7)",
        Expressions.toString(
            Expressions.constant(
                BigDecimal.valueOf(314159260, 8))));

    // Parentheses needed, to override the left-associativity of +.
    assertEquals(
        "1 + (2 + 3)",
        Expressions.toString(
            Expressions.add(
                Expressions.constant(1),
                Expressions.add(
                    Expressions.constant(2),
                    Expressions.constant(3)))));

    // No parentheses needed; higher precedence of * achieves the desired
    // effect.
    assertEquals(
        "1 + 2 * 3",
        Expressions.toString(
            Expressions.add(
                Expressions.constant(1),
                Expressions.multiply(
                    Expressions.constant(2),
                    Expressions.constant(3)))));

    assertEquals(
        "1 * (2 + 3)",
        Expressions.toString(
            Expressions.multiply(
                Expressions.constant(1),
                Expressions.add(
                    Expressions.constant(2),
                    Expressions.constant(3)))));

    // Parentheses needed, to overcome right-associativity of =.
    assertEquals(
        "(1 = 2) = 3",
        Expressions.toString(
            Expressions.assign(
                Expressions.assign(
                    Expressions.constant(1), Expressions.constant(2)),
                Expressions.constant(3))));

    // Ternary operator.
    assertEquals(
        "1 < 2 ? (3 < 4 ? 5 : 6) : 7 < 8 ? 9 : 10",
        Expressions.toString(
            Expressions.condition(
                Expressions.lessThan(
                    Expressions.constant(1),
                    Expressions.constant(2)),
                Expressions.condition(
                    Expressions.lessThan(
                        Expressions.constant(3),
                        Expressions.constant(4)),
                    Expressions.constant(5),
                    Expressions.constant(6)),
                Expressions.condition(
                    Expressions.lessThan(
                        Expressions.constant(7),
                        Expressions.constant(8)),
                    Expressions.constant(9),
                    Expressions.constant(10)))));

    assertEquals(
        "0 + (double) (2 + 3)",
        Expressions.toString(
            Expressions.add(
                Expressions.constant(0),
                Expressions.convert_(
                    Expressions.add(
                        Expressions.constant(2), Expressions.constant(3)),
                    Double.TYPE))));

    // "--5" would be a syntax error
    assertEquals(
        "- - 5",
        Expressions.toString(
            Expressions.negate(
                Expressions.negate(
                    Expressions.constant(5)))));

    assertEquals(
        "a.empno",
        Expressions.toString(
            Expressions.field(
                Expressions.parameter(Linq4jTest.Employee.class, "a"),
                "empno")));

    assertEquals(
        "a.length",
        Expressions.toString(
            Expressions.field(
                Expressions.parameter(Object[].class, "a"),
                "length")));

    assertEquals(
        "java.util.Collections.EMPTY_LIST",
        Expressions.toString(
            Expressions.field(
                null, Collections.class, "EMPTY_LIST")));

    final ParameterExpression paramX =
        Expressions.parameter(String.class, "x");
    assertEquals(
        "new org.apache.calcite.linq4j.function.Function1() {\n"
            + "  public int apply(String x) {\n"
            + "    return x.length();\n"
            + "  }\n"
            + "  public Object apply(Object x) {\n"
            + "    return apply(\n"
            + "      (String) x);\n"
            + "  }\n"
            + "}\n",
        Expressions.toString(
            Expressions.lambda(
                Function1.class,
                Expressions.call(
                    paramX, "length", Collections.emptyList()),
                Arrays.asList(paramX))));

    // 1-dimensional array with initializer
    assertEquals(
        "new String[] {\n"
            + "  \"foo\",\n"
            + "  null,\n"
            + "  \"bar\\\"baz\"}",
        Expressions.toString(
            Expressions.newArrayInit(
                String.class,
                Expressions.constant("foo"),
                Expressions.constant(null),
                Expressions.constant("bar\"baz"))));

    // 2-dimensional array with initializer
    assertEquals(
        "new String[][] {\n"
            + "  new String[] {\n"
            + "    \"foo\",\n"
            + "    \"bar\"},\n"
            + "  null,\n"
            + "  new String[] {\n"
            + "    null}}",
        Expressions.toString(
            Expressions.newArrayInit(
                String.class,
                2,
                Expressions.constant(new String[] {"foo", "bar"}),
                Expressions.constant(null),
                Expressions.constant(new String[] {null}))));

    // 1-dimensional array
    assertEquals(
        "new String[x + 1]",
        Expressions.toString(
            Expressions.newArrayBounds(
                String.class,
                1,
                Expressions.add(
                    Expressions.parameter(0, int.class, "x"),
                    Expressions.constant(1)))));

    // 3-dimensional array
    assertEquals(
        "new String[x + 1][][]",
        Expressions.toString(
            Expressions.newArrayBounds(
                String.class,
                3,
                Expressions.add(
                    Expressions.parameter(0, int.class, "x"),
                    Expressions.constant(1)))));

    assertEquals(
        "(int) ((String) (Object) \"foo\").length()",
        Expressions.toString(
            Expressions.convert_(
                Expressions.call(
                    Expressions.convert_(
                        Expressions.convert_(
                            Expressions.constant("foo"),
                            Object.class),
                        String.class),
                    "length",
                    Collections.emptyList()),
                Integer.TYPE)));

    // resolving a static method
    assertEquals(
        "Integer.valueOf(\"0123\")",
        Expressions.toString(
            Expressions.call(
                Integer.class,
                "valueOf",
                Collections.<Expression>singletonList(
                    Expressions.constant("0123")))));

    // precedence of not and instanceof
    assertEquals(
        "!(o instanceof String)",
        Expressions.toString(
            Expressions.not(
                Expressions.typeIs(
                    Expressions.parameter(Object.class, "o"),
                    String.class))));

    // not not
    assertEquals(
        "!!(o instanceof String)",
        Expressions.toString(
            Expressions.not(
                Expressions.not(
                    Expressions.typeIs(
                        Expressions.parameter(Object.class, "o"),
                        String.class)))));
  }

  @Test void testWriteConstant() {
    // array of primitives
    assertEquals(
        "new int[] {\n"
            + "  1,\n"
            + "  2,\n"
            + "  -1}",
        Expressions.toString(
            Expressions.constant(new int[]{1, 2, -1})));

    // primitive
    assertEquals(
        "-12",
        Expressions.toString(
            Expressions.constant(-12)));

    assertEquals(
        "(short)-12",
        Expressions.toString(
            Expressions.constant((short) -12)));

    assertEquals(
        "(byte)-12",
        Expressions.toString(
            Expressions.constant((byte) -12)));

    // boxed primitives
    assertEquals(
        "Integer.valueOf(1)",
        Expressions.toString(
            Expressions.constant(1, Integer.class)));

    assertEquals(
        "Double.valueOf(-3.14D)",
        Expressions.toString(
            Expressions.constant(-3.14, Double.class)));

    assertEquals(
        "Boolean.valueOf(true)",
        Expressions.toString(
            Expressions.constant(true, Boolean.class)));

    // primitive with explicit class
    assertEquals(
        "1",
        Expressions.toString(
            Expressions.constant(1, int.class)));

    assertEquals(
        "(short)1",
        Expressions.toString(
            Expressions.constant(1, short.class)));

    assertEquals(
        "(byte)1",
        Expressions.toString(
            Expressions.constant(1, byte.class)));

    assertEquals(
        "-3.14D",
        Expressions.toString(
            Expressions.constant(-3.14, double.class)));

    assertEquals(
        "true",
        Expressions.toString(
            Expressions.constant(true, boolean.class)));

    // objects and nulls
    assertEquals(
        "new String[] {\n"
            + "  \"foo\",\n"
            + "  null}",
        Expressions.toString(
            Expressions.constant(new String[] {"foo", null})));

    // string
    assertEquals(
        "\"hello, \\\"world\\\"!\"",
        Expressions.toString(
            Expressions.constant("hello, \"world\"!")));

    // enum
    assertEquals(
        "org.apache.calcite.linq4j.test.ExpressionTest.MyEnum.X",
        Expressions.toString(
            Expressions.constant(MyEnum.X)));

    // array of enum
    assertEquals(
        "new org.apache.calcite.linq4j.test.ExpressionTest.MyEnum[] {\n"
            + "  org.apache.calcite.linq4j.test.ExpressionTest.MyEnum.X,\n"
            + "  org.apache.calcite.linq4j.test.ExpressionTest.MyEnum.Y}",
        Expressions.toString(
            Expressions.constant(new MyEnum[]{MyEnum.X, MyEnum.Y})));

    // class
    assertEquals(
        "java.lang.String.class",
        Expressions.toString(
            Expressions.constant(String.class)));

    // array class
    assertEquals(
        "int[].class",
        Expressions.toString(
            Expressions.constant(int[].class)));

    assertEquals(
        "java.util.List[][].class",
        Expressions.toString(
            Expressions.constant(List[][].class)));

    // automatically call constructor if it matches fields
    assertEquals(
        "new org.apache.calcite.linq4j.test.Linq4jTest.Employee[] {\n"
            + "  new org.apache.calcite.linq4j.test.Linq4jTest.Employee(\n"
            + "    100,\n"
            + "    \"Fred\",\n"
            + "    10),\n"
            + "  new org.apache.calcite.linq4j.test.Linq4jTest.Employee(\n"
            + "    110,\n"
            + "    \"Bill\",\n"
            + "    30),\n"
            + "  new org.apache.calcite.linq4j.test.Linq4jTest.Employee(\n"
            + "    120,\n"
            + "    \"Eric\",\n"
            + "    10),\n"
            + "  new org.apache.calcite.linq4j.test.Linq4jTest.Employee(\n"
            + "    130,\n"
            + "    \"Janet\",\n"
            + "    10)}",
        Expressions.toString(
            Expressions.constant(Linq4jTest.emps)));
  }

  @Test void testWriteArray() {
    assertEquals(
        "1 + integers[2 + index]",
        Expressions.toString(
            Expressions.add(
                Expressions.constant(1),
                Expressions.arrayIndex(
                    Expressions.variable(int[].class, "integers"),
                    Expressions.add(
                        Expressions.constant(2),
                        Expressions.variable(int.class, "index"))))));
  }

  @Test void testWriteAnonymousClass() {
    // final List<String> baz = Arrays.asList("foo", "bar");
    // new AbstractList<String>() {
    //     public int size() {
    //         return baz.size();
    //     }
    //     public String get(int index) {
    //         return ((String) baz.get(index)).toUpperCase();
    //     }
    // }
    final ParameterExpression bazParameter =
        Expressions.parameter(
            Types.of(List.class, String.class),
            "baz");
    final ParameterExpression indexParameter =
        Expressions.parameter(
            Integer.TYPE,
            "index");
    BlockStatement e =
        Expressions.block(
            Expressions.declare(
                Modifier.FINAL,
                bazParameter,
                Expressions.call(
                    Arrays.class,
                    "asList",
                    Arrays.<Expression>asList(
                        Expressions.constant("foo"),
                        Expressions.constant("bar")))),
            Expressions.statement(
                Expressions.new_(
                    Types.of(AbstractList.class, String.class),
                    Collections.emptyList(),
                    Arrays.asList(
                        Expressions.fieldDecl(
                            Modifier.PUBLIC | Modifier.FINAL,
                            Expressions.parameter(
                                String.class,
                                "qux"),
                            Expressions.constant("xyzzy")),
                        Expressions.methodDecl(
                            Modifier.PUBLIC,
                            Integer.TYPE,
                            "size",
                            Collections.emptyList(),
                            Blocks.toFunctionBlock(
                                Expressions.call(
                                    bazParameter,
                                    "size",
                                    Collections.emptyList()))),
                        Expressions.methodDecl(
                            Modifier.PUBLIC,
                            String.class,
                            "get",
                            Arrays.asList(indexParameter),
                            Blocks.toFunctionBlock(
                                Expressions.call(
                                    Expressions.convert_(
                                        Expressions.call(
                                            bazParameter,
                                            "get",
                                            Arrays.<Expression>asList(
                                                indexParameter)),
                                        String.class),
                                    "toUpperCase",
                                    ImmutableList.of())))))));
    assertEquals(
        "{\n"
            + "  final java.util.List<String> baz = java.util.Arrays.asList(\"foo\", \"bar\");\n"
            + "  new java.util.AbstractList<String>(){\n"
            + "    public final String qux = \"xyzzy\";\n"
            + "    public int size() {\n"
            + "      return baz.size();\n"
            + "    }\n"
            + "\n"
            + "    public String get(int index) {\n"
            + "      return ((String) baz.get(index)).toUpperCase();\n"
            + "    }\n"
            + "\n"
            + "  };\n"
            + "}\n",
        Expressions.toString(e));
  }

  @Test void testWriteWhile() {
    DeclarationStatement xDecl;
    DeclarationStatement yDecl;
    Node node =
        Expressions.block(
            xDecl = Expressions.declare(
                0,
                "x",
                Expressions.constant(10)),
            yDecl = Expressions.declare(
                0,
                "y",
                Expressions.constant(0)),
            Expressions.while_(
                Expressions.lessThan(
                    xDecl.parameter,
                    Expressions.constant(5)),
                Expressions.statement(
                    Expressions.preIncrementAssign(yDecl.parameter))));
    assertEquals(
        "{\n"
            + "  int x = 10;\n"
            + "  int y = 0;\n"
            + "  while (x < 5) {\n"
            + "    ++y;\n"
            + "  }\n"
            + "}\n",
        Expressions.toString(node));
  }

  @Test void testWriteTryCatchFinally() {
    final ParameterExpression cce_ =
        Expressions.parameter(Modifier.FINAL, ClassCastException.class, "cce");
    final ParameterExpression re_ =
        Expressions.parameter(0, RuntimeException.class, "re");
    Node node =
        Expressions.tryCatchFinally(
            Expressions.block(
                Expressions.return_(null,
                    Expressions.call(
                        Expressions.constant("foo"),
                        "length"))),
            Expressions.statement(
                Expressions.call(
                    Expressions.constant("foo"),
                    "toUpperCase")),
            Expressions.catch_(cce_,
                Expressions.return_(null, Expressions.constant(null))),
            Expressions.catch_(re_,
                Expressions.throw_(
                    Expressions.new_(IndexOutOfBoundsException.class))));
    assertEquals(
        "try {\n"
            + "  return \"foo\".length();\n"
            + "} catch (final ClassCastException cce) {\n"
            + "  return null;\n"
            + "} catch (RuntimeException re) {\n"
            + "  throw new IndexOutOfBoundsException();\n"
            + "} finally {\n"
            + "  \"foo\".toUpperCase();\n"
            + "}\n",
        Expressions.toString(node));
  }

  @Test void testWriteTryFinally() {
    Node node =
        Expressions.ifThen(
            Expressions.constant(true),
            Expressions.tryFinally(
                Expressions.block(
                    Expressions.return_(null,
                        Expressions.call(
                            Expressions.constant("foo"),
                            "length"))),
                Expressions.statement(
                    Expressions.call(
                        Expressions.constant("foo"),
                        "toUpperCase"))));
    assertEquals(
        "if (true) {\n"
            + "  try {\n"
            + "    return \"foo\".length();\n"
            + "  } finally {\n"
            + "    \"foo\".toUpperCase();\n"
            + "  }\n"
            + "}\n",
        Expressions.toString(node));
  }

  @Test void testWriteTryCatch() {
    final ParameterExpression cce_ =
        Expressions.parameter(Modifier.FINAL, ClassCastException.class, "cce");
    final ParameterExpression re_ =
        Expressions.parameter(0, RuntimeException.class, "re");
    Node node =
        Expressions.tryCatch(
            Expressions.block(
                Expressions.return_(null,
                    Expressions.call(Expressions.constant("foo"), "length"))),
            Expressions.catch_(cce_,
                Expressions.return_(null, Expressions.constant(null))),
            Expressions.catch_(re_,
                Expressions.return_(null,
                    Expressions.call(re_, "toString"))));
    assertEquals(
        "try {\n"
            + "  return \"foo\".length();\n"
            + "} catch (final ClassCastException cce) {\n"
            + "  return null;\n"
            + "} catch (RuntimeException re) {\n"
            + "  return re.toString();\n"
            + "}\n",
        Expressions.toString(node));
  }

  @Test void testType() {
    // Type of ternary operator is the gcd of its arguments.
    assertEquals(
        long.class,
        Expressions.condition(
            Expressions.constant(true),
            Expressions.constant(5),
            Expressions.constant(6L)).getType());
    assertEquals(
        long.class,
        Expressions.condition(
            Expressions.constant(true),
            Expressions.constant(5L),
            Expressions.constant(6)).getType());

    // If one of the arguments is null constant, it is implicitly coerced.
    assertEquals(
        String.class,
        Expressions.condition(
            Expressions.constant(true),
            Expressions.constant("xxx"),
            Expressions.constant(null)).getType());
    assertEquals(
        Integer.class,
        Expressions.condition(
            Expressions.constant(true),
            Expressions.constant(0),
            Expressions.constant(null)).getType());

    // In Java, "-" applied to short and byte yield int.
    assertEquals(double.class,
        Expressions.negate(Expressions.constant((double) 1)).getType());
    assertEquals(float.class,
        Expressions.negate(Expressions.constant((float) 1)).getType());
    assertEquals(long.class,
        Expressions.negate(Expressions.constant((long) 1)).getType());
    assertEquals(int.class,
        Expressions.negate(Expressions.constant(1)).getType());
    assertEquals(int.class,
        Expressions.negate(Expressions.constant((short) 1)).getType());
    assertEquals(int.class,
        Expressions.negate(Expressions.constant((byte) 1)).getType());
  }

  @Test void testCompile() throws NoSuchMethodException {
    // Creating a parameter for the expression tree.
    ParameterExpression param = Expressions.parameter(String.class);

    // Creating an expression for the method call and specifying its
    // parameter.
    MethodCallExpression methodCall =
        Expressions.call(
            Integer.class,
            "valueOf",
            Collections.<Expression>singletonList(param));

    // The following statement first creates an expression tree,
    // then compiles it, and then runs it.
    int x =
        Expressions.<Function1<String, Integer>>lambda(
            methodCall,
            new ParameterExpression[] { param })
            .getFunction()
            .apply("1234");
    assertEquals(1234, x);
  }

  @Test void testBlockBuilder() {
    checkBlockBuilder(
        false,
        "{\n"
            + "  final int three = 1 + 2;\n"
            + "  final int six = three * 2;\n"
            + "  final int nine = three * three;\n"
            + "  final int eighteen = three + six + nine;\n"
            + "  return eighteen;\n"
            + "}\n");
    checkBlockBuilder(
        true,
        "{\n"
            + "  final int three = 1 + 2;\n"
            + "  return three + three * 2 + three * three;\n"
            + "}\n");
  }

  public void checkBlockBuilder(boolean optimizing, String expected) {
    BlockBuilder statements = new BlockBuilder(optimizing);
    Expression one =
        statements.append(
            "one", Expressions.constant(1));
    Expression two =
        statements.append(
            "two", Expressions.constant(2));
    Expression three =
        statements.append(
            "three", Expressions.add(one, two));
    Expression six =
        statements.append(
            "six",
            Expressions.multiply(three, two));
    Expression nine =
        statements.append(
            "nine",
            Expressions.multiply(three, three));
    Expression eighteen =
        statements.append(
            "eighteen",
            Expressions.add(
                Expressions.add(three, six),
                nine));
    statements.add(Expressions.return_(null, eighteen));
    BlockStatement expression = statements.toBlock();
    assertEquals(expected, Expressions.toString(expression));
    expression.accept(new Shuttle());
  }

  @Test void testBlockBuilder2() {
    BlockBuilder statements = new BlockBuilder();
    Expression element =
        statements.append(
            "element", Expressions.constant(null));
    Expression comparator =
        statements.append(
            "comparator", Expressions.constant(null, Comparator.class));
    Expression treeSet =
        statements.append(
            "treeSet",
            Expressions.new_(
                TreeSet.class,
                Arrays.asList(comparator)));
    statements.add(
        Expressions.return_(
            null,
            Expressions.call(
                treeSet,
                "add",
                element)));
    BlockStatement expression = statements.toBlock();
    final String expected = "{\n"
        + "  final java.util.TreeSet treeSet = new java.util.TreeSet(\n"
        + "    (java.util.Comparator) null);\n"
        + "  return treeSet.add(null);\n"
        + "}\n";
    assertThat(Expressions.toString(expression), is(expected));
    expression.accept(new Shuttle());
  }

  @Test void testBlockBuilder3() {
/*
    int a = 1;
    int b = a + 2;
    int c = a + 3;
    int d = a + 4;
    int e = {
      int b = a + 3;
      foo(b);
    }
    bar(a, b, c, d, e);
*/
    BlockBuilder builder0 = new BlockBuilder();
    final Expression a = builder0.append("_a", Expressions.constant(1));
    final Expression b =
        builder0.append("_b", Expressions.add(a, Expressions.constant(2)));
    final Expression c =
        builder0.append("_c", Expressions.add(a, Expressions.constant(3)));
    final Expression d =
        builder0.append("_d", Expressions.add(a, Expressions.constant(4)));

    BlockBuilder builder1 = new BlockBuilder();
    final Expression b1 =
        builder1.append("_b", Expressions.add(a, Expressions.constant(3)));
    builder1.add(
        Expressions.statement(
            Expressions.call(ExpressionTest.class, "foo", b1)));
    final Expression e = builder0.append("e", builder1.toBlock());
    builder0.add(
        Expressions.statement(
            Expressions.call(ExpressionTest.class, "bar", a, b, c, d, e)));
    // With the bug in BlockBuilder.append(String, BlockExpression),
    //    bar(1, _b, _c, _d, foo(_d));
    // Correct result is
    //    bar(1, _b, _c, _d, foo(_c));
    // because _c has the same expression (a + 3) as inner b.
    BlockStatement expression = builder0.toBlock();
    assertEquals(
        "{\n"
            + "  final int _b = 1 + 2;\n"
            + "  final int _c = 1 + 3;\n"
            + "  final int _d = 1 + 4;\n"
            + "  final int _b0 = 1 + 3;\n"
            + "  org.apache.calcite.linq4j.test.ExpressionTest.bar(1, _b, _c, _d, org.apache.calcite.linq4j.test.ExpressionTest.foo(_b0));\n"
            + "}\n",
        Expressions.toString(expression));
    expression.accept(new Shuttle());
  }

  @Test void testConstantExpression() {
    final Expression constant = Expressions.constant(
        new Object[] {
            1,
            new Object[] {
                (byte) 1, (short) 2, (int) 3, (long) 4,
                (float) 5, (double) 6, (char) 7, true, "string", null
            },
            new AllType(true, (byte) 100, (char) 101, (short) 102, 103,
                (long) 104, (float) 105, (double) 106, new BigDecimal(107),
                new BigInteger("108"), "109", null)
        });
    assertEquals(
        "new Object[] {\n"
            + "  1,\n"
            + "  new Object[] {\n"
            + "    (byte)1,\n"
            + "    (short)2,\n"
            + "    3,\n"
            + "    4L,\n"
            + "    5.0F,\n"
            + "    6.0D,\n"
            + "    (char)7,\n"
            + "    true,\n"
            + "    \"string\",\n"
            + "    null},\n"
            + "  new org.apache.calcite.linq4j.test.ExpressionTest.AllType(\n"
            + "    true,\n"
            + "    (byte)100,\n"
            + "    (char)101,\n"
            + "    (short)102,\n"
            + "    103,\n"
            + "    104L,\n"
            + "    105.0F,\n"
            + "    106.0D,\n"
            + "    java.math.BigDecimal.valueOf(107L),\n"
            + "    new java.math.BigInteger(\"108\"),\n"
            + "    \"109\",\n"
            + "    null)}",
        constant.toString());
    constant.accept(new Shuttle());
  }

  @Test void testBigDecimalConstantExpression() {
    assertEquals("java.math.BigDecimal.valueOf(104L)",
        Expressions.toString(Expressions.constant("104", BigDecimal.class)));
    assertEquals("java.math.BigDecimal.valueOf(1L, -3)",
        Expressions.toString(Expressions.constant("1000", BigDecimal.class)));
    assertEquals("java.math.BigDecimal.valueOf(1L, -3)",
        Expressions.toString(Expressions.constant(1000, BigDecimal.class)));
    assertEquals("java.math.BigDecimal.valueOf(107L)",
        Expressions.toString(Expressions.constant(107, BigDecimal.class)));
    assertEquals("java.math.BigDecimal.valueOf(199999999999999L)",
        Expressions.toString(Expressions.constant(199999999999999L, BigDecimal.class)));
    assertEquals("java.math.BigDecimal.valueOf(1234L, 2)",
        Expressions.toString(Expressions.constant(12.34, BigDecimal.class)));
  }

  @Test void testObjectConstantExpression() {
    assertEquals("(byte)100",
        Expressions.toString(Expressions.constant((byte) 100, Object.class)));
    assertEquals("(char)100",
        Expressions.toString(Expressions.constant((char) 100, Object.class)));
    assertEquals("(short)100",
        Expressions.toString(Expressions.constant((short) 100, Object.class)));
    assertEquals("100L",
        Expressions.toString(Expressions.constant(100L, Object.class)));
    assertEquals("100.0F",
        Expressions.toString(Expressions.constant(100F, Object.class)));
    assertEquals("100.0D",
        Expressions.toString(Expressions.constant(100D, Object.class)));
  }

  @Test void testClassDecl() {
    final NewExpression newExpression =
        Expressions.new_(
            Object.class,
            ImmutableList.of(),
            Arrays.asList(
                Expressions.fieldDecl(
                    Modifier.PUBLIC | Modifier.FINAL,
                    Expressions.parameter(String.class, "foo"),
                    Expressions.constant("bar")),
                new ClassDeclaration(
                    Modifier.PUBLIC | Modifier.STATIC,
                    "MyClass",
                    null,
                    ImmutableList.of(),
                    Arrays.asList(
                        new FieldDeclaration(
                            0,
                            Expressions.parameter(int.class, "x"),
                            Expressions.constant(0)))),
                Expressions.fieldDecl(
                    0,
                    Expressions.parameter(int.class, "i"))));
    assertEquals(
        "new Object(){\n"
            + "  public final String foo = \"bar\";\n"
            + "  public static class MyClass {\n"
            + "    int x = 0;\n"
            + "  }\n"
            + "  int i;\n"
            + "}",
        Expressions.toString(newExpression));
    newExpression.accept(new Shuttle());
  }

  @Test void testReturn() {
    assertEquals(
        "if (true) {\n"
            + "  return;\n"
            + "} else {\n"
            + "  return 1;\n"
            + "}\n",
        Expressions.toString(
            Expressions.ifThenElse(
                Expressions.constant(true),
                Expressions.return_(null),
                Expressions.return_(null, Expressions.constant(1)))));
  }

  @Test void testIfElseIfElse() {
    assertEquals(
        "if (true) {\n"
            + "  return;\n"
            + "} else if (false) {\n"
            + "  return;\n"
            + "} else {\n"
            + "  return 1;\n"
            + "}\n",
        Expressions.toString(
            Expressions.ifThenElse(
                Expressions.constant(true),
                Expressions.return_(null),
                Expressions.constant(false),
                Expressions.return_(null),
                Expressions.return_(null, Expressions.constant(1)))));
  }

  /** Test for common sub-expression elimination. */
  @Test void testSubExpressionElimination() {
    final BlockBuilder builder = new BlockBuilder(true);
    ParameterExpression x = Expressions.parameter(Object.class, "p");
    Expression current4 = builder.append(
        "current4",
        Expressions.convert_(x, Object[].class));
    Expression v = builder.append(
        "v",
        Expressions.convert_(
            Expressions.arrayIndex(
                current4,
                Expressions.constant(4)), Short.class));
    Expression v0 = builder.append(
        "v0",
        Expressions.convert_(v, Number.class));
    Expression v1 = builder.append(
        "v1",
        Expressions.convert_(
            Expressions.arrayIndex(
                current4,
                Expressions.constant(4)), Short.class));
    Expression v2 = builder.append(
        "v2",
        Expressions.convert_(v, Number.class));
    Expression v3 = builder.append(
        "v3",
        Expressions.convert_(
            Expressions.arrayIndex(
                current4,
                Expressions.constant(4)), Short.class));
    Expression v4 = builder.append(
        "v4",
        Expressions.convert_(v3, Number.class));
    Expression v5 = builder.append("v5", Expressions.call(v4, "intValue"));
    Expression v6 = builder.append(
        "v6",
        Expressions.condition(
            Expressions.equal(v2, Expressions.constant(null)),
            Expressions.constant(null),
            Expressions.equal(v5, Expressions.constant(1997))));
    builder.add(Expressions.return_(null, v6));
    assertEquals(
        "{\n"
            + "  final Short v = (Short) ((Object[]) p)[4];\n"
            + "  return (Number) v == null ? (Boolean) null : ("
            + "(Number) v).intValue() == 1997;\n"
            + "}\n",
        Expressions.toString(builder.toBlock()));
  }

  @Test void testFor() throws NoSuchFieldException {
    final BlockBuilder builder = new BlockBuilder();
    final ParameterExpression i_ = Expressions.parameter(int.class, "i");
    builder.add(
        Expressions.for_(
            Expressions.declare(
                0, i_, Expressions.constant(0)),
            Expressions.lessThan(i_, Expressions.constant(10)),
            Expressions.postIncrementAssign(i_),
            Expressions.block(
                Expressions.statement(
                    Expressions.call(
                        Expressions.field(
                            null, System.class.getField("out")),
                        "println",
                        i_)))));
    assertEquals(
        "{\n"
            + "  for (int i = 0; i < 10; i++) {\n"
            + "    System.out.println(i);\n"
            + "  }\n"
            + "}\n",
        Expressions.toString(builder.toBlock()));
  }

  @Test void testFor2() throws NoSuchFieldException {
    final BlockBuilder builder = new BlockBuilder();
    final ParameterExpression i_ = Expressions.parameter(int.class, "i");
    final ParameterExpression j_ = Expressions.parameter(int.class, "j");
    builder.add(
        Expressions.for_(
            Arrays.asList(
                Expressions.declare(
                    0, i_, Expressions.constant(0)),
                Expressions.declare(
                    0, j_, Expressions.constant(10))),
            null,
            null,
            Expressions.block(
                Expressions.ifThen(
                    Expressions.lessThan(
                        Expressions.preIncrementAssign(i_),
                        Expressions.preDecrementAssign(j_)),
                    Expressions.break_(null)))));
    assertEquals(
        "{\n"
            + "  for (int i = 0, j = 10; ; ) {\n"
            + "    if (++i < --j) {\n"
            + "      break;\n"
            + "    }\n"
            + "  }\n"
            + "}\n",
        Expressions.toString(builder.toBlock()));
  }

  @Test void testForEach() {
    final BlockBuilder builder = new BlockBuilder();
    final ParameterExpression i_ = Expressions.parameter(int.class, "i");
    final ParameterExpression list_ = Expressions.parameter(List.class, "list");
    builder.add(
        Expressions.forEach(i_, list_,
            Expressions.ifThen(
                Expressions.lessThan(
                    Expressions.constant(1),
                    Expressions.constant(2)),
                Expressions.break_(null))));
    assertThat(Expressions.toString(builder.toBlock()),
        is("{\n"
            + "  for (int i : list) {\n"
            + "    if (1 < 2) {\n"
            + "      break;\n"
            + "    }\n"
            + "  }\n"
            + "}\n"));
  }

  @Test void testEmptyListLiteral() throws Exception {
    assertEquals("java.util.Collections.EMPTY_LIST",
        Expressions.toString(Expressions.constant(Arrays.asList())));
  }

  @Test void testOneElementListLiteral() throws Exception {
    assertEquals("java.util.Arrays.asList(1)",
        Expressions.toString(Expressions.constant(Arrays.asList(1))));
  }

  @Test void testTwoElementsListLiteral() throws Exception {
    assertEquals("java.util.Arrays.asList(1,\n"
            + "  2)",
        Expressions.toString(Expressions.constant(Arrays.asList(1, 2))));
  }

  @Test void testNestedListsLiteral() throws Exception {
    assertEquals("java.util.Arrays.asList(java.util.Arrays.asList(1,\n"
            + "    2),\n"
            + "  java.util.Arrays.asList(3,\n"
            + "    4))",
        Expressions.toString(
            Expressions.constant(
                Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3, 4)))));
  }

  @Test void testEmptyMapLiteral() throws Exception {
    assertEquals("com.google.common.collect.ImmutableMap.of()",
        Expressions.toString(Expressions.constant(new HashMap())));
  }

  @Test void testOneElementMapLiteral() throws Exception {
    assertEquals("com.google.common.collect.ImmutableMap.of(\"abc\", 42)",
        Expressions.toString(Expressions.constant(Collections.singletonMap("abc", 42))));
  }

  @Test void testTwoElementsMapLiteral() throws Exception {
    assertEquals("com.google.common.collect.ImmutableMap.of(\"abc\", 42,\n"
            + "\"def\", 43)",
        Expressions.toString(Expressions.constant(ImmutableMap.of("abc", 42, "def", 43))));
  }

  @Test void testTenElementsMapLiteral() throws Exception {
    Map<String, String> map = new LinkedHashMap<>(); // for consistent output
    for (int i = 0; i < 10; i++) {
      map.put("key_" + i, "value_" + i);
    }
    assertEquals("com.google.common.collect.ImmutableMap.builder().put(\"key_0\", \"value_0\")\n"
            + ".put(\"key_1\", \"value_1\")\n"
            + ".put(\"key_2\", \"value_2\")\n"
            + ".put(\"key_3\", \"value_3\")\n"
            + ".put(\"key_4\", \"value_4\")\n"
            + ".put(\"key_5\", \"value_5\")\n"
            + ".put(\"key_6\", \"value_6\")\n"
            + ".put(\"key_7\", \"value_7\")\n"
            + ".put(\"key_8\", \"value_8\")\n"
            + ".put(\"key_9\", \"value_9\").build()",
        Expressions.toString(Expressions.constant(map)));
  }

  @Test void testEvaluate() {
    Expression x = Expressions.add(ONE, TWO);
    Object value = Expressions.evaluate(x);
    assertThat(value, is(3));
  }

  @Test void testEmptySetLiteral() throws Exception {
    assertEquals("com.google.common.collect.ImmutableSet.of()",
        Expressions.toString(Expressions.constant(new HashSet())));
  }

  @Test void testOneElementSetLiteral() throws Exception {
    assertEquals("com.google.common.collect.ImmutableSet.of(1)",
        Expressions.toString(Expressions.constant(Sets.newHashSet(1))));
  }

  @Test void testTwoElementsSetLiteral() throws Exception {
    assertEquals("com.google.common.collect.ImmutableSet.of(1,2)",
        Expressions.toString(Expressions.constant(ImmutableSet.of(1, 2))));
  }

  @Test void testTenElementsSetLiteral() throws Exception {
    Set set = new LinkedHashSet(); // for consistent output
    for (int i = 0; i < 10; i++) {
      set.add(i);
    }
    assertEquals("com.google.common.collect.ImmutableSet.builder().add(0)\n"
            + ".add(1)\n"
            + ".add(2)\n"
            + ".add(3)\n"
            + ".add(4)\n"
            + ".add(5)\n"
            + ".add(6)\n"
            + ".add(7)\n"
            + ".add(8)\n"
            + ".add(9).build()",
        Expressions.toString(Expressions.constant(set)));
  }

  @Test void testTenElementsLinkedHashSetLiteral() throws Exception {
    Set set = new LinkedHashSet(); // for consistent output
    for (Integer i = 0; i < 10; i++) {
      set.add(i);
    }
    assertEquals("com.google.common.collect.ImmutableSet.builder().add(0)\n"
            + ".add(1)\n"
            + ".add(2)\n"
            + ".add(3)\n"
            + ".add(4)\n"
            + ".add(5)\n"
            + ".add(6)\n"
            + ".add(7)\n"
            + ".add(8)\n"
            + ".add(9).build()",
        Expressions.toString(Expressions.constant(set)));
  }

  @Test void testTenElementsSetStringLiteral() throws Exception {
    Set set = new LinkedHashSet(); // for consistent output
    for (int i = 10; i > 0; i--) {
      set.add(String.valueOf(i));
    }
    assertEquals("com.google.common.collect.ImmutableSet.builder().add(\"10\")\n"
            + ".add(\"9\")\n"
            + ".add(\"8\")\n"
            + ".add(\"7\")\n"
            + ".add(\"6\")\n"
            + ".add(\"5\")\n"
            + ".add(\"4\")\n"
            + ".add(\"3\")\n"
            + ".add(\"2\")\n"
            + ".add(\"1\").build()",
        Expressions.toString(Expressions.constant(set)));
  }

  /** An enum. */
  enum MyEnum {
    X,
    Y {
      public String toString() {
        return "YYY";
      }
    }
  }

  public static int foo(int x) {
    return 0;
  }

  public static int bar(int v, int w, int x, int y, int z) {
    return 0;
  }

  /** A class with a field for each type of interest. */
  public static class AllType {
    public final boolean b;
    public final byte y;
    public final char c;
    public final short s;
    public final int i;
    public final long l;
    public final float f;
    public final double d;
    public final BigDecimal bd;
    public final BigInteger bi;
    public final String str;
    public final Object o;

    public AllType(boolean b, byte y, char c, short s, int i, long l, float f,
        double d, BigDecimal bd, BigInteger bi, String str, Object o) {
      this.b = b;
      this.y = y;
      this.c = c;
      this.s = s;
      this.i = i;
      this.l = l;
      this.f = f;
      this.d = d;
      this.bd = bd;
      this.bi = bi;
      this.str = str;
      this.o = o;
    }
  }
}
