Fix bad codegen for lambdas in JsOverlay methods.

The fix is a bit of a hack, a better solution would be
not to mimic the placement of the lambda implematation
by JDT, which is done that way out of necesity (as
lambdas are created dynamically via a factory), and
instead synthesize the method in the anonymous inner
class that is already synthesized to represent the
lambda in GWT.

Bug: #9354
Bug-Link: http://github.com/gwtproject/gwt/issues/9354
Change-Id: I749c5ef1356ae5e0ec6a8f2dcabbaa15e4001f9a
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
index fa7c8a0..a97e53d 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/GwtAstBuilder.java
@@ -26,6 +26,7 @@
 import com.google.gwt.dev.jjs.SourceOrigin;
 import com.google.gwt.dev.jjs.ast.AccessModifier;
 import com.google.gwt.dev.jjs.ast.CanHaveSuppressedWarnings;
+import com.google.gwt.dev.jjs.ast.HasJsInfo;
 import com.google.gwt.dev.jjs.ast.JArrayLength;
 import com.google.gwt.dev.jjs.ast.JArrayRef;
 import com.google.gwt.dev.jjs.ast.JArrayType;
@@ -1114,6 +1115,12 @@
       // JDT synthesizes a method lambda$n(capture1, capture2, ..., lambda_arg1, lambda_arg2, ...)
       // Here we create a JMethod from this
       JMethod lambdaMethod = createMethodFromBinding(info, x.binding, paramNames);
+      // Because the lambda implementations is synthesized as a static method in the
+      // enclosing class, it needs to be adjusted if that class happens to be a JsType.
+      lambdaMethod.setJsMemberInfo(HasJsInfo.JsMemberType.NONE, null, null, false);
+      if (curClass.type.isJsNative()) {
+        lambdaMethod.setJsOverlay();
+      }
       JMethodBody methodBody = new JMethodBody(info);
       lambdaMethod.setBody(methodBody);
       // We need to push this method  on the stack as it introduces a scope, and
@@ -1332,7 +1339,6 @@
       // First let's get that synthetic method we created in the visit() call on the
       // containing class?
       JMethod lambdaMethod = curMethod.method;
-
       // And pop off the body nodes of the LambdaExpression that was processed as children
       // Deal with any boxing/unboxing needed
       JNode node = pop();
diff --git a/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java8Test.java b/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java8Test.java
index 91a9183..5c9d601 100644
--- a/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java8Test.java
+++ b/user/test-super/com/google/gwt/dev/jjs/super/com/google/gwt/dev/jjs/test/Java8Test.java
@@ -1564,4 +1564,16 @@
     assertEquals(5,
         ((MyIntFuncToSomeIntegeFunction2) SomeInteger::new).apply(5, addInteger).m1());
   }
+
+  @JsType(isNative = true)
+  private static class NativeClassWithJsOverlay {
+    @JsOverlay
+    public static String m(String s) {
+      MyFunction1<String, String> id = (a) -> a;
+      return id.apply(s);
+    }
+  }
+  public void testNativeJsOverlay_lambda() {
+    assertSame("Hello", NativeClassWithJsOverlay.m("Hello"));
+  }
 }
diff --git a/user/test/com/google/gwt/dev/jjs/test/Java8Test.java b/user/test/com/google/gwt/dev/jjs/test/Java8Test.java
index 3c360f1..1fda5c6 100644
--- a/user/test/com/google/gwt/dev/jjs/test/Java8Test.java
+++ b/user/test/com/google/gwt/dev/jjs/test/Java8Test.java
@@ -288,6 +288,10 @@
     assertFalse(isGwtSourceLevel8());
   }
 
+  public void testNativeJsOverlay_lambda() {
+    assertFalse(isGwtSourceLevel8());
+  }
+
   private boolean isGwtSourceLevel8() {
     return JUnitShell.getCompilerOptions().getSourceLevel().compareTo(SourceLevel.JAVA8) >= 0;
   }