JS: relax several JSO declarations to accept Object instead of JSObject

This commit is contained in:
Alexey Andreev 2023-08-03 20:50:22 +02:00
parent 334e2829b3
commit f30a050bfd
16 changed files with 97 additions and 68 deletions

View File

@ -18,10 +18,9 @@ package org.teavm.jso.core;
import org.teavm.interop.NoSideEffects;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSIndexer;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public abstract class JSArray<T extends JSObject> implements JSArrayReader<T> {
public abstract class JSArray<T> implements JSArrayReader<T> {
private JSArray() {
}
@ -85,18 +84,18 @@ public abstract class JSArray<T extends JSObject> implements JSArrayReader<T> {
@JSBody(script = "return new Array();")
@NoSideEffects
public static native <T extends JSObject> JSArray<T> create();
public static native <T> JSArray<T> create();
@JSBody(params = "size", script = "return new Array(size);")
@NoSideEffects
public static native <T extends JSObject> JSArray<T> create(int size);
public static native <T> JSArray<T> create(int size);
@JSBody(params = "object", script = "return Array.isArray(object);")
@NoSideEffects
public static native boolean isArray(JSObject object);
public static native boolean isArray(Object object);
@SafeVarargs
public static <S extends JSObject> JSArray<S> of(S... items) {
public static <S> JSArray<S> of(S... items) {
JSArray<S> array = create(items.length);
for (int i = 0; i < items.length; ++i) {
array.set(i, items[i]);

View File

@ -20,7 +20,7 @@ import org.teavm.jso.JSIndexer;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public interface JSArrayReader<T extends JSObject> extends JSObject {
public interface JSArrayReader<T> extends JSObject {
@JSProperty
@NoSideEffects
int getLength();

View File

@ -27,7 +27,7 @@ public abstract class JSError implements JSObject {
+ "} catch (e) {"
+ "return catchClause(e);"
+ "}")
public static native <T extends JSObject> T catchNative(TryClause<T> tryClause, CatchClause<T> catchClause);
public static native <T> T catchNative(TryClause<T> tryClause, CatchClause<T> catchClause);
@JSBody(params = "object", script = "return object instanceof Error;")
public static native boolean isError(JSObject object);
@ -42,12 +42,12 @@ public abstract class JSError implements JSObject {
public abstract String getName();
@JSFunctor
public interface TryClause<T extends JSObject> extends JSObject {
public interface TryClause<T> extends JSObject {
T run();
}
@JSFunctor
public interface CatchClause<T extends JSObject> extends JSObject {
public interface CatchClause<T> extends JSObject {
T accept(JSObject e);
}
}

View File

@ -15,12 +15,18 @@
*/
package org.teavm.jso.core;
import org.teavm.interop.NoSideEffects;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
public abstract class JSFinalizationRegistry implements JSObject {
public abstract void register(JSObject obj, JSObject token);
public abstract void register(Object obj, Object token);
@JSBody(params = "consumer", script = "return new FinalizationRegistry(consumer);")
public static native JSFinalizationRegistry create(JSFinalizationRegistryConsumer consumer);
@JSBody(script = "return typeof FinalizationRegistry !== 'undefined';")
@NoSideEffects
public static native boolean isSupported();
}

View File

@ -20,5 +20,5 @@ import org.teavm.jso.JSObject;
@JSFunctor
public interface JSFinalizationRegistryConsumer extends JSObject {
void accept(JSObject obj);
void accept(Object obj);
}

View File

@ -19,33 +19,31 @@ import org.teavm.jso.JSByRef;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
public interface JSFunction extends JSObject {
public abstract class JSFunction implements JSObject {
@JSProperty
int getLength();
public abstract int getLength();
@JSProperty
String getName();
public abstract String getName();
JSObject call(JSObject thisArg);
public abstract Object call(Object thisArg);
JSObject call(JSObject thisArg, JSObject a);
public abstract Object call(Object thisArg, Object a);
JSObject call(JSObject thisArg, JSObject a, JSObject b);
public abstract Object call(Object thisArg, Object a, Object b);
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c);
public abstract Object call(Object thisArg, Object a, Object b, Object c);
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c,
JSObject d);
public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d);
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e);
public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d, Object e);
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f);
public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d, Object e, Object f);
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f,
JSObject g);
public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d, Object e, Object f, Object g);
JSObject call(JSObject thisArg, JSObject a, JSObject b, JSObject c, JSObject d, JSObject e, JSObject f,
JSObject g, JSObject h);
public abstract Object call(Object thisArg, Object a, Object b, Object c, Object d, Object e, Object f, Object g,
Object h);
JSObject apply(JSObject thisArg, @JSByRef JSObject[] arguments);
public abstract Object apply(Object thisArg, @JSByRef Object[] arguments);
}

View File

@ -18,7 +18,7 @@ package org.teavm.jso.core;
import org.teavm.jso.JSIndexer;
import org.teavm.jso.JSObject;
public interface JSMapLike<T extends JSObject> extends JSObject {
public interface JSMapLike<T> extends JSObject {
@JSIndexer
T get(String key);

View File

@ -25,11 +25,11 @@ public final class JSObjects {
@JSBody(params = "object", script = "return Object.getOwnPropertyNames(object);")
@NoSideEffects
public static native String[] getOwnPropertyNames(JSObject object);
public static native String[] getOwnPropertyNames(Object object);
@JSBody(params = "object", script = "return Object.keys(object);")
@NoSideEffects
public static native String[] keys(JSObject object);
public static native String[] keys(Object object);
@JSBody(params = "object", script = "return Object.values(object);")
@NoSideEffects
@ -45,7 +45,7 @@ public final class JSObjects {
@JSBody(params = "object", script = "return typeof object === 'undefined';")
@NoSideEffects
public static native boolean isUndefined(JSObject object);
public static native boolean isUndefined(Object object);
@JSBody(script = "return void 0;")
@NoSideEffects
@ -53,16 +53,16 @@ public final class JSObjects {
@JSBody(params = "object", script = "return typeof object;")
@NoSideEffects
public static native String typeOf(JSObject object);
public static native String typeOf(Object object);
@JSBody(params = "object", script = "return object.toString();")
public static native String toString(JSObject object);
public static native String toString(Object object);
@JSBody(params = { "object", "name" }, script = "return name in object;")
@NoSideEffects
public static native boolean hasProperty(JSObject object, String name);
public static native boolean hasProperty(Object object, String name);
@JSBody(params = "object", script = "return Object.getPrototypeOf(object);")
@NoSideEffects
public static native JSObject getPrototypeOf(JSObject object);
public static native JSObject getPrototypeOf(Object object);
}

View File

@ -16,15 +16,9 @@
package org.teavm.jso.core;
import org.teavm.jso.JSFunctor;
import org.teavm.jso.JSObject;
/**
*
* @author Alexey Andreev
* @param <T>
*/
@JSFunctor
@FunctionalInterface
public interface JSSortFunction<T extends JSObject> {
public interface JSSortFunction<T> {
int compare(T a, T b);
}

View File

@ -19,14 +19,14 @@ import org.teavm.interop.NoSideEffects;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
public abstract class JSSymbol<T extends JSObject> implements JSObject {
public abstract class JSSymbol<T> implements JSObject {
@JSBody(params = "name", script = "return Symbol(name);")
public static native <T extends JSObject> JSSymbol<T> create(String name);
public static native <T> JSSymbol<T> create(String name);
@JSBody(params = "obj", script = "return obj[this];")
public native T get(JSObject obj);
public native T get(Object obj);
@JSBody(params = { "obj", "value" }, script = "obj[this] = value;")
@NoSideEffects
public native void set(JSObject obj, T value);
public native void set(Object obj, T value);
}

View File

@ -19,7 +19,7 @@ import org.teavm.interop.NoSideEffects;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
public abstract class JSWeakMap<K extends JSObject, V extends JSObject> implements JSObject {
public abstract class JSWeakMap<K, V> implements JSObject {
public abstract V get(K key);
public abstract boolean has(K key);
@ -30,5 +30,9 @@ public abstract class JSWeakMap<K extends JSObject, V extends JSObject> implemen
@JSBody(script = "return new WeakMap();")
@NoSideEffects
public static native <K extends JSObject, V extends JSObject> JSWeakMap<K, V> create();
public static native <K, V> JSWeakMap<K, V> create();
@JSBody(script = "return typeof WeakMap !== 'undefined';")
@NoSideEffects
public static native boolean isSupported();
}

View File

@ -19,12 +19,12 @@ import org.teavm.interop.NoSideEffects;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
public abstract class JSWeakRef<T extends JSObject> implements JSObject {
public abstract class JSWeakRef<T> implements JSObject {
public abstract T deref();
@JSBody(params = "value", script = "return new WeakRef(value);")
@NoSideEffects
public static native <T extends JSObject> JSWeakRef<T> create(T value);
public static native <T> JSWeakRef<T> create(T value);
@JSBody(script = "return typeof WeakRef !== 'undefined';")
@NoSideEffects

View File

@ -15,13 +15,12 @@
*/
package org.teavm.jso.dom.events;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.typedarrays.ArrayBuffer;
public interface MessageEvent extends Event {
@JSProperty
JSObject getData();
Object getData();
@JSProperty("data")
String getDataAsString();

View File

@ -15,14 +15,13 @@
*/
package org.teavm.jso.workers;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.dom.events.EventTarget;
import org.teavm.jso.dom.events.MessageEvent;
public interface MessagePort extends EventTarget {
void postMessage(JSObject message);
void postMessage(Object message);
void start();

View File

@ -16,7 +16,6 @@
package org.teavm.jso.workers;
import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject;
import org.teavm.jso.JSProperty;
import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.dom.events.MessageEvent;
@ -28,7 +27,7 @@ public abstract class Worker implements AbstractWorker {
@JSProperty("onmessage")
public abstract void onMessage(EventListener<MessageEvent> listener);
public abstract void postMessage(JSObject message);
public abstract void postMessage(Object message);
public abstract void terminate();
}

View File

@ -62,37 +62,37 @@ public final class JSWrapper {
if (wrappers != null) {
var type = JSObjects.typeOf(js);
if (type.equals("object") || type.equals("function")) {
var existingRef = wrappers.get(js);
var existing = !JSObjects.isUndefined(existingRef) ? existingRef.deref() : JSObjects.undefined();
var existingRef = get(wrappers, js);
var existing = !JSObjects.isUndefined(existingRef) ? deref(existingRef) : JSObjects.undefined();
if (JSObjects.isUndefined(existing)) {
var wrapper = new JSWrapper(js);
wrappers.set(js, JSWeakRef.create(wrapperToJs(wrapper)));
set(wrappers, js, createWeakRef(wrapperToJs(wrapper)));
return wrapper;
} else {
return jsToWrapper(existing);
}
} else if (type.equals("string")) {
var jsString = (JSString) js;
var existingRef = stringWrappers.get(jsString);
var existing = !JSObjects.isUndefined(existingRef) ? existingRef.deref() : JSObjects.undefined();
var existingRef = get(stringWrappers, jsString);
var existing = !JSObjects.isUndefined(existingRef) ? deref(existingRef) : JSObjects.undefined();
if (JSObjects.isUndefined(existing)) {
var wrapper = new JSWrapper(js);
var wrapperAsJs = wrapperToJs(wrapper);
stringWrappers.set(jsString, JSWeakRef.create(wrapperAsJs));
stringFinalizationRegistry.register(wrapperAsJs, jsString);
set(stringWrappers, jsString, createWeakRef(wrapperAsJs));
register(stringFinalizationRegistry, wrapperAsJs, jsString);
return wrapper;
} else {
return jsToWrapper(existing);
}
} else if (type.equals("number")) {
var jsNumber = (JSNumber) js;
var existingRef = numberWrappers.get(jsNumber);
var existing = !JSObjects.isUndefined(existingRef) ? existingRef.deref() : JSObjects.undefined();
var existingRef = get(numberWrappers, jsNumber);
var existing = !JSObjects.isUndefined(existingRef) ? deref(existingRef) : JSObjects.undefined();
if (JSObjects.isUndefined(existing)) {
var wrapper = new JSWrapper(js);
var wrapperAsJs = wrapperToJs(wrapper);
numberWrappers.set(jsNumber, JSWeakRef.create(wrapperAsJs));
numberFinalizationRegistry.register(wrapperAsJs, jsNumber);
set(numberWrappers, jsNumber, createWeakRef(wrapperAsJs));
register(numberFinalizationRegistry, wrapperAsJs, jsNumber);
return wrapper;
} else {
return jsToWrapper(existing);
@ -102,6 +102,37 @@ public final class JSWrapper {
return new JSWrapper(js);
}
@JSBody(params = "target", script = "return new WeakRef(target);")
@NoSideEffects
private static native JSWeakRef<JSObject> createWeakRef(JSObject target);
@JSBody(params = "target", script = "return target.deref();")
@NoSideEffects
private static native JSObject deref(JSWeakRef<JSObject> target);
@JSBody(params = { "registry", "target", "token" }, script = "return registry.register(target, token);")
@NoSideEffects
private static native void register(JSFinalizationRegistry registry, JSObject target, JSObject token);
@JSBody(params = { "map", "key" }, script = "return map.get(key);")
@NoSideEffects
private static native JSWeakRef<JSObject> get(JSMap<? extends JSObject, JSWeakRef<JSObject>> map, JSObject key);
@JSBody(params = { "map", "key", "value" }, script = "map.set(key, value);")
@NoSideEffects
private static native void set(JSMap<? extends JSObject, JSWeakRef<JSObject>> map, JSObject key, JSObject value);
@JSBody(params = { "map", "key" }, script = "return map.get(key);")
@NoSideEffects
private static native JSWeakRef<JSObject> get(JSWeakMap<? extends JSObject, JSWeakRef<JSObject>> map,
JSObject key);
@JSBody(params = { "map", "key", "value" }, script = "map.set(key, value);")
@NoSideEffects
private static native void set(JSWeakMap<? extends JSObject, JSWeakRef<JSObject>> map, JSObject key,
JSObject value);
@NoSideEffects
public static Object maybeWrap(Object o) {
return o == null || isJava(o) ? o : wrap(o);
}