mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Improves value conversion support for JavaScriptBody
This commit is contained in:
parent
ee28309008
commit
f27c641d32
|
@ -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
|
||||
|
|
|
@ -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")) {
|
||||
private void wrapParameter(SourceWriter writer, String param) throws IOException {
|
||||
writer.appendMethodBody(JavaScriptConvGenerator.toJsMethod);
|
||||
writer.append("(").append(param).append(")");
|
||||
} else {
|
||||
writer.append(param);
|
||||
}
|
||||
}
|
||||
|
||||
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.append("(").append(param).append(",").ws().append(Renderer.typeToClsString(writer.getNaming(), type))
|
||||
.append(")");
|
||||
}
|
||||
|
||||
private static class GeneratorJsCallback extends JsCallback {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user