Remove JSConstructor. Further development of JSO TCK

This commit is contained in:
Alexey Andreev 2015-09-12 13:47:58 +03:00
parent 0b66d4c799
commit 5fca860b70
10 changed files with 182 additions and 216 deletions

View File

@ -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);

View File

@ -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) {

View File

@ -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;
/**
* <p>Marks abstract member method as a JavaScript constructor. This is equivalent to the following:</p>
*
* <pre>{@code
* @JSBody(params = ..., script = "return new this.constructorName(...);")
* }</pre>
*
* <p>where <code>constructorName</code> is method's name by default or a name, directly specified by
* this annotation.</p>
*
* @author Alexey Andreev
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface JSConstructor {
String value() default "";
}

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}
}

View File

@ -134,9 +134,8 @@ public final class Platform {
((PlatformHelper) Window.current()).killSchedule(id);
}
public static <T> PlatformQueue<T> createQueue() {
return ((PlatformHelper) Window.current()).newQueue();
}
@JSBody(params = {}, script = "return [];")
public static native <T> PlatformQueue<T> createQueue();
public static PlatformString stringFromCharCode(int charCode) {
return ((PlatformHelper) Window.current()).getStringClass().fromCharCode(charCode);

View File

@ -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")
<T> PlatformQueue<T> newQueue();
@JSMethod("clearTimeout")
void killSchedule(int scheduleId);
}