From ac3159aadf11968a89bfdbff168817b5789cebec Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 8 Sep 2015 18:39:21 +0300 Subject: [PATCH] Further refactoring of JSO spec --- teavm-jso/src/main/java/org/teavm/jso/JS.java | 113 +++++++----------- .../src/main/java/org/teavm/jso/JSArray.java | 4 +- .../main/java/org/teavm/jso/JSBoolean.java | 4 +- .../main/java/org/teavm/jso/JSExpression.java | 41 ------- .../src/main/java/org/teavm/jso/JSNumber.java | 30 +++-- .../src/main/java/org/teavm/jso/JSObject.java | 2 - .../src/main/java/org/teavm/jso/JSString.java | 71 +++++++++++ 7 files changed, 140 insertions(+), 125 deletions(-) delete mode 100644 teavm-jso/src/main/java/org/teavm/jso/JSExpression.java create mode 100644 teavm-jso/src/main/java/org/teavm/jso/JSString.java diff --git a/teavm-jso/src/main/java/org/teavm/jso/JS.java b/teavm-jso/src/main/java/org/teavm/jso/JS.java index e6db11c1d..83eeb19f4 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JS.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JS.java @@ -49,14 +49,14 @@ public final class JS { throw new AssertionError("Unexpected type"); } - @JSExpression(params = "obj", expr = "typeof(obj)") + @JSBody(params = "obj", script = "return typeof(obj);") private static native JSObject getTypeName(JSObject obj); /** * Gets global JavaScript object, that is similar to the window object in the browser. * @return global object. */ - @JSExpression(params = "obj", expr = "window") + @JSBody(params = {}, script = "return window;") public static native JSObject getGlobal(); @InjectedBy(JSNativeGenerator.class) @@ -148,136 +148,136 @@ public final class JS { return result; } - public static JSArray wrap(short[][] array) { - JSArray result = JSArray.create(array.length); + public static JSArray> wrap(short[][] array) { + JSArray> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSArray> wrap(short[][][] array) { - JSArray> result = JSArray.create(array.length); + public static JSArray>> wrap(short[][][] array) { + JSArray>> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSIntArray wrap(char[] array) { - JSIntArray result = createIntArray(array.length); + public static JSArray wrap(char[] array) { + JSArray result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { - result.set(i, array[i]); + result.set(i, JSNumber.valueOf(array[i])); } return result; } - public static JSArray wrap(char[][] array) { - JSArray result = JSArray.create(array.length); + public static JSArray> wrap(char[][] array) { + JSArray> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSArray> wrap(char[][][] array) { - JSArray> result = JSArray.create(array.length); + public static JSArray>> wrap(char[][][] array) { + JSArray>> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSIntArray wrap(int[] array) { - JSIntArray result = createIntArray(array.length); + public static JSArray wrap(int[] array) { + JSArray result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { - result.set(i, array[i]); + result.set(i, JSNumber.valueOf(array[i])); } return result; } - public static JSArray wrap(int[][] array) { - JSArray result = JSArray.create(array.length); + public static JSArray> wrap(int[][] array) { + JSArray> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSArray> wrap(int[][][] array) { - JSArray> result = JSArray.create(array.length); + public static JSArray>> wrap(int[][][] array) { + JSArray>> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSStringArray wrap(String[] array) { - JSStringArray result = JSStringArray.create(array.length); + public static JSArray wrap(String[] array) { + JSArray result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { - result.set(i, array[i]); + result.set(i, JSString.valueOf(array[i])); } return result; } - public static JSArray wrap(String[][] array) { - JSArray result = JSArray.create(array.length); + public static JSArray> wrap(String[][] array) { + JSArray> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSArray> wrap(String[][][] array) { - JSArray> result = JSArray.create(array.length); + public static JSArray>> wrap(String[][][] array) { + JSArray>> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSDoubleArray wrap(float[] array) { - JSDoubleArray result = createDoubleArray(array.length); + public static JSArray wrap(float[] array) { + JSArray result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { - result.set(i, array[i]); + result.set(i, JSNumber.valueOf(array[i])); } return result; } - public static JSArray wrap(float[][] array) { - JSArray result = JSArray.create(array.length); + public static JSArray> wrap(float[][] array) { + JSArray> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSArray> wrap(float[][][] array) { - JSArray> result = JSArray.create(array.length); + public static JSArray>> wrap(float[][][] array) { + JSArray>> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSDoubleArray wrap(double[] array) { - JSDoubleArray result = createDoubleArray(array.length); + public static JSArray wrap(double[] array) { + JSArray result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { - result.set(i, array[i]); + result.set(i, JSNumber.valueOf(array[i])); } return result; } - public static JSArray wrap(double[][] array) { - JSArray result = JSArray.create(array.length); + public static JSArray> wrap(double[][] array) { + JSArray> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } return result; } - public static JSArray> wrap(double[][][] array) { - JSArray> result = JSArray.create(array.length); + public static JSArray>> wrap(double[][][] array) { + JSArray>> result = JSArray.create(array.length); for (int i = 0; i < array.length; ++i) { result.set(i, wrap(array[i])); } @@ -319,101 +319,78 @@ public final class JS { return result; } - @JSExpression(params = "obj", expr = "typeof(obj) === 'undefined'") + @JSBody(params = "obj", script = "return typeof(obj) === 'undefined';") public static native boolean isUndefined(JSObject obj); - @JSExpression(params = { "instance", "method" }, expr = "instance[method]()") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method); - @JSExpression(params = { "instance", "method", "a" }, expr = "instance[method](a)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a); - @JSExpression(params = { "instance", "method", "a", "b" }, expr = "instance[method](a, b)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b); - @JSExpression(params = { "instance", "method", "a", "b", "c" }, expr = "instance[method](a, b, c)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d" }, expr = "instance[method](a, b, c, d)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e" }, expr = "instance[method](a, b, c, d, e)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e", "f" }, - expr = "instance[method](a, b, c, d, e, f)") + @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e", "f", "g" }, - expr = "instance[method](a, b, c, d, e, f, g)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e", "f", "g", "h" }, - expr = "instance[method](a, b, c, d, e, f, g, h)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e", "f", "g", "h", "i" }, - expr = "instance[method](a, b, c, d, e, f, g, h, i)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j" }, - expr = "instance[method](a, b, c, d, e, f, g, h, i, j)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k" }, - expr = "instance[method](a, b, c, d, e, f, g, h, i, j, k)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j, JSObject k); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l" }, - expr = "instance[method](a, b, c, d, e, f, g, h, i, j, k, l)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j, JSObject k, JSObject l); - @JSExpression(params = { "instance", "method", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m" }, - expr = "instance[method](a, b, c, d, e, f, g, h, i, j, k, l, m)") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject invoke(JSObject instance, JSObject method, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j, JSObject k, JSObject l, JSObject m); - @JSExpression(params = { "instance", "method" }, - expr = "new instance[method]()") @InjectedBy(JSNativeGenerator.class) @PluggableDependency(JSNativeGenerator.class) public static native JSObject instantiate(JSObject instance, JSObject constructor); @@ -471,11 +448,11 @@ public final class JS { }; } - @JSExpression(params = { "instance", "index" }, expr = "instance[index]") + @JSBody(params = { "instance", "index" }, script = "return instance[index];") public static native JSObject get(JSObject instance, JSObject index); @InjectedBy(JSNativeGenerator.class) - @JSExpression(params = { "instance", "index", "obj" }, expr = "instance[index] = obj") + @JSBody(params = { "instance", "index", "obj" }, script = "instance[index] = obj;") public static native void set(JSObject instance, JSObject index, JSObject obj); @GeneratedBy(JSNativeGenerator.class) diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSArray.java b/teavm-jso/src/main/java/org/teavm/jso/JSArray.java index a2618b626..e577fe920 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSArray.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSArray.java @@ -79,9 +79,9 @@ public abstract class JSArray implements JSArrayReader { public abstract JSArray splice(int start, int count, T a, T b, T c, T d); - @JSExpression(params = {}, expr = "new Array()") + @JSBody(params = {}, script = "return new Array();") public static native JSArray create(); - @JSExpression(params = "size", expr = "new Array(size)") + @JSBody(params = "size", script = "return new Array(size);") public static native JSArray create(int size); } diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSBoolean.java b/teavm-jso/src/main/java/org/teavm/jso/JSBoolean.java index 71437778c..f4af15067 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSBoolean.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSBoolean.java @@ -27,9 +27,9 @@ public abstract class JSBoolean implements JSObject { return booleanValue(this); } - @JSExpression(params = "value", expr = "value") + @JSBody(params = "value", script = "return value;") private static native boolean booleanValue(JSBoolean value); - @JSExpression(params = "value", expr = "value") + @JSBody(params = "value", script = "return value;") public static native JSBoolean valueOf(boolean value); } diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSExpression.java b/teavm-jso/src/main/java/org/teavm/jso/JSExpression.java deleted file mode 100644 index 1bcea4ca3..000000000 --- a/teavm-jso/src/main/java/org/teavm/jso/JSExpression.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2015 Alexey Andreev. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.teavm.jso; - -/** - *

Indicates that method is to have native JavaScript implementation, which can be written as a - * single JavaScript expression. - * Method only can take and return primitive values and {@link JSObject}s. - * JSExpression script can't call Java methods, but you can pass callbacks wrapped into {@link JSFunctor}. - * Note that unless method is static, it must belong to class that implements {@link JSObject}. - * If applied to non-native method, original Java body will be overwritten by JavaScript.

- * - *

Use this annotation instead of JSBody when possible, since this can increase performance and - * reduce generated JavaScript size.

- * - * @author Alexey Andreev - */ -public @interface JSExpression { - /** - *

How method parameters are named inside JavaScript implementation.

- */ - String[] params(); - - /** - *

JavaScript expression.

- */ - String expr(); -} diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSNumber.java b/teavm-jso/src/main/java/org/teavm/jso/JSNumber.java index 6f5fde8c0..8638d876e 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSNumber.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSNumber.java @@ -27,49 +27,59 @@ public abstract class JSNumber implements JSObject { return doubleValue(this); } - @JSExpression(params = "number", expr = "number") + @JSBody(params = "number", script = "return number;") private static native double doubleValue(JSNumber number); public final int intValue() { return intValue(this); } - @JSExpression(params = "number", expr = "number") + @JSBody(params = "number", script = "return number;") private static native int intValue(JSNumber number); + public final char charValue() { + return charValue(this); + } + + @JSBody(params = "number", script = "return number;") + private static native char charValue(JSNumber number); + public final byte byteValue() { return byteValue(this); } - @JSExpression(params = "number", expr = "number") + @JSBody(params = "number", script = "return number;") private static native byte byteValue(JSNumber number); public final short shortValue() { return shortValue(this); } - @JSExpression(params = "number", expr = "number") + @JSBody(params = "number", script = "return number;") private static native short shortValue(JSNumber number); public final float floatValue() { return floatValue(this); } - @JSExpression(params = "number", expr = "number") + @JSBody(params = "number", script = "return number;") private static native float floatValue(JSNumber number); - @JSExpression(params = "value", expr = "value") + @JSBody(params = "value", script = "return value;") public static native JSNumber valueOf(byte value); - @JSExpression(params = "value", expr = "value") + @JSBody(params = "value", script = "return value;") public static native JSNumber valueOf(short value); - @JSExpression(params = "value", expr = "value") + @JSBody(params = "value", script = "return value;") public static native JSNumber valueOf(int value); - @JSExpression(params = "value", expr = "value") + @JSBody(params = "value", script = "return value;") + public static native JSNumber valueOf(char value); + + @JSBody(params = "value", script = "return value;") public static native JSNumber valueOf(float value); - @JSExpression(params = "value", expr = "value") + @JSBody(params = "value", script = "return value;") public static native JSNumber valueOf(double value); } diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSObject.java b/teavm-jso/src/main/java/org/teavm/jso/JSObject.java index a27ed8774..906de29c6 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JSObject.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JSObject.java @@ -20,6 +20,4 @@ package org.teavm.jso; * @author Alexey Andreev */ public interface JSObject { - @Override - String toString(); } diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSString.java b/teavm-jso/src/main/java/org/teavm/jso/JSString.java new file mode 100644 index 000000000..195a9d617 --- /dev/null +++ b/teavm-jso/src/main/java/org/teavm/jso/JSString.java @@ -0,0 +1,71 @@ +/* + * Copyright 2015 Alexey Andreev. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.teavm.jso; + +/** + * + * @author Alexey Andreev + */ +public abstract class JSString implements JSObject { + private JSString() { + } + + public final String stringValue() { + return stringValue(this); + } + + @JSBody(params = "str", script = "return str;") + private static native String stringValue(JSString str); + + @JSBody(params = "str", script = "return str;") + public static native JSString valueOf(String str); + + @JSBody(params = "code", script = "return String.fromCharCode(code)") + public static native JSString fromCharCode(int code); + + @JSProperty + public abstract int getLength(); + + public abstract JSString charAt(int index); + + public abstract int charCodeAt(int index); + + public abstract JSString concat(JSString a); + + public abstract JSString concat(JSString a, JSString b); + + public abstract JSString concat(JSString a, JSString b, JSString c); + + public abstract int indexOf(JSString a); + + public abstract int lastIndexOf(JSString a); + + public abstract JSString slice(int beginSlice); + + public abstract JSString slice(int beginSlice, int endSlice); + + public abstract JSString[] split(JSString separator); + + public abstract JSString[] split(JSString separator, int limit); + + public abstract JSString substr(int start); + + public abstract JSString substr(int start, int length); + + public abstract JSString substring(int start); + + public abstract JSString substring(int start, int end); +}