diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java
index d056e635c..72d742454 100644
--- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java
+++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java
@@ -79,6 +79,8 @@ public class JavaScriptBodyDependency implements DependencyListener {
dependencyChecker.attachMethodGraph(JavaScriptConvGenerator.toJsMethod, DependencyStack.ROOT);
dependencyChecker.attachMethodGraph(JavaScriptConvGenerator.intValueMethod, DependencyStack.ROOT);
dependencyChecker.attachMethodGraph(JavaScriptConvGenerator.valueOfIntMethod, DependencyStack.ROOT);
+ dependencyChecker.attachMethodGraph(JavaScriptConvGenerator.booleanValueMethod, DependencyStack.ROOT);
+ dependencyChecker.attachMethodGraph(JavaScriptConvGenerator.valueOfBooleanMethod, DependencyStack.ROOT);
}
@Override
diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java
index f89c13033..9a9cf809a 100644
--- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java
+++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptBodyGenerator.java
@@ -20,6 +20,7 @@ import java.util.List;
import net.java.html.js.JavaScriptBody;
import org.teavm.codegen.NamingStrategy;
import org.teavm.codegen.SourceWriter;
+import org.teavm.javascript.Renderer;
import org.teavm.javascript.ni.Generator;
import org.teavm.javascript.ni.GeneratorContext;
import org.teavm.model.*;
@@ -53,7 +54,7 @@ public class JavaScriptBodyGenerator implements Generator {
writer.outdent().append("}).call(").append(context.getParameterName(0));
for (int i = 0; i < args.size(); ++i) {
writer.append(",").ws();
- wrapParameter(writer, methodRef.getDescriptor().parameterType(i), context.getParameterName(i + 1));
+ wrapParameter(writer, context.getParameterName(i + 1));
}
writer.append(")").softNewLine();
writer.append("return ");
@@ -61,22 +62,15 @@ public class JavaScriptBodyGenerator implements Generator {
writer.append(";").softNewLine();
}
- private void wrapParameter(SourceWriter writer, ValueType type, String param) throws IOException {
- if (type.isObject("java.lang.Object")) {
- writer.appendMethodBody(JavaScriptConvGenerator.toJsMethod);
- writer.append("(").append(param).append(")");
- } else {
- writer.append(param);
- }
+ private void wrapParameter(SourceWriter writer, String param) throws IOException {
+ writer.appendMethodBody(JavaScriptConvGenerator.toJsMethod);
+ writer.append("(").append(param).append(")");
}
private void unwrapValue(SourceWriter writer, ValueType type, String param) throws IOException {
- if (type.isObject("java.lang.Object")) {
- writer.appendMethodBody(JavaScriptConvGenerator.fromJsMethod);
- writer.append("(").append(param).append(")");
- } else {
- writer.append(param);
- }
+ writer.appendMethodBody(JavaScriptConvGenerator.fromJsMethod);
+ writer.append("(").append(param).append(",").ws().append(Renderer.typeToClsString(writer.getNaming(), type))
+ .append(")");
}
private static class GeneratorJsCallback extends JsCallback {
diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConv.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConv.java
index 4139f076c..9d7b41127 100644
--- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConv.java
+++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConv.java
@@ -29,5 +29,5 @@ public final class JavaScriptConv {
public static native Object toJavaScript(Object obj);
@GeneratedBy(JavaScriptConvGenerator.class)
- public static native Object fromJavaScript(Object obj);
+ public static native Object fromJavaScript(Object obj, Object cls);
}
diff --git a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConvGenerator.java b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConvGenerator.java
index e9ba59792..190f129bc 100644
--- a/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConvGenerator.java
+++ b/teavm-html4j/src/main/java/org/teavm/html4j/JavaScriptConvGenerator.java
@@ -29,13 +29,17 @@ public class JavaScriptConvGenerator implements Generator {
private static final String convCls = JavaScriptConv.class.getName();
static final MethodReference intValueMethod = new MethodReference("java.lang.Integer",
new MethodDescriptor("intValue", ValueType.INTEGER));
+ static final MethodReference booleanValueMethod = new MethodReference("java.lang.Boolean",
+ new MethodDescriptor("booleanValue", ValueType.BOOLEAN));
static final MethodReference valueOfIntMethod = new MethodReference("java.lang.Integer",
new MethodDescriptor("valueOf", ValueType.INTEGER, ValueType.object("java.lang.Integer")));
+ static final MethodReference valueOfBooleanMethod = new MethodReference("java.lang.Boolean",
+ new MethodDescriptor("valueOf", ValueType.BOOLEAN, ValueType.object("java.lang.Boolean")));
private static final ValueType objType = ValueType.object("java.lang.Object");
static final MethodReference toJsMethod = new MethodReference(convCls, new MethodDescriptor(
"toJavaScript", objType, objType));
static final MethodReference fromJsMethod = new MethodReference(convCls, new MethodDescriptor(
- "fromJavaScript", objType, objType));
+ "fromJavaScript", objType, objType, objType));
@Override
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
@@ -53,43 +57,67 @@ public class JavaScriptConvGenerator implements Generator {
String obj = context.getParameterName(1);
writer.append("if (" + obj + " === null) {").softNewLine().indent();
writer.append("return null;").softNewLine();
+ writer.outdent().append("} else if (typeof " + obj + " === 'number') {").indent().softNewLine();
+ writer.append("return " + obj + ";").softNewLine();
writer.outdent().append("} else if (" + obj + ".constructor.$meta.item) {").indent().softNewLine();
writer.append("var arr = new Array(" + obj + ".data.length);").softNewLine();
writer.append("for (var i = 0; i < arr.length; ++i) {").indent().softNewLine();
writer.append("arr[i] = ").appendMethodBody(toJsMethod).append("(" + obj + ".data[i]);").softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("return arr;").softNewLine();
- writer.outdent().append("}");
- writer.append(" else if (" + obj + ".constructor === ").appendClass("java.lang.String")
+ writer.outdent().append("} else if (" + obj + ".constructor === ").appendClass("java.lang.String")
.append(") {").indent().softNewLine();
generateStringToJavaScript(context, writer);
writer.outdent().append("} else if (" + obj + ".constructor === ").appendClass("java.lang.Integer")
.append(") {").indent().softNewLine();
writer.append("return ").appendMethodBody(intValueMethod).append("(" + obj + ");").softNewLine();
- writer.outdent().append("}");
- writer.append(" else {").indent().softNewLine();
+ writer.outdent().append("} else if (" + obj + ".constructor === ").appendClass("java.lang.Boolean")
+ .append(") {").indent().softNewLine();
+ writer.append("return ").appendMethodBody(booleanValueMethod).append("(" + obj + ")!==0;").softNewLine();
+ writer.outdent().append("} else {").indent().softNewLine();
writer.append("return " + obj + ";").softNewLine();
writer.outdent().append("}").softNewLine();
}
private void generateFromJavaScript(GeneratorContext context, SourceWriter writer) throws IOException {
String obj = context.getParameterName(1);
+ String type = context.getParameterName(2);
writer.append("if (" + obj +" === null || " + obj + " === undefined)").ws().append("{")
.softNewLine().indent();
writer.append("return null;").softNewLine();
- writer.outdent().append("} else if (" + obj + " instanceof Array) {").indent().softNewLine();
- writer.append("var arr = $rt_createArray($rt_objcls(), " + obj + ".length);").softNewLine();
+ writer.outdent().append("} else if (" + type + ".$meta.item) {").indent().softNewLine();
+ writer.append("var arr = $rt_createArray(" + type + ".$meta.item, " + obj + ".length);").softNewLine();
writer.append("for (var i = 0; i < arr.data.length; ++i) {").indent().softNewLine();
- writer.append("arr.data[i] = ").appendMethodBody(fromJsMethod).append("(" + obj + "[i]);")
+ writer.append("arr.data[i] = ").appendMethodBody(fromJsMethod).append("(" + obj + "[i], " + type + ");")
.softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("return arr;").softNewLine();
- writer.outdent().append("}");
- writer.append(" else if (" + obj + ".constructor === ").appendClass("java.lang.String")
+ writer.outdent().append("} else if (" + type + " === ").appendClass("java.lang.String")
.append(") {").indent().softNewLine();
writer.append("return $rt_str(" + obj + ");").softNewLine();
- writer.outdent().append("} else if (" + obj + " | 0 === " + obj + ") {").indent().softNewLine();
+ writer.outdent().append("} else if (" + type + " === ").appendClass("java.lang.Integer")
+ .append(") {").indent().softNewLine();
writer.append("return ").appendMethodBody(valueOfIntMethod).append("(" + obj + ");").softNewLine();
+ writer.outdent().append("} else if (" + type + " === $rt_intcls()) {").indent().softNewLine();
+ writer.append("return " + obj + "|0;").softNewLine();
+ writer.outdent().append("} else if (" + type + " === ").appendClass("java.lang.Boolean")
+ .append(") {").indent().softNewLine();
+ writer.append("return ").appendMethodBody(valueOfBooleanMethod).append("(" + obj + "?1:0);").softNewLine();
+ writer.outdent().append("} else if (" + type + " === $rt_booleancls()) {").indent().softNewLine();
+ writer.append("return " + obj + "?1:0;").softNewLine();
+ writer.outdent().append("} else if (" + obj + " instanceof Array) {").indent().softNewLine();
+ writer.append("var arr = $rt_createArray($rt_objcls(), " + obj + ".length);").softNewLine();
+ writer.append("for (var i = 0; i < arr.data.length; ++i) {").indent().softNewLine();
+ writer.append("arr.data[i] = ").appendMethodBody(fromJsMethod).append("(" + obj + "[i], $rt_objcls());")
+ .softNewLine();
+ writer.outdent().append("}").softNewLine();
+ writer.append("return arr;").softNewLine();
+ writer.outdent().append("} else if (typeof " + obj + " === 'number') {").indent().softNewLine();
+ writer.append("if (" + obj + "|0 === " + obj + ") {").indent().softNewLine();
+ writer.append("return ").appendMethodBody(valueOfIntMethod).append("(" + obj + ");").softNewLine();
+ writer.outdent().append("}").softNewLine();
+ writer.outdent().append("} else if (typeof " + obj + " === 'boolean') {").indent().softNewLine();
+ writer.append("return ").appendMethodBody(valueOfBooleanMethod).append("(" + obj + "?1:0);").softNewLine();
writer.outdent().append("} else {").indent().softNewLine();
writer.append("return ").append(obj).append(";").softNewLine();
writer.outdent().append("}").softNewLine();
diff --git a/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyConversionTests.java b/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyConversionTests.java
index a31e4b237..0cfaa1185 100644
--- a/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyConversionTests.java
+++ b/teavm-html4j/src/test/java/org/teavm/html4j/test/JavaScriptBodyConversionTests.java
@@ -27,15 +27,30 @@ public class JavaScriptBodyConversionTests {
@Test
public void convertsInteger() {
assertEquals(23, returnAsInt(23));
+ assertEquals(Integer.valueOf(23), returnAsInteger(23));
+ assertEquals(23, returnAsObject(23));
+ assertEquals(24, addOne((Object)23));
+ assertEquals(Integer.valueOf(24), addOne(Integer.valueOf(23)));
+ assertEquals(24, addOne(23));
}
@Test
public void convertsIntegerResult() {
assertEquals(23, returnAsObject(23));
+ assertEquals(Integer.valueOf(23), returnAsInteger(23));
+ assertEquals(23, returnAsInt(23));
+ }
+
+ @Test
+ public void convertsBoolean() {
+ assertTrue(returnAsBoolean(true));
+ assertTrue(returnAsBooleanWrapper(true));
+ assertEquals(Boolean.TRUE, returnAsObject(true));
}
@Test
public void convertsArray() {
+ assertEquals(42, getArrayItem(new int[] { 23, 42 }, 1));
assertEquals(42, getArrayItem(new Integer[] { 23, 42 }, 1));
}
@@ -47,12 +62,46 @@ public class JavaScriptBodyConversionTests {
assertEquals(Integer.valueOf(1), arrayCopy[0]);
}
+ @Test
+ public void createsArrayOfProperType() {
+ assertEquals(Object[].class, returnAsObject(new int[] { 23, 42 }).getClass());
+ assertEquals(Integer[].class, returnAsIntegerArray(new Integer[] { 23, 42 }).getClass());
+ assertEquals(int[].class, returnAsIntArray(new Integer[] { 23, 42 }).getClass());
+ }
+
@JavaScriptBody(args = { "value" }, body = "return value;")
private native int returnAsInt(Object value);
+ @JavaScriptBody(args = { "value" }, body = "return value;")
+ private native boolean returnAsBoolean(Object value);
+
+ @JavaScriptBody(args = { "value" }, body = "return value;")
+ private native Boolean returnAsBooleanWrapper(boolean value);
+
+ @JavaScriptBody(args = { "value" }, body = "return value;")
+ private native Integer returnAsInteger(Integer value);
+
@JavaScriptBody(args = { "value" }, body = "return value;")
private native Object returnAsObject(int value);
+ @JavaScriptBody(args = { "value" }, body = "return value + 1;")
+ private native int addOne(Object value);
+
+ @JavaScriptBody(args = { "value" }, body = "return value + 1;")
+ private native Integer addOne(Integer value);
+
+ @JavaScriptBody(args = { "value" }, body = "return value + 1;")
+ private native int addOne(int value);
+
+ @JavaScriptBody(args = { "value" }, body = "return value;")
+ private native Object returnAsObject(Object array);
+
+ @JavaScriptBody(args = { "value" }, body = "return value;")
+ private native int[] returnAsIntArray(Object array);
+
+ @JavaScriptBody(args = { "value" }, body = "return value;")
+ private native Integer[] returnAsIntegerArray(Object array);
+
@JavaScriptBody(args = { "value" }, body = "value[0] = 1; return value;")
private native Object modifyIntegerArray(Object value);