diff --git a/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JS.java b/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JS.java
index bb3244524..ea8c3afdf 100644
--- a/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JS.java
+++ b/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JS.java
@@ -390,48 +390,6 @@ final class JS {
JSObject d, JSObject e, JSObject f, JSObject g, JSObject h, JSObject i, JSObject j, JSObject k,
JSObject l, JSObject m);
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor);
-
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a);
-
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b);
-
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
- JSObject c);
-
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
- JSObject c, JSObject d);
-
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
- JSObject c, JSObject d, JSObject e);
-
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
- JSObject c, JSObject d, JSObject e, JSObject f);
-
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
- JSObject c, JSObject d, JSObject e, JSObject f, JSObject g);
-
- @InjectedBy(JSNativeGenerator.class)
- @PluggableDependency(JSNativeGenerator.class)
- public static native JSObject instantiate(JSObject instance, JSObject constructor, JSObject a, JSObject b,
- JSObject c, JSObject d, JSObject e, JSObject f, JSObject g, JSObject h);
-
@InjectedBy(JSNativeGenerator.class)
@JSBody(params = { "instance", "index" }, script = "return instance[index];")
public static native JSObject get(JSObject instance, JSObject index);
diff --git a/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java b/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java
index a4a758aa5..f2e062eb4 100644
--- a/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java
+++ b/teavm-jso-impl/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java
@@ -27,7 +27,6 @@ import org.teavm.diagnostics.Diagnostics;
import org.teavm.javascript.spi.GeneratedBy;
import org.teavm.javascript.spi.Sync;
import org.teavm.jso.JSBody;
-import org.teavm.jso.JSConstructor;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSIndexer;
import org.teavm.jso.JSMethod;
@@ -371,40 +370,20 @@ class JavascriptNativeProcessor {
}
} else {
String name = method.getName();
- AnnotationReader constructorAnnot = method.getAnnotations().get(JSConstructor.class.getName());
- boolean isConstructor = false;
- if (constructorAnnot != null) {
- if (!isSupportedType(method.getResultType())) {
- diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript "
- + "constructor declaration", invoke.getMethod());
- continue;
- }
- AnnotationValue nameVal = constructorAnnot.getValue("value");
- name = nameVal != null ? constructorAnnot.getValue("value").getString() : "";
- if (name.isEmpty()) {
- if (!method.getName().startsWith("new") || method.getName().length() == 3) {
- diagnostics.error(callLocation, "Method {{m0}} is not declared as a native "
- + "JavaScript constructor, but its name does not satisfy conventions",
- invoke.getMethod());
- continue;
- }
- name = method.getName().substring(3);
- }
- isConstructor = true;
- } else {
- AnnotationReader methodAnnot = method.getAnnotations().get(JSMethod.class.getName());
- if (methodAnnot != null) {
- AnnotationValue redefinedMethodName = methodAnnot.getValue("value");
- if (redefinedMethodName != null) {
- name = redefinedMethodName.getString();
- }
- }
- if (method.getResultType() != ValueType.VOID && !isSupportedType(method.getResultType())) {
- diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript method "
- + "declaration", invoke.getMethod());
- continue;
+
+ AnnotationReader methodAnnot = method.getAnnotations().get(JSMethod.class.getName());
+ if (methodAnnot != null) {
+ AnnotationValue redefinedMethodName = methodAnnot.getValue("value");
+ if (redefinedMethodName != null) {
+ name = redefinedMethodName.getString();
}
}
+ if (method.getResultType() != ValueType.VOID && !isSupportedType(method.getResultType())) {
+ diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript method "
+ + "declaration", invoke.getMethod());
+ continue;
+ }
+
for (ValueType arg : method.getParameterTypes()) {
if (!isSupportedType(arg)) {
diagnostics.error(callLocation, "Method {{m0}} is not a proper native JavaScript method "
@@ -416,8 +395,7 @@ class JavascriptNativeProcessor {
InvokeInstruction newInvoke = new InvokeInstruction();
ValueType[] signature = new ValueType[method.parameterCount() + 3];
Arrays.fill(signature, ValueType.object(JSObject.class.getName()));
- newInvoke.setMethod(new MethodReference(JS.class.getName(),
- isConstructor ? "instantiate" : "invoke", signature));
+ newInvoke.setMethod(new MethodReference(JS.class.getName(), "invoke", signature));
newInvoke.setType(InvocationType.SPECIAL);
newInvoke.setReceiver(result);
newInvoke.getArguments().add(invoke.getInstance());
@@ -793,7 +771,7 @@ class JavascriptNativeProcessor {
} else if (itemType.isObject(String.class)) {
return new MethodReference(JS.class, "unwrapStringArray", JSArrayReader.class, String[].class);
}
- return new MethodReference(JS.class, "unwrapArray", Class.class, JSArrayReader.class, byte[].class);
+ return new MethodReference(JS.class, "unwrapArray", Class.class, JSArrayReader.class, JSObject[].class);
}
private MethodReference multipleDimensionArrayUnwrapper(ValueType itemType) {
diff --git a/teavm-jso/src/main/java/org/teavm/jso/JSConstructor.java b/teavm-jso/src/main/java/org/teavm/jso/JSConstructor.java
deleted file mode 100644
index 76b25140c..000000000
--- a/teavm-jso/src/main/java/org/teavm/jso/JSConstructor.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2014 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;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- *
Marks abstract member method as a JavaScript constructor. This is equivalent to the following:
- *
- * {@code
- * @JSBody(params = ..., script = "return new this.constructorName(...);")
- * }
- *
- * where constructorName
is method's name by default or a name, directly specified by
- * this annotation.
- *
- * @author Alexey Andreev
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.METHOD)
-public @interface JSConstructor {
- String value() default "";
-}
diff --git a/teavm-jso/src/main/java/org/teavm/jso/webgl/WebGLContextAttributes.java b/teavm-jso/src/main/java/org/teavm/jso/webgl/WebGLContextAttributes.java
index 8ed6cac0f..f64748a7f 100644
--- a/teavm-jso/src/main/java/org/teavm/jso/webgl/WebGLContextAttributes.java
+++ b/teavm-jso/src/main/java/org/teavm/jso/webgl/WebGLContextAttributes.java
@@ -15,6 +15,7 @@
*/
package org.teavm.jso.webgl;
+import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
@@ -22,40 +23,43 @@ import org.teavm.jso.JSProperty;
*
* @author Alexey Andreev
*/
-public interface WebGLContextAttributes extends JSObject {
+public abstract class WebGLContextAttributes implements JSObject {
@JSProperty
- boolean isAlpha();
+ public abstract boolean isAlpha();
@JSProperty
- void setAlpha(boolean alpha);
+ public abstract void setAlpha(boolean alpha);
@JSProperty
- boolean isDepth();
+ public abstract boolean isDepth();
@JSProperty
- void setDepth(boolean depth);
+ public abstract void setDepth(boolean depth);
@JSProperty
- boolean isScencil();
+ public abstract boolean isScencil();
@JSProperty
- void setStencil(boolean stencil);
+ public abstract void setStencil(boolean stencil);
@JSProperty
- boolean isAntialias();
+ public abstract boolean isAntialias();
@JSProperty
- void setAntialias(boolean antialias);
+ public abstract void setAntialias(boolean antialias);
@JSProperty
- boolean isPremultipliedAlpha();
+ public abstract boolean isPremultipliedAlpha();
@JSProperty
- void setPremultipliedAlpha(boolean premultipliedAlpha);
+ public abstract void setPremultipliedAlpha(boolean premultipliedAlpha);
@JSProperty
- boolean isPreserveDrawingBuffer();
+ public abstract boolean isPreserveDrawingBuffer();
@JSProperty
- void setPreserveDrawingBuffer(boolean preserveDrawingBuffer);
+ public abstract void setPreserveDrawingBuffer(boolean preserveDrawingBuffer);
+
+ @JSBody(params = {}, script = "return {};")
+ public static native WebGLContextAttributes create();
}
diff --git a/teavm-jso/src/main/java/org/teavm/jso/webgl/WebGLContextAttributesFactory.java b/teavm-jso/src/main/java/org/teavm/jso/webgl/WebGLContextAttributesFactory.java
deleted file mode 100644
index 6ab7ba60c..000000000
--- a/teavm-jso/src/main/java/org/teavm/jso/webgl/WebGLContextAttributesFactory.java
+++ /dev/null
@@ -1,28 +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.webgl;
-
-import org.teavm.jso.JSConstructor;
-import org.teavm.jso.JSObject;
-
-/**
- *
- * @author Alexey Andreev
- */
-public interface WebGLContextAttributesFactory extends JSObject {
- @JSConstructor("Object")
- WebGLContextAttributes createWebGLContextAttributes();
-}
diff --git a/teavm-jso/src/test/java/org/teavm/jso/test/AnnotationsTest.java b/teavm-jso/src/test/java/org/teavm/jso/test/AnnotationsTest.java
new file mode 100644
index 000000000..b8b435e9d
--- /dev/null
+++ b/teavm-jso/src/test/java/org/teavm/jso/test/AnnotationsTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.test;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+import org.teavm.jso.JSBody;
+import org.teavm.jso.JSMethod;
+import org.teavm.jso.JSObject;
+import org.teavm.jso.JSProperty;
+
+/**
+ *
+ * @author Alexey Andreev
+ */
+public class AnnotationsTest {
+ @Test
+ public void staticBodyWorks() {
+ assertEquals(12, add(5, 7));
+ }
+
+ @Test
+ public void memberBodyWorks() {
+ assertEquals(12, convert(convert(5).add(convert(7))));
+ }
+
+ @Test
+ public void abstractWrapperWorks() {
+ AbstractWrapper obj = AbstractWrapper.create(5);
+ assertEquals(5, obj.getValue());
+ assertEquals(12, obj.testMethod(6));
+ assertEquals(13, obj.renamedMethod(6));
+ assertEquals(25, obj.javaMethod(6));
+ }
+
+ @Test
+ public void interfaceWrapperWorks() {
+ InterfaceWrapper obj = createWrapper(5);
+ assertEquals(5, obj.getValue());
+ assertEquals(12, obj.testMethod(6));
+ assertEquals(13, obj.renamedMethod(6));
+ }
+
+ @JSBody(params = { "a", "b" }, script = "return a + b;")
+ private static native int add(int a, int b);
+
+ @JSBody(params = "n", script = "return n;")
+ private static native Num convert(int n);
+
+ @JSBody(params = "n", script = "return n;")
+ private static native int convert(Num n);
+
+ static abstract class Num implements JSObject {
+ @JSBody(params = "other", script = "return this + other;")
+ public final native Num add(Num other);
+ }
+
+ static abstract class AbstractWrapper implements JSObject {
+ private AbstractWrapper() {
+ }
+
+ @JSProperty
+ public abstract int getValue();
+
+ public abstract int testMethod(int num);
+
+ @JSMethod("renamedJSMethod")
+ public abstract int renamedMethod(int num);
+
+ public final int javaMethod(int num) {
+ return testMethod(num) + renamedMethod(num);
+ }
+
+ @JSBody(params = "value", script = ""
+ + "return {"
+ + "value : value, "
+ + "testMethod : function(num) { return this.value + num + 1; }, "
+ + "renamedJSMethod : function(num) { return this.value + num + 2; }"
+ + "};")
+ public static native AbstractWrapper create(int value);
+ }
+
+ interface InterfaceWrapper extends JSObject {
+ @JSProperty
+ int getValue();
+
+ int testMethod(int num);
+
+ @JSMethod("renamedJSMethod")
+ int renamedMethod(int num);
+ }
+
+ @JSBody(params = "value", script = ""
+ + "return {"
+ + "value : value, "
+ + "testMethod : function(num) { return this.value + num + 1; }, "
+ + "renamedJSMethod : function(num) { return this.value + num + 2; }"
+ + "};")
+ public static native InterfaceWrapper createWrapper(int value);
+}
diff --git a/teavm-jso/src/test/java/org/teavm/jso/test/ConversionTest.java b/teavm-jso/src/test/java/org/teavm/jso/test/ConversionTest.java
index afa36d3e2..1e67e2cae 100644
--- a/teavm-jso/src/test/java/org/teavm/jso/test/ConversionTest.java
+++ b/teavm-jso/src/test/java/org/teavm/jso/test/ConversionTest.java
@@ -20,6 +20,7 @@ import org.junit.Test;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
+import org.teavm.jso.core.JSString;
/**
*
@@ -120,6 +121,26 @@ public class ConversionTest {
assertArrayEquals(new String[] { "foo" }, arrays.getH()[0][0][0]);
}
+ @Test
+ public void passesJSObject() {
+ assertEquals("(foo)", surround(JSString.valueOf("foo")).stringValue());
+ }
+
+ @Test
+ public void convertsArrayOfJSObject() {
+ assertEquals("(foo)", surround(new JSString[] { JSString.valueOf("foo") })[0].stringValue());
+ assertEquals("(foo)", surround(new JSString[][] {{ JSString.valueOf("foo") }})[0][0].stringValue());
+ assertEquals("(foo)", surround(new JSString[][][][] {{{{ JSString.valueOf("foo") }}}})[0][0][0][0]
+ .stringValue());
+ }
+
+ @Test
+ public void copiesArray() {
+ int[] array = { 23 };
+ assertEquals(24, mutate(array));
+ assertEquals(23, array[0]);
+ }
+
@JSBody(params = { "a", "b", "c", "d", "e", "f", "g", "h" }, script = ""
+ "return '' + a + ':' + b + ':' + c + ':' + d + ':' + e + ':' + f.toFixed(1) + ':'"
+ "+ g.toFixed(1) + ':' + h;")
@@ -263,4 +284,19 @@ public class ConversionTest {
@JSProperty
String[][][][] getH();
}
+
+ @JSBody(params = "str", script = "return '(' + str + ')';")
+ private static native JSString surround(JSString str);
+
+ @JSBody(params = "str", script = "return ['(' + str[0] + ')'];")
+ private static native JSString[] surround(JSString[] str);
+
+ @JSBody(params = "str", script = "return [['(' + str[0][0] + ')']];")
+ private static native JSString[][] surround(JSString[][] str);
+
+ @JSBody(params = "str", script = "return [[[['(' + str[0][0][0][0] + ')']]]];")
+ private static native JSString[][][][] surround(JSString[][][][] str);
+
+ @JSBody(params = "array", script = "array[0]++; return array[0];")
+ private static native int mutate(int[] array);
}
diff --git a/teavm-jso/src/test/java/org/teavm/jso/test/JSBodyTest.java b/teavm-jso/src/test/java/org/teavm/jso/test/JSBodyTest.java
deleted file mode 100644
index 34d7f393f..000000000
--- a/teavm-jso/src/test/java/org/teavm/jso/test/JSBodyTest.java
+++ /dev/null
@@ -1,51 +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.test;
-
-import static org.junit.Assert.*;
-import org.junit.Test;
-import org.teavm.jso.JSBody;
-import org.teavm.jso.JSObject;
-
-/**
- *
- * @author Alexey Andreev
- */
-public class JSBodyTest {
- @Test
- public void staticWorks() {
- assertEquals(12, add(5, 7));
- }
-
- @Test
- public void memberWorks() {
- assertEquals(12, convert(convert(5).add(convert(7))));
- }
-
- @JSBody(params = { "a", "b" }, script = "return a + b;")
- private static native int add(int a, int b);
-
- @JSBody(params = "n", script = "return n;")
- private static native Num convert(int n);
-
- @JSBody(params = "n", script = "return n;")
- private static native int convert(Num n);
-
- static abstract class Num implements JSObject {
- @JSBody(params = "other", script = "return this + other;")
- public final native Num add(Num other);
- }
-}
diff --git a/teavm-platform/src/main/java/org/teavm/platform/Platform.java b/teavm-platform/src/main/java/org/teavm/platform/Platform.java
index 9f68a024e..abf5483b6 100644
--- a/teavm-platform/src/main/java/org/teavm/platform/Platform.java
+++ b/teavm-platform/src/main/java/org/teavm/platform/Platform.java
@@ -134,9 +134,8 @@ public final class Platform {
((PlatformHelper) Window.current()).killSchedule(id);
}
- public static PlatformQueue createQueue() {
- return ((PlatformHelper) Window.current()).newQueue();
- }
+ @JSBody(params = {}, script = "return [];")
+ public static native PlatformQueue createQueue();
public static PlatformString stringFromCharCode(int charCode) {
return ((PlatformHelper) Window.current()).getStringClass().fromCharCode(charCode);
diff --git a/teavm-platform/src/main/java/org/teavm/platform/PlatformHelper.java b/teavm-platform/src/main/java/org/teavm/platform/PlatformHelper.java
index 817cc08e3..dfe2b4c9c 100644
--- a/teavm-platform/src/main/java/org/teavm/platform/PlatformHelper.java
+++ b/teavm-platform/src/main/java/org/teavm/platform/PlatformHelper.java
@@ -15,7 +15,6 @@
*/
package org.teavm.platform;
-import org.teavm.jso.JSConstructor;
import org.teavm.jso.JSMethod;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
@@ -31,9 +30,6 @@ interface PlatformHelper extends JSObject {
@JSProperty("String")
PlatformStringClass getStringClass();
- @JSConstructor("Array")
- PlatformQueue newQueue();
-
@JSMethod("clearTimeout")
void killSchedule(int scheduleId);
}