Skip to content

Commit

Permalink
[WASM] JsInterop - Fix an issue with static native method overloading.
Browse files Browse the repository at this point in the history
We incorrectly throw an error when we encounter 2 native jsmethod overloads with differing parameter counts. Example:

  @JsMethod
  public static native int test();

  @JsMethod
  public static native int test(int n);

These two generate the same import, because we use a method reference, and so there should be no conflict.

PiperOrigin-RevId: 551897267
  • Loading branch information
Googler authored and copybara-github committed Jul 28, 2023
1 parent 4701336 commit 02b12ae
Show file tree
Hide file tree
Showing 9 changed files with 653 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,11 @@ private void addMethodImport(JsMethodImport newImport) {
existingImport.getImportKey());
}

if (!newImport.getSignature().equals(existingImport.getSignature())) {
if (!newImport.getSignature().equals(existingImport.getSignature())
// Signature doesn't matter if the method import is emitted as a method
// reference. Exclude these in this check.
&& !(newImport.emitAsMethodReference()
&& existingImport.emitAsMethodReference())) {
problems.error(
newImport.getMethod().getSourcePosition(),
"Native methods '%s' and '%s', importing JavaScript method '%s', have"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,32 @@ load(
"//transpiler/javatests/com/google/j2cl/integration:integration_test.bzl",
"integration_test",
)
load("//build_defs:rules.bzl", "j2wasm_library")

package(
default_applicable_licenses = ["//:j2cl_license"],
licenses = ["notice"],
)

j2wasm_library(
name = "staticjsmethods-j2wasm",
srcs = glob(
[
"*.java",
"*.js",
],
exclude = [
# .native.js not supported in Wasm.
"Main.native.js",
],
),
deps = [
"//jre/java:javaemul_internal_annotations-j2wasm",
"//third_party:gwt-jsinterop-annotations-j2wasm",
"//transpiler/javatests/com/google/j2cl/integration/testing:testing-j2wasm",
],
)

integration_test(
name = "staticjsmethods",
srcs = glob([
Expand All @@ -17,5 +37,4 @@ integration_test(
# Contains JsInterop features which are only applicable for JS output.
enable_jvm_test = False,
enable_kt = False,
enable_wasm = False,
)
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import static com.google.j2cl.integration.testing.Asserts.assertTrue;
import static jsinterop.annotations.JsPackage.GLOBAL;

import javaemul.internal.annotations.Wasm;
import jsinterop.annotations.JsMethod;

public class Main {
Expand All @@ -36,6 +37,7 @@ public static void testJsMethodsCalledByJava() {
assertTrue(f2(1) == 23);
}

@Wasm("nop") // .native.js not supported in Wasm.
public static void testJsMethodsCalledByJS() {
assertTrue(callF1(1) == 12);
assertTrue(callF2(1) == 23);
Expand All @@ -50,6 +52,9 @@ public static void testNativeJsMethod() {
assertTrue(floor(1.5) == 1);
assertTrue(f3(-1) == 1);
assertTrue(isFinite(1.0));
assertTrue(max(2, 3) == 3);
assertTrue(max(2, 3, 4) == 4);
assertTrue(max(2.0, 3.0) == 3.0);
}

public static void testDeepNamespaceNativeJsMethod() {
Expand All @@ -65,9 +70,11 @@ public static void main(String... args) {
}

@JsMethod
@Wasm("nop")
public static native int callF1(int a);

@JsMethod
@Wasm("nop")
public static native int callF2(int a);

@JsMethod(namespace = GLOBAL, name = "Math.floor")
Expand All @@ -76,6 +83,15 @@ public static void main(String... args) {
@JsMethod(namespace = GLOBAL, name = "Math.abs")
public static native int f3(int d);

@JsMethod(namespace = GLOBAL, name = "Math.max")
public static native int max(int a, int b);

@JsMethod(namespace = GLOBAL, name = "Math.max")
public static native int max(int a, int b, int c);

@JsMethod(namespace = GLOBAL, name = "Math.max")
public static native double max(double a, double b);

@JsMethod(namespace = GLOBAL, name = "isFinite")
public static native boolean isFinite(double d);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ readable_example(
]),
# TODO(b/202515129): Allow dependencies on native code (like js & iOS) in J2KT.
generate_kt_readables = False,
generate_wasm_readables = False,
generate_wasm_imports = True,
deps = ["//third_party:gwt-jsinterop-annotations-j2cl"],
)
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,15 @@ public static void f2(int a) {}
@JsMethod(namespace = "foo.Baz", name = "baz")
public static native boolean f6();

@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.max")
public static native int max(int a, int b);

@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.max")
public static native int max(int a, int b, int c);

@JsMethod(namespace = JsPackage.GLOBAL, name = "Math.max")
public static native double max(double a, double b);

public void test() {
StaticJsMembers.f1(1);
f1(1);
Expand All @@ -76,6 +85,12 @@ public void test() {
f4(1.1);
StaticJsMembers.f5();
f5();
StaticJsMembers.max(1, 2);
max(1, 2);
StaticJsMembers.max(1, 2, 3);
max(1, 2, 3);
StaticJsMembers.max(1.0, 2.0);
max(1.0, 2.0);

int n = field1;
n = field2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ class StaticJsMembers extends j_l_Object {
isFinite(1.1);
Bar.baz();
Bar.baz();
Math.max(1, 2);
Math.max(1, 2);
Math.max(1, 2, 3);
Math.max(1, 2, 3);
Math.max(1, 2);
Math.max(1, 2);
let n = StaticJsMembers.$static_field1__staticjsmembers_StaticJsMembers;
n = StaticJsMembers.$static_field2__staticjsmembers_StaticJsMembers;
n = Math.PI;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
[f4(1.1);] => [isFinite(1.1);] "staticjsmembers.StaticJsMembers.test"
[StaticJsMembers.f5();] => [Bar.baz();] "staticjsmembers.StaticJsMembers.test"
[f5();] => [Bar.baz();] "staticjsmembers.StaticJsMembers.test"
[StaticJsMembers.max(1, 2);] => [Math.max(1, 2);] "staticjsmembers.StaticJsMembers.test"
[max(1, 2);] => [Math.max(1, 2);] "staticjsmembers.StaticJsMembers.test"
[StaticJsMembers.max(1, 2, 3);] => [Math.max(1, 2, 3);] "staticjsmembers.StaticJsMembers.test"
[max(1, 2, 3);] => [Math.max(1, 2, 3);] "staticjsmembers.StaticJsMembers.test"
[StaticJsMembers.max(1.0, 2.0);] => [Math.max(1, 2);] "staticjsmembers.StaticJsMembers.test"
[max(1.0, 2.0);] => [Math.max(1, 2);] "staticjsmembers.StaticJsMembers.test"
[int n = field1;] => [let n = StaticJsMembers.$static_field1__staticjsmembers_StaticJsMembers;] "staticjsmembers.StaticJsMembers.test"
[n] => [n] "n"
[n = field2;] => [n = StaticJsMembers.$static_field2__staticjsmembers_StaticJsMembers;] "staticjsmembers.StaticJsMembers.test"
Expand Down
Loading

0 comments on commit 02b12ae

Please sign in to comment.