/*
 * 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.dev.util.arg.SourceLevel;
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 {
    sourceLevel = SourceLevel.JAVA9;
    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() {
  }
}
