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;
}