/*
 * Copyright 2017 Google Inc.
 *
 * Licensed 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 com.google.gwt.dev.jjs.impl;

import com.google.gwt.dev.javac.testing.impl.JavaResourceBase;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.jjs.ast.JClassType;
import com.google.gwt.dev.jjs.ast.JConstructor;
import com.google.gwt.dev.jjs.ast.JInterfaceType;
import com.google.gwt.dev.jjs.ast.JMethod;
import com.google.gwt.dev.jjs.ast.JMethodBody;
import com.google.gwt.dev.jjs.ast.JPrimitiveType;
import com.google.gwt.dev.jjs.ast.JProgram;
import com.google.gwt.thirdparty.guava.common.base.Joiner;

import java.util.Collections;

/**
 * Tests that {@link com.google.gwt.dev.jjs.impl.GwtAstBuilder} correctly builds the AST for
 * features introduced in Java 8.
 */
public class Java8AstTest extends FullCompileTestBase {

  @Override
  public void setUp() throws Exception {
    super.setUp();
    addAll(LAMBDA_METAFACTORY);

    addAll(JavaResourceBase.createMockJavaResource("test.Runnable",
        "package test;",
        "public interface Runnable {",
        "  void run();",
        "}"
    ));
    addAll(JavaResourceBase.createMockJavaResource("test.Lambda",
        "package test;",
        "public interface Lambda<T> {",
        "  T run(int a, int b);",
        "}"
    ));
    addAll(JavaResourceBase.createMockJavaResource("test.Lambda2",
        "package test;",
        "public interface Lambda2<T> {",
        "  boolean run(T a, T b);",
        "}"
    ));
    addAll(JavaResourceBase.createMockJavaResource("test.AcceptsLambda",
        "package test;",
        "public class AcceptsLambda<T> {",
        "  public T accept(Lambda<T> foo) {",
        "    return foo.run(10, 20);",
        "  }",
        "  public boolean accept2(Lambda2<String> foo) {",
        "    return foo.run(\"a\", \"b\");",
        "  }",
        "}"
    ));

    addAll(JavaResourceBase.createMockJavaResource("test.Pojo",
        "package test;",
        "public class Pojo {",
        "  public Pojo(int x, int y) {",
        "  }",
        "  public Integer fooInstance(int a, int b) {",
        "    return a + b;",
        "  }",
        "}"
    ));

    addAll(JavaResourceBase.createMockJavaResource("test.DefaultInterface",
        "package test;",
        "public interface DefaultInterface {",
        "  void method1();",
        "  default int method2() { return 42; }",
        "}"
    ));

    addAll(JavaResourceBase.createMockJavaResource("test.DefaultInterfaceImpl",
        "package test;",
        "public class DefaultInterfaceImpl implements DefaultInterface {",
        "  public void method1() {}",
        "}"
    ));

    addAll(JavaResourceBase.createMockJavaResource("test.DefaultInterfaceImpl2",
        "package test;",
        "public class DefaultInterfaceImpl2 implements DefaultInterface {",
        "  public void method1() {}",
        "  public int method2() { return DefaultInterface.super.method2(); }",
        "}"
    ));
  }

  public void testCompileLambdaNoCapture() throws Exception {
    String lambda = "new AcceptsLambda<Integer>().accept((a,b) -> a + b);";
    assertEqualBlock(
        "(new AcceptsLambda()).accept(new EntryPoint$lambda$0$Type());",
        lambda
       );
    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    assertNotNull(getMethod(program, "lambda$0"));

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);

    // no fields
    assertEquals(0, lambdaInnerClass.getFields().size());

    // should have constructor taking no args
    JMethod ctor = findMethod(lambdaInnerClass, "EntryPoint$lambda$0$Type");
    assertTrue(ctor instanceof JConstructor);
    assertEquals(0, ctor.getParams().size());

    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));
    // should implement run method
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){return EntryPoint.lambda$0(arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testCompileLambdaCaptureLocal() throws Exception {
    String lambda = "int x = 42; new AcceptsLambda<Integer>().accept((a,b) -> x + a + b);";
    assertEqualBlock(
        "int x=42;(new AcceptsLambda()).accept(new EntryPoint$lambda$0$Type(x));",
        lambda
    );
    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    assertNotNull(getMethod(program, "lambda$0"));

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);

    // should have constructor taking x
    JMethod ctor = findMethod(lambdaInnerClass, "EntryPoint$lambda$0$Type");
    assertTrue(ctor instanceof JConstructor);
    assertEquals(1, ctor.getParams().size());
    assertEquals(JPrimitiveType.INT, ctor.getOriginalParamTypes().get(0));

    // should have 1 field to store the local
    assertEquals(1, lambdaInnerClass.getFields().size());
    assertEquals(JPrimitiveType.INT, lambdaInnerClass.getFields().get(0).getType());

    // should contain assignment statement of ctor param to field
    assertEquals("{this.x_0=x_0;}", formatSource(ctor.getBody().toSource()));
    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda as static function
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){" +
            "return EntryPoint.lambda$0(this.x_0,arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testCompileLambdaCaptureLocalWithBlockInLambda() throws Exception {
    String lambda =
        "int x = 42; "
        + "new AcceptsLambda<Integer>().accept((a,b) -> { int temp = x; return temp + a + b; });";
    assertEqualBlock(
        "int x=42;(new AcceptsLambda()).accept(new EntryPoint$lambda$0$Type(x));",
        lambda
    );
    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    assertNotNull(getMethod(program, "lambda$0"));

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);

    // should have constructor taking x
    JMethod ctor = findMethod(lambdaInnerClass, "EntryPoint$lambda$0$Type");
    assertTrue(ctor instanceof JConstructor);
    assertEquals(1, ctor.getParams().size());
    assertEquals(JPrimitiveType.INT, ctor.getOriginalParamTypes().get(0));

    // should have 1 field to store the local
    assertEquals(1, lambdaInnerClass.getFields().size());
    assertEquals(JPrimitiveType.INT, lambdaInnerClass.getFields().get(0).getType());

    // should contain assignment statement of ctor param to field
    assertEquals("{this.x_0=x_0;}", formatSource(ctor.getBody().toSource()));
    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda as static function
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){" +
            "return EntryPoint.lambda$0(this.x_0,arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  // test whether local capture and outer scope capture work together
  public void testCompileLambdaCaptureLocalAndField() throws Exception {
    addSnippetClassDecl("private int y = 22;");
    String lambda = "int x = 42; new AcceptsLambda<Integer>().accept((a,b) -> x + y + a + b);";
    assertEqualBlock(
        "int x=42;(new AcceptsLambda()).accept(new EntryPoint$lambda$0$Type(this,x));",
        lambda
    );
    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    assertNotNull(getMethod(program, "lambda$0"));

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);

    // should have constructor taking this and x
    JMethod ctor = findMethod(lambdaInnerClass, "EntryPoint$lambda$0$Type");
    assertTrue(ctor instanceof JConstructor);
    assertEquals(2, ctor.getParams().size());
    assertEquals(lambdaInnerClass.getEnclosingType(), ctor.getOriginalParamTypes().get(0));
    assertEquals(JPrimitiveType.INT, ctor.getOriginalParamTypes().get(1));

    // should have 2 field to store the outer and local
    assertEquals(2, lambdaInnerClass.getFields().size());
    assertEquals(lambdaInnerClass.getEnclosingType(),
        lambdaInnerClass.getFields().get(0).getType());
    assertEquals(JPrimitiveType.INT, lambdaInnerClass.getFields().get(1).getType());

    // should contain assignment statement of ctor params to field
    assertEquals("{this.$$outer_0=$$outer_0;this.x_1=x_1;}",
        formatSource(ctor.getBody().toSource()));
    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda via captured instance
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){" +
            "return this.$$outer_0.lambda$0(this.x_1,arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  // make sure nested scoping of identically named variables works
  public void testCompileLambdaCaptureOuterInnerField() throws Exception {
    addSnippetClassDecl("private int y = 22;");
    addSnippetClassDecl("class Foo { " +
          "int y = 42;" +
          "void m() {" +
          "new AcceptsLambda<Integer>().accept((a,b) -> EntryPoint.this.y + y + a + b); }" +
        " }");
    String lambda = "new Foo().m();";
    assertEqualBlock(
        "(new EntryPoint$Foo(this)).m();",
        lambda
    );
    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    JMethod lambdaMethod = findMethod(program.getFromTypeMap("test.EntryPoint$Foo"), "lambda$0");
    assertNotNull(lambdaMethod);
    assertEquals("{return Integer.valueOf(this.this$01.y+this.y+a_0+b_1);}",
        formatSource(lambdaMethod.getBody().toSource()));
    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$Foo$lambda$0$Type");
    assertNotNull(lambdaInnerClass);

    // should have constructor taking this
    JMethod ctor = findMethod(lambdaInnerClass, "EntryPoint$Foo$lambda$0$Type");
    assertTrue(ctor instanceof JConstructor);
    assertEquals(1, ctor.getParams().size());
    assertEquals(lambdaInnerClass.getEnclosingType(), ctor.getOriginalParamTypes().get(0));

    // should have 1 field to store the outer
    assertEquals(1, lambdaInnerClass.getFields().size());
    assertEquals(lambdaInnerClass.getEnclosingType(),
        lambdaInnerClass.getFields().get(0).getType());

    // should contain assignment statement of ctor params to field
    assertEquals("{this.$$outer_0=$$outer_0;}", formatSource(ctor.getBody().toSource()));
    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda via captured instance
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){return this.$$outer_0.lambda$0(arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testLambdaCaptureParameter() throws Exception {
    addSnippetClassDecl("interface ClickHandler {\n" +
        "    int onClick(int a);\n" +
        "  }\n" +
        "  private int addClickHandler(ClickHandler clickHandler) {\n" +
        "    return clickHandler.onClick(1);\n" +
        "  }\n" +
        "  private int addClickHandler(int a) {\n" +
        "    return addClickHandler(x->{int temp = a; return temp;});\n" +
        "  }\n");
    JProgram program = compileSnippet("int", "return addClickHandler(2);", false);
    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);

    // should have constructor taking the outer variable from parameter
    JMethod ctor = findMethod(lambdaInnerClass, "EntryPoint$lambda$0$Type");
    assertTrue(ctor instanceof JConstructor);
    assertEquals(1, ctor.getParams().size());
    assertEquals(JPrimitiveType.INT, ctor.getOriginalParamTypes().get(0));

    // should have 1 field to store the outer
    assertEquals(1, lambdaInnerClass.getFields().size());
    assertEquals(JPrimitiveType.INT,
        lambdaInnerClass.getFields().get(0).getType());

    // should contain assignment statement of ctor params to field
    assertEquals("{this.a_0=a_0;}", formatSource(ctor.getBody().toSource()));
    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(
        program.getFromTypeMap("test.EntryPoint$ClickHandler")));

    JMethod samMethod = findMethod(lambdaInnerClass, "onClick");
    assertEquals("public final int onClick(int a){return EntryPoint.lambda$0(this.a_0,a);}",
        formatSource(samMethod.toSource()));
  }

  public void testLambdaNestingCaptureLocal() throws Exception {
    addSnippetClassDecl("interface Inner {\n" +
        "    void f();\n" +
        "  }\n");
    addSnippetClassDecl(
        "  interface Outer {\n" +
        "     void accept(Inner t);\n" +
        "   }\n");
    addSnippetClassDecl(
        "  public static void call(Outer a) {\n" +
        "    a.accept(() -> {});\n" +
        "  }\n");
    String nestedLambda = "boolean[] success = new boolean[] {false};\n"
        + "call( sam1 -> { call(sam2 -> {success[0] = true;}); });";
    assertEqualBlock("boolean[]success=new boolean[]{false};"
        + "EntryPoint.call(new EntryPoint$lambda$1$Type(success));", nestedLambda);
    JProgram program = compileSnippet("void", nestedLambda, false);
    JClassType lambdaInnerClass1 = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    JClassType lambdaInnerClass2 = (JClassType) getType(program, "test.EntryPoint$lambda$1$Type");
    JClassType lambdaInnerClass3 = (JClassType) getType(program, "test.EntryPoint$lambda$2$Type");
    assertNotNull(lambdaInnerClass1);
    assertNotNull(lambdaInnerClass2);
    assertNotNull(lambdaInnerClass3);

    // check constructors
    JMethod ctor1 = findMethod(lambdaInnerClass1, "EntryPoint$lambda$0$Type");
    assertTrue(ctor1 instanceof JConstructor);
    assertEquals(0, ctor1.getParams().size());

    JMethod ctor2 = findMethod(lambdaInnerClass2, "EntryPoint$lambda$1$Type");
    assertTrue(ctor2 instanceof JConstructor);
    assertEquals(1, ctor2.getParams().size());
    assertEquals("boolean[]", ctor2.getOriginalParamTypes().get(0).getName());

    JMethod ctor3 = findMethod(lambdaInnerClass3, "EntryPoint$lambda$2$Type");
    assertTrue(ctor3 instanceof JConstructor);
    assertEquals(1, ctor3.getParams().size());
    assertEquals("boolean[]", ctor3.getOriginalParamTypes().get(0).getName());

    // check fields
    assertEquals(0, lambdaInnerClass1.getFields().size());

    assertEquals(1, lambdaInnerClass2.getFields().size());
    assertEquals("boolean[]",
        lambdaInnerClass2.getFields().get(0).getType().getName());

    assertEquals(1, lambdaInnerClass3.getFields().size());
    assertEquals("boolean[]",
        lambdaInnerClass3.getFields().get(0).getType().getName());

    // check constructor body
    assertEquals("{this.success_0=success_0;}", formatSource(ctor2.getBody().toSource()));
    assertEquals("{this.success_0=success_0;}", formatSource(ctor3.getBody().toSource()));

    // check super interface
    assertTrue(lambdaInnerClass1.getImplements().contains(
        program.getFromTypeMap("test.EntryPoint$Inner")));
    assertTrue(lambdaInnerClass2.getImplements().contains(
        program.getFromTypeMap("test.EntryPoint$Outer")));
    assertTrue(lambdaInnerClass3.getImplements().contains(
        program.getFromTypeMap("test.EntryPoint$Outer")));

    // check samMethod
    JMethod samMethod1 = findMethod(lambdaInnerClass2, "accept");
    JMethod samMethod2 = findMethod(lambdaInnerClass3, "accept");
    assertEquals(
        "public final void accept(EntryPoint$Inner t){EntryPoint.lambda$1(this.success_0,t);}",
        formatSource(samMethod1.toSource()));
    assertEquals(
        "public final void accept(EntryPoint$Inner t){EntryPoint.lambda$2(this.success_0,t);}",
        formatSource(samMethod2.toSource()));

    // check lambda method
    JMethod lambdaMethod1 = findMethod(program, "lambda$1");
    JMethod lambdaMethod2 = findMethod(program, "lambda$2");
    assertEquals(
        "private static void lambda$1(boolean[]success_0,EntryPoint$Inner sam1_1)"
        + "{{EntryPoint.call(new EntryPoint$lambda$2$Type(success_0));}}",
        formatSource(lambdaMethod1.toSource()));
    assertEquals(
        "private static void lambda$2(boolean[]success_0,EntryPoint$Inner sam2_1)"
        + "{{success_0[0]=true;}}",
        formatSource(lambdaMethod2.toSource()));
  }

  public void testLambdaNestingInAnonymousCaptureLocal() throws Exception {
    String lambda =
        "int x = 42;\n" +
        "new Runnable() { public void run() { Lambda<Integer> l = (a, b) -> x + a + b; l.run(1, 2); } }.run();";
    assertEqualBlock("int x=42;(new EntryPoint$1(this,x)).run();", lambda);
    JProgram program = compileSnippet("void", lambda, false);
    JClassType outerClass = (JClassType) getType(program, "test.EntryPoint$1");

    // check that anonymous class implementation uses synthetic field val$x2 to initialize lambda
    // synthetic class
    assertEquals(
        "public void run(){Lambda l=new EntryPoint$1$lambda$0$Type(this.val$x2);l.run(1,2);}",
        formatSource(findMethod(outerClass, "run").toSource()));
  }

  public void testLambdaNestingInMultipleAnonymousCaptureLocal() throws Exception {
    addSnippetClassDecl("interface I { int foo(Integer i); }");
    // checks that lambda has access to local variable and arguments when placed in local anonymous
    // class with multiple nesting
    String snippet =
        "int[] x = new int[] {42};\n" +
        "int result = new I(){\n" +
        "  public int foo(Integer i1){\n" +
        "    return new I(){\n" +
        "      public int foo(Integer i2){\n" +
        "        return new I(){\n" +
        "          public int foo(Integer i3){\n" +
        "            Lambda<Integer> l = (a, b) -> x[0] = x[0] + a + b + i1 + i2 + i3;\n" +
        "            return l.run(1, 2);\n" +
        "          }\n" +
        "        }.foo(3);\n" +
        "      }\n" +
        "    }.foo(2);\n" +
        "  }\n" +
        "}.foo(1);\n";

    JProgram program = compileSnippet("void", snippet, false);
    JClassType outer1 = (JClassType) getType(program, "test.EntryPoint$1");
    JClassType outer2 = (JClassType) getType(program, "test.EntryPoint$1$1");
    JClassType outer3 = (JClassType) getType(program, "test.EntryPoint$1$1$1");

    assertNotNull(outer1);
    assertNotNull(outer2);
    assertNotNull(outer3);

    JMethod outer1Method = findMethod(outer1, "foo");
    JMethod outer2Method = findMethod(outer2, "foo");
    JMethod outer3Method = findMethod(outer3, "foo");
    assertNotNull(outer3Method);
    assertEquals(
        "public int foo(Integer i1){"
        + "return(new EntryPoint$1$1(this,this.val$x2,i1)).foo(Integer.valueOf(2));"
        + "}",
        formatSource(outer1Method.toSource()));
    assertEquals(
        "public int foo(Integer i2){"
        + "return(new EntryPoint$1$1$1(this,this.val$x2,this.val$i13,i2)).foo(Integer.valueOf(3));"
        + "}",
        formatSource(outer2Method.toSource()));
    // checks that lambda scope initialized similar to anonymous class
    assertEquals(
        "public int foo(Integer i3){"
        + "Lambda l=new EntryPoint$1$1$1$lambda$0$Type(this.val$x2,this.val$i13,this.val$i24,i3);"
        + "return((Integer)l.run(1,2)).intValue();"
        + "}",
        formatSource(outer3Method.toSource()));
  }

  public void testLambdaNestingInMultipleMixedAnonymousCaptureLocal() throws Exception {
    // checks that lambda has access to local variable and arguments when placed in mixed scopes
    // Local Class -> Local Class -> Local Anonymous -> lambda -> Local Anonymous
    addSnippetClassDecl("interface I { int foo(Integer i); }");
    addSnippetClassDecl("class A {\n" +
      "int a() {\n" +
      "  int[] x = new int[] {42};\n" +
      "  class B {\n" +
      "    void b() {\n" +
      "      I i = new I(){\n" +
      "        public int foo(Integer arg){\n" +
      "          Runnable r = () ->{\n" +
      "            new Runnable() {\n" +
      "              public void run() {\n" +
      "                Lambda<Integer> l = (a, b) -> x[0] = x[0] + a + b + arg;\n" +
      "                x[0] = l.run(1, 2);\n" +
      "              }\n" +
      "            }.run();\n" +
      "          };\n" +
      "          r.run();\n" +
      "          return x[0];\n" +
      "        }\n" +
      "      };\n" +
      "      i.foo(1);\n" +
      "    }\n" +
      "  }\n" +
      "  B b = new B();\n" +
      "  b.b();\n" +
      "  return x[0];\n" +
      "}\n" +
    "}\n");

    String snippet = "A a = new A();";
    JProgram program = compileSnippet("void", snippet, false);
    JClassType lambdaOuter = (JClassType) getType(program, "test.EntryPoint$A$1B$1$1");
    assertNotNull(lambdaOuter);

    JMethod lambdaOuterMethod = findMethod(lambdaOuter, "run");
    assertNotNull(lambdaOuterMethod);
    // checks that lambda initialization properly uses synthetic fields from outer class
    assertEquals(
        "public void run(){"
        + "Lambda l=new EntryPoint$A$1B$1$1$lambda$0$Type(this.val$x2,this.val$arg3);"
        + "this.val$x2[0]=((Integer)l.run(1,2)).intValue();"
        + "}",
        formatSource(lambdaOuterMethod.toSource()));
  }

  public void testLambdaNestingCaptureField() throws Exception {
    addSnippetClassDecl("interface Inner {\n" +
        "    void f();\n" +
        "  }\n");
    addSnippetClassDecl(
        "  interface Outer {\n" +
        "     void accept(Inner t);\n" +
        "   }\n");
    addSnippetClassDecl(
        "  static class A {\n" +
        "    public boolean[] success = new boolean[] {false};\n" +
        "    public void call(Outer a) {\n" +
        "      a.accept(() -> {});\n" +
        "    }\n" +
        "  }\n");
    String nestedLambda = "A a = new A();\n"
        + "a.call( sam1 -> { a.call(sam2 -> {a.success[0] = true;}); });";
    assertEqualBlock("EntryPoint$A a=new EntryPoint$A();a.call(new EntryPoint$lambda$0$Type(a));",
        nestedLambda);
    JProgram program = compileSnippet("void", nestedLambda, false);
    JClassType lambdaInnerClass1 = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    JClassType lambdaInnerClass2 = (JClassType) getType(program, "test.EntryPoint$lambda$1$Type");
    assertNotNull(lambdaInnerClass1);
    assertNotNull(lambdaInnerClass2);

    // check constructors
    JMethod ctor1 = findMethod(lambdaInnerClass1, "EntryPoint$lambda$0$Type");
    assertTrue(ctor1 instanceof JConstructor);
    assertEquals(1, ctor1.getParams().size());
    assertEquals("test.EntryPoint$A", ctor1.getOriginalParamTypes().get(0).getName());

    JMethod ctor2 = findMethod(lambdaInnerClass2, "EntryPoint$lambda$1$Type");
    assertTrue(ctor2 instanceof JConstructor);
    assertEquals(1, ctor2.getParams().size());
    assertEquals("test.EntryPoint$A", ctor2.getOriginalParamTypes().get(0).getName());

    // check fields
    assertEquals(1, lambdaInnerClass1.getFields().size());
    assertEquals("test.EntryPoint$A", lambdaInnerClass2.getFields().get(0).getType().getName());

    assertEquals(1, lambdaInnerClass2.getFields().size());
    assertEquals("test.EntryPoint$A", lambdaInnerClass2.getFields().get(0).getType().getName());

    // check constructor body
    assertEquals("{this.a_0=a_0;}", formatSource(ctor2.getBody().toSource()));
    assertEquals("{this.a_0=a_0;}", formatSource(ctor2.getBody().toSource()));

    // check super interface
    assertTrue(lambdaInnerClass1.getImplements().contains(
        program.getFromTypeMap("test.EntryPoint$Outer")));
    assertTrue(lambdaInnerClass2.getImplements().contains(
        program.getFromTypeMap("test.EntryPoint$Outer")));

    // check samMethod
    JMethod samMethod1 = findMethod(lambdaInnerClass1, "accept");
    JMethod samMethod2 = findMethod(lambdaInnerClass2, "accept");
    assertEquals(
        "public final void accept(EntryPoint$Inner t){EntryPoint.lambda$0(this.a_0,t);}",
        formatSource(samMethod1.toSource()));
    assertEquals(
        "public final void accept(EntryPoint$Inner t){EntryPoint.lambda$1(this.a_0,t);}",
        formatSource(samMethod2.toSource()));

    // check lambda method
    JMethod lambdaMethod1 = findMethod(program, "lambda$0");
    JMethod lambdaMethod2 = findMethod(program, "lambda$1");
    assertEquals(
        "private static void lambda$0(EntryPoint$A a_0,EntryPoint$Inner sam1_1)"
        + "{{a_0.call(new EntryPoint$lambda$1$Type(a_0));}}",
        formatSource(lambdaMethod1.toSource()));
    assertEquals(
        "private static void lambda$1(EntryPoint$A a_0,EntryPoint$Inner sam2_1)"
        + "{{a_0.success[0]=true;}}",
        formatSource(lambdaMethod2.toSource()));
  }

  public void testCompileStaticReferenceBinding() throws Exception {
    addSnippetClassDecl("public static Integer foo(int x, int y) { return x + y; }");
    String lambda = "new AcceptsLambda<Integer>().accept(EntryPoint::foo);";

    String generatedInnerClassName = "test.EntryPoint$0methodref$foo$Type";
    String simpleLambdaInnerClassName = generatedInnerClassName.substring("test.".length());

    assertEqualBlock(
        "(new AcceptsLambda()).accept(new " + simpleLambdaInnerClassName + "());", lambda);
    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    assertNotNull(getMethod(program, "foo"));

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, generatedInnerClassName);
    assertNotNull(lambdaInnerClass);

    // should have constructor taking this and x
    JMethod ctor = findMethod(lambdaInnerClass,
        simpleLambdaInnerClassName);
    assertTrue(ctor instanceof JConstructor);
    // no ctor args
    assertEquals(0, ctor.getParams().size());

    // no fields
    assertEquals(0, lambdaInnerClass.getFields().size());

    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda via captured instance
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){return EntryPoint.foo(arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testCompileInstanceReferenceBinding() throws Exception {
    addSnippetClassDecl("public Integer foo(int x, int y) { return x + y; }");
    String lambda = "new AcceptsLambda<Integer>().accept(this::foo);";

    String generatedInnerClassName = "test.EntryPoint$0methodref$foo$Type";
    String simpleLambdaInnerClassName = generatedInnerClassName.substring("test.".length());

    assertEqualBlock(
        "(new AcceptsLambda()).accept(new " + simpleLambdaInnerClassName + "(this));",
        lambda
    );
    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    assertNotNull(getMethod(program, "foo"));

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, generatedInnerClassName);
    assertNotNull(lambdaInnerClass);

    // should have constructor taking this and x
    JMethod ctor = findMethod(lambdaInnerClass,  simpleLambdaInnerClassName);
    assertTrue(ctor instanceof JConstructor);
    // instance capture
    assertEquals(1, ctor.getParams().size());
    assertEquals(lambdaInnerClass.getEnclosingType(), ctor.getOriginalParamTypes().get(0));

    // should have 1 field to store the captured instance
    assertEquals(1, lambdaInnerClass.getFields().size());
    assertEquals(lambdaInnerClass.getEnclosingType(),
        lambdaInnerClass.getFields().get(0).getType());

    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda via captured instance
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){return this.$$outer_0.foo(arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testCompileInstanceReferenceBindingMultiple() throws Exception {
    addSnippetClassDecl("Pojo instance1 = new Pojo(1, 2);");
    addSnippetClassDecl("Pojo instance2 = new Pojo(3, 4);");
    String reference =
        "new AcceptsLambda<Integer>().accept(instance1::fooInstance);\n" +
        "new AcceptsLambda<Integer>().accept(instance2::fooInstance);";

    String generatedInnerClassName = "test.EntryPoint$0methodref$fooInstance$Type";
    String simpleLambdaInnerClassName1 = generatedInnerClassName.substring("test.".length());
    String simpleLambdaInnerClassName2 = "EntryPoint$1methodref$fooInstance$Type";

    assertEqualBlock(
        "(new AcceptsLambda()).accept(new " + simpleLambdaInnerClassName1 + "(this.instance1));\n"
        + "(new AcceptsLambda()).accept(new " + simpleLambdaInnerClassName2 + "(this.instance2));",
        reference);
    JProgram program = compileSnippet("void", reference, false);

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, generatedInnerClassName);
    assertNotNull(lambdaInnerClass);
    assertEquals(1, Collections.frequency(program.getDeclaredTypes(), lambdaInnerClass));

    // should have constructor taking the instance
    JMethod ctor = findMethod(lambdaInnerClass, simpleLambdaInnerClassName1);
    assertTrue(ctor instanceof JConstructor);
    // instance capture
    assertEquals(1, ctor.getParams().size());
    // should have 1 field to store the captured instance
    assertEquals(1, lambdaInnerClass.getFields().size());
    assertEquals(lambdaInnerClass.getFields().get(0).getType(),
        ctor.getOriginalParamTypes().get(0));

    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda via captured instance
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){return this.$$outer_0.fooInstance(arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testCompileInstanceReferenceBindingMultipleWithSameMethodSignature() throws Exception {
    addSnippetClassDecl(
        "static class TestMF_A {",
        "  public String getId() {",
        "    return \"A\";",
        "  }",
        "}",

        "static class TestMF_B {",
        "  public String getId() {",
        "    return \"B\";",
        "  }",
        "}",

        "interface Function<T> {",
        "  T apply();",
        "}",

        "private String f(Function<String> arg) {",
        "    return arg.apply();",
        "  }");

    String reference = Joiner.on('\n').join(
        "TestMF_A a = new TestMF_A();",
        "TestMF_B b = new TestMF_B();",
        "f(a::getId);",
        "f(b::getId);"
    );

    String generatedInnerClassNameForA = "test.EntryPoint$0methodref$getId$Type";
    String simpleLambdaInnerClassNameForA =
        generatedInnerClassNameForA.substring("test.".length());

    String generatedInnerClassNameForB = "test.EntryPoint$1methodref$getId$Type";
    String simpleLambdaInnerClassNameForB =
        generatedInnerClassNameForB.substring("test.".length());

    assertEqualBlock(
        "EntryPoint$TestMF_A a=new EntryPoint$TestMF_A();"
            + "EntryPoint$TestMF_B b=new EntryPoint$TestMF_B();"
            + "this.f(new " + simpleLambdaInnerClassNameForA + "(a));"
            + "this.f(new " + simpleLambdaInnerClassNameForB + "(b));",
        reference);
    JProgram program = compileSnippet("void", reference, false);

    // created by GwtAstBuilder
    JClassType innerClassA = (JClassType) getType(program, generatedInnerClassNameForA);
    JClassType innerClassB = (JClassType) getType(program, generatedInnerClassNameForB);
    assertNotNull(innerClassA);
    assertNotNull(innerClassB);

    // should have constructor taking this and x
    JMethod ctorA = findMethod(innerClassA, simpleLambdaInnerClassNameForA);
    assertTrue(ctorA instanceof JConstructor);
    // instance capture
    assertEquals(1, ctorA.getParams().size());
    assertEquals("test.EntryPoint$TestMF_A", ctorA.getOriginalParamTypes().get(0).getName());
    JMethod ctorB = findMethod(innerClassB, simpleLambdaInnerClassNameForB);
    assertTrue(ctorB instanceof JConstructor);
    // instance capture
    assertEquals(1, ctorB.getParams().size());
    assertEquals("test.EntryPoint$TestMF_B", ctorB.getOriginalParamTypes().get(0).getName());

    // should have 1 field to store the captured instance
    assertEquals(1, innerClassA.getFields().size());
    assertEquals("test.EntryPoint$TestMF_A",
        innerClassA.getFields().get(0).getType().getName());
    assertEquals(1, innerClassB.getFields().size());
    assertEquals("test.EntryPoint$TestMF_B",
        innerClassB.getFields().get(0).getType().getName());

    // should extends EntryPoint$Function
    assertTrue(
        innerClassA.getImplements().contains(program.getFromTypeMap("test.EntryPoint$Function")));
    assertTrue(
        innerClassB.getImplements().contains(program.getFromTypeMap("test.EntryPoint$Function")));

    // should implement apply method
    JMethod samMethodA = findMethod(innerClassA, "apply");
    assertEquals(
        "public final Object apply(){return this.$$outer_0.getId();}",
        formatSource(samMethodA.toSource()));
    JMethod samMethodB = findMethod(innerClassB, "apply");
    assertEquals(
        "public final Object apply(){return this.$$outer_0.getId();}",
        formatSource(samMethodB.toSource()));
  }

  public void testCompileStaticReferenceBindingMultiple() throws Exception {
    addSnippetClassDecl(
        "static class TestMF_A {",
        "  public static String getId() {",
        "    return \"A\";",
        "  }",
        "}",

        "static class TestMF_B {",
        "  public static String getId() {",
        "    return \"B\";",
        "  }",
        "}",

        "interface Function<T> {",
        "  T apply();",
        "}",

        "private String f(Function<String> arg) {",
        "    return arg.apply();",
        "  }");
    String reference = "f(TestMF_A::getId);\n" + "f(TestMF_B::getId);";

    String generatedInnerClassNameForA = "test.EntryPoint$0methodref$getId$Type";
    String simpleLambdaInnerClassNameForA =
        generatedInnerClassNameForA.substring("test.".length());

    String generatedInnerClassNameForB = "test.EntryPoint$1methodref$getId$Type";
    String simpleLambdaInnerClassNameForB =
        generatedInnerClassNameForB.substring("test.".length());

    assertEqualBlock("this.f(new " + simpleLambdaInnerClassNameForA + "());" +
            "this.f(new " + simpleLambdaInnerClassNameForB + "());",
        reference);
    JProgram program = compileSnippet("void", reference, false);

    // created by GwtAstBuilder
    JClassType innerClassA = (JClassType) getType(program, generatedInnerClassNameForA);
    JClassType innerClassB = (JClassType) getType(program, generatedInnerClassNameForB);
    assertNotNull(innerClassA);
    assertNotNull(innerClassB);

    // should extends EntryPoint$Function
    assertTrue(
        innerClassA.getImplements().contains(program.getFromTypeMap("test.EntryPoint$Function")));
    assertTrue(
        innerClassB.getImplements().contains(program.getFromTypeMap("test.EntryPoint$Function")));

    // should implement apply method
    JMethod samMethodA = findMethod(innerClassA, "apply");
    assertEquals(
        "public final Object apply(){return EntryPoint$TestMF_A.getId();}",
        formatSource(samMethodA.toSource()));
    JMethod samMethodB = findMethod(innerClassB, "apply");
    assertEquals(
        "public final Object apply(){return EntryPoint$TestMF_B.getId();}",
        formatSource(samMethodB.toSource()));
  }

  public void testCompileImplicitQualifierReferenceBinding() throws Exception {
    String lambda = "new AcceptsLambda<String>().accept2(String::equalsIgnoreCase);";

    String generatedInnerClassName = "test.EntryPoint$0methodref$equalsIgnoreCase$Type";
    String simpleLambdaInnerClassName =
        generatedInnerClassName.substring("test.".length());

    assertEqualBlock(
        "(new AcceptsLambda()).accept2(new " +  simpleLambdaInnerClassName + " ());",
        lambda
    );
    JProgram program = compileSnippet("void", lambda, false);

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, generatedInnerClassName);
    assertNotNull(lambdaInnerClass);

    // should have constructor taking this and x
    JMethod ctor = findMethod(lambdaInnerClass, simpleLambdaInnerClassName);
    assertTrue(ctor instanceof JConstructor);
    // no instance capture
    assertEquals(0, ctor.getParams().size());

    // no fields
    assertEquals(0, lambdaInnerClass.getFields().size());

    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda2")));

    // should implement run method and invoke lambda via captured instance
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final boolean run(Object arg0,Object arg1)"
            + "{return((String)arg0).equalsIgnoreCase((String)arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testCompileConstructorReferenceBinding() throws Exception {
    String lambda = "new AcceptsLambda<Pojo>().accept(Pojo::new);";

    String generatedInnerClassName = "test.EntryPoint$0methodref$ctor$Type";
    String simpleLambdaInnerClassName =
        generatedInnerClassName.substring("test.".length());

    assertEqualBlock(
        "(new AcceptsLambda()).accept(new " + simpleLambdaInnerClassName + "());",
        lambda
    );
    JProgram program = compileSnippet("void", lambda, false);

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, generatedInnerClassName);
    assertNotNull(lambdaInnerClass);

    // should have constructor taking this and x
    JMethod ctor = findMethod(lambdaInnerClass, simpleLambdaInnerClassName);
    assertTrue(ctor instanceof JConstructor);
    // no instance capture
    assertEquals(0, ctor.getParams().size());

    // no fields
    assertEquals(0, lambdaInnerClass.getFields().size());

    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda via captured instance
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){return new Pojo(arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testCompileConstructorReferenceBindingWithEnclosingInstanceCapture()
      throws Exception {
    addSnippetClassDecl(
        "int field1, field2;",

        "class Pojo2 {",
        "  public Pojo2(int x, int y) {",
        "  }",
        "  public int someMethod() { ",
        "    return field1 + field2; ",
        "  }",
        "}"
    );

    String lambda = "new AcceptsLambda<Pojo2>().accept(Pojo2::new);";

    String generatedInnerClassName = "test.EntryPoint$0methodref$ctor$Type";
    String simpleLambdaInnerClassName =
        generatedInnerClassName.substring("test.".length());

    assertEqualBlock("(new AcceptsLambda()).accept(new " + simpleLambdaInnerClassName + "(this));",
        lambda
    );
    JProgram program = compileSnippet("void", lambda, false);

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, generatedInnerClassName);
    assertNotNull(lambdaInnerClass);

    // should have constructor taking this and x
    JMethod ctor = findMethod(lambdaInnerClass, simpleLambdaInnerClassName);
    assertTrue(ctor instanceof JConstructor);
    // one instance capture
    assertEquals(1, ctor.getParams().size());

    // one field for instance
    assertEquals(1, lambdaInnerClass.getFields().size());

    // should extends test.Lambda
    assertTrue(lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.Lambda")));

    // should implement run method and invoke lambda via captured instance
    JMethod samMethod = findMethod(lambdaInnerClass, "run");
    assertEquals(
        "public final Object run(int arg0,int arg1){"
            + "return new EntryPoint$Pojo2(this.test_EntryPoint,arg0,arg1);}",
        formatSource(samMethod.toSource()));
  }

  public void testIntersectionCast() throws Exception {
    addSnippetClassDecl("static class A {void print() {} }");
    addSnippetClassDecl("interface I1 {}");
    addSnippetClassDecl("interface I2 {}");
    addSnippetClassDecl("interface I3 {}");
    addSnippetClassDecl("static class B extends A implements I1 {}");
    addSnippetClassDecl("static class C extends A implements I1, I2, I3 {}");
    String cast1 = "B b = new B(); ((A & I1) b).print();";
    assertEqualBlock("EntryPoint$B b=new EntryPoint$B();((EntryPoint$A)(EntryPoint$I1)b).print();",
        cast1);
    String cast2 = "C c = new C(); ((A & I1 & I2 & I3)c).print();";
    assertEqualBlock("EntryPoint$C c=new EntryPoint$C();"
        + "((EntryPoint$A)(EntryPoint$I1)(EntryPoint$I2)(EntryPoint$I3)c).print();", cast2);
  }

  public void testIntersectionCastOfLambda() throws Exception {
    addSnippetClassDecl("interface I1 { public void foo(); }");
    addSnippetClassDecl("interface I2 { }");
    String lambda = "Object o = (I2 & I1) () -> {};";
    assertEqualBlock("Object o=(EntryPoint$I2)(EntryPoint$I1)new EntryPoint$lambda$0$Type();",
        lambda);

    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    assertNotNull(getMethod(program, "lambda$0"));

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);

    // no fields
    assertEquals(0, lambdaInnerClass.getFields().size());

    // should have constructor taking no args
    JMethod ctor = findMethod(lambdaInnerClass, "EntryPoint$lambda$0$Type");
    assertTrue(ctor instanceof JConstructor);
    assertEquals(0, ctor.getParams().size());

    // should implements I1 and I2
    assertTrue(
        lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I1")));
    assertTrue(
        lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I2")));
    // should implement foo method
    JMethod samMethod = findMethod(lambdaInnerClass, "foo");
    assertEquals("public final void foo(){EntryPoint.lambda$0();}",
        formatSource(samMethod.toSource()));
  }

  public void testMultipleIntersectionCastOfLambda() throws Exception {
    addSnippetClassDecl("interface I1 { public void foo(); }");
    addSnippetClassDecl("interface I2 { }");
    addSnippetClassDecl("interface I3 { }");
    String lambda = "I2 o = (I3 & I2 & I1) () -> {};";
    assertEqualBlock(
        "EntryPoint$I2 o=(EntryPoint$I3)(EntryPoint$I2)(EntryPoint$I1)new EntryPoint$lambda$0$Type();",
        lambda);

    JProgram program = compileSnippet("void", lambda, false);
    // created by JDT, should exist
    assertNotNull(getMethod(program, "lambda$0"));

    // created by GwtAstBuilder
    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);

    // no fields
    assertEquals(0, lambdaInnerClass.getFields().size());

    // should have constructor taking no args
    JMethod ctor = findMethod(lambdaInnerClass, "EntryPoint$lambda$0$Type");
    assertTrue(ctor instanceof JConstructor);
    assertEquals(0, ctor.getParams().size());

    // should extends java.lang.Object, implements I1, I2 and I3
    assertEquals("java.lang.Object", lambdaInnerClass.getSuperClass().getName());
    assertTrue(
        lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I1")));
    assertTrue(
        lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I2")));
    assertTrue(
        lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I3")));
    // should implement foo method
    JMethod samMethod = findMethod(lambdaInnerClass, "foo");
    assertEquals("public final void foo(){EntryPoint.lambda$0();}",
        formatSource(samMethod.toSource()));
  }

  public void testIntersectionCastOfLambdaOneAbstractMethod() throws Exception {
    addSnippetClassDecl("interface I1 { public void foo(); }");
    addSnippetClassDecl("interface I2 extends I1{ public void foo();}");
    String lambda = "Object o = (I1 & I2) () -> {};";
    // (I1 & I2) is resolved to I2 by JDT.
    assertEqualBlock("Object o=(EntryPoint$I2)new EntryPoint$lambda$0$Type();",
        lambda);

    JProgram program = compileSnippet("void", lambda, false);

    assertNotNull(getMethod(program, "lambda$0"));

    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);
    assertEquals("java.lang.Object", lambdaInnerClass.getSuperClass().getName());
    assertEquals(1, lambdaInnerClass.getImplements().size()); // only implements I2.
    assertTrue(
        lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I2")));
    // should implement foo method
    JMethod samMethod = findMethod(lambdaInnerClass, "foo");
    assertEquals("public final void foo(){EntryPoint.lambda$0();}",
        formatSource(samMethod.toSource()));
  }

  public void testIntersectionCastMultipleAbstractMethods() throws Exception {
    addSnippetClassDecl("interface I1 { public void foo(); }");
    addSnippetClassDecl("interface I2 { public void foo(); }");
    String lambda = "Object o = (I1 & I2) () -> {};";
    assertEqualBlock("Object o=(EntryPoint$I1)(EntryPoint$I2)new EntryPoint$lambda$0$Type();",
        lambda);

    JProgram program = compileSnippet("void", lambda, false);

    assertNotNull(getMethod(program, "lambda$0"));

    JClassType lambdaInnerClass = (JClassType) getType(program, "test.EntryPoint$lambda$0$Type");
    assertNotNull(lambdaInnerClass);
    assertEquals("java.lang.Object", lambdaInnerClass.getSuperClass().getName());
    assertEquals(2, lambdaInnerClass.getImplements().size());
    assertTrue(
        lambdaInnerClass.getImplements().contains(program.getFromTypeMap("test.EntryPoint$I1")));
    // should implement foo method
    JMethod samMethod = findMethod(lambdaInnerClass, "foo");
    assertEquals("public final void foo(){EntryPoint.lambda$0();}",
        formatSource(samMethod.toSource()));
  }

  private static final MockJavaResource LAMBDA_METAFACTORY =
      JavaResourceBase.createMockJavaResource("java.lang.invoke.LambdaMetafactory",
          "package java.lang.invoke;",
          "public class LambdaMetafactory {",
          "}");

  public void testDefaultInterfaceMethod() throws Exception {
    JProgram program = compileSnippet("void", "(new DefaultInterfaceImpl()).method2();", false);

    // created by GwtAstBuilder
    JInterfaceType intf = (JInterfaceType) getType(program, "test.DefaultInterface");
    // should have an actual method with body on it
    JMethod defaultMethod = findMethod(intf, "method2");
    assertNotNull(defaultMethod);
    assertNotNull(defaultMethod.getBody());
    assertEquals(1, ((JMethodBody) defaultMethod.getBody()).getBlock().getStatements().size());
  }

  public void testDefaultInterfaceMethodSuperResolution() throws Exception {
    JProgram program = compileSnippet("void", "new DefaultInterfaceImpl2();", false);
    // created by GwtAstBuilder
    JClassType clazz = (JClassType) getType(program, "test.DefaultInterfaceImpl2");
    JMethod defaultMethod = findMethod(clazz, "method2");
    assertNotNull(defaultMethod);
    assertNotNull(defaultMethod.getBody());
    assertEquals("{return this.DefaultInterface.method2();}",
        formatSource(defaultMethod.getBody().toSource()));
  }

  /**
   * Regression test for issue 9190.
   */
  public void testMethodHandlerLambdaFromDifferentCompilationUnits() throws Exception {
    MockJavaResource interfaceF =
        JavaResourceBase.createMockJavaResource("test.F",
            "package test;",
            "@FunctionalInterface",
            "public interface F {",
            "  boolean eval();",
            "}");
    MockJavaResource classOne =
        JavaResourceBase.createMockJavaResource("test.ClassOne",
            "package test;",
            "public class ClassOne {",
            "  public boolean m() { return true; }",
            "  public static boolean evaluateF(F f) { return f.eval(); }",
            "  public boolean evaluateM() {",
            "    ClassOne a = new ClassOne();",
            "    return evaluateF(this::m);",
            "  }",
            "}");

    String entryPointClass = Joiner.on('\n').join(
        "package test;",
        "public class EntryPoint {",
        "  public static void onModuleLoad() {",
        "    ClassOne classOne = new ClassOne();",
        "    ClassOne.evaluateF(classOne::m);",
        "    new ClassOne().evaluateM();",
        "  }",
        "}");

    addAll(interfaceF, classOne);

    // Compiling the snippet to Javascript makes sure JavaScript generation does not trigger the
    // assertion in {@link GenerateJavaScriptAST.CreateNamesAndScopesVisitor#recordSymbol}.
    //
    // Also just performing the compile asserts that the AST is well formed.
    compileSnippetToJS(entryPointClass);
  }

  @Override
  protected void optimizeJava() {
  }
}
