From 5ecfb3620c295c5e10a4e153bd91253ca9cd9674 Mon Sep 17 00:00:00 2001 From: marciodel Date: Mon, 29 May 2017 10:08:40 -0300 Subject: [PATCH] Support for default and static methods in Functors --- .../org/teavm/jso/impl/JSClassProcessor.java | 7 ++-- .../java/org/teavm/jso/test/FunctorTest.java | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java b/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java index f7f6a8e8e..2e60efa2f 100644 --- a/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java +++ b/jso/impl/src/main/java/org/teavm/jso/impl/JSClassProcessor.java @@ -991,7 +991,9 @@ class JSClassProcessor { } private boolean isProperFunctor(ClassReader type) { - return type.hasModifier(ElementModifier.INTERFACE) && type.getMethods().size() == 1; + return type.hasModifier(ElementModifier.INTERFACE) + && type.getMethods().stream().filter(it->it.hasModifier(ElementModifier.ABSTRACT)) + .toArray().length == 1; } private Variable wrapFunctor(CallLocation location, Variable var, ClassReader type) { @@ -999,7 +1001,8 @@ class JSClassProcessor { diagnostics.error(location, "Wrong functor: {{c0}}", type.getName()); return var; } - String name = type.getMethods().iterator().next().getName(); + String name = type.getMethods().stream() + .filter(it->it.hasModifier(ElementModifier.ABSTRACT)).findFirst().get().getName(); Variable functor = program.createVariable(); Variable nameVar = addStringWrap(addString(name, location.getSourceLocation()), location.getSourceLocation()); InvokeInstruction insn = new InvokeInstruction(); diff --git a/tests/src/test/java/org/teavm/jso/test/FunctorTest.java b/tests/src/test/java/org/teavm/jso/test/FunctorTest.java index 8988a4d73..cb1b995a4 100644 --- a/tests/src/test/java/org/teavm/jso/test/FunctorTest.java +++ b/tests/src/test/java/org/teavm/jso/test/FunctorTest.java @@ -41,6 +41,24 @@ public class FunctorTest { assertSame(firstRef, secondRef); } + @Test + public void functorWithDefaultMethodPassed(){ + JSFunctionWithDefaultMethod javaFunction = (s) -> s+" returned"; + + String returned = javaFunction.defaultMethod(); + + assertEquals(returned, "Content returned"); + } + + @Test + public void functorWithStaticMethodPassed(){ + JSFunctionWithStaticMethod javaFunction = (s) -> s+" returned"; + + String returned = javaFunction.apply(JSFunctionWithStaticMethod.staticMethod()); + + assertEquals(returned, "Content returned"); + } + @Test public void propertyWithNonAlphabeticFirstChar() { WithProperties wp = getWithPropertiesInstance(); @@ -63,6 +81,24 @@ public class FunctorTest { int apply(int a, int b); } + @JSFunctor + interface JSFunctionWithDefaultMethod extends JSObject { + String apply(String a); + + default String defaultMethod(){ + return apply("Content"); + } + } + + @JSFunctor + interface JSFunctionWithStaticMethod extends JSObject { + String apply(String a); + + public static String staticMethod(){ + return "Content"; + } + } + interface WithProperties extends JSObject { @JSProperty String get_foo();