From 2e4af24c99ae468f1bd9e6e5c8751dc53bfc2741 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Fri, 3 Apr 2015 18:51:03 +0400 Subject: [PATCH 1/5] Creating IndexedDB API wrappers --- .../org/teavm/dom/events/EventListener.java | 4 +- .../org/teavm/dom/events/EventTarget.java | 8 +- .../org/teavm/dom/html/HTMLBodyElement.java | 15 ++-- .../org/teavm/dom/indexeddb/EventHandler.java | 28 +++++++ .../teavm/dom/indexeddb/IDBCountRequest.java | 27 +++++++ .../org/teavm/dom/indexeddb/IDBCursor.java | 26 +++++++ .../teavm/dom/indexeddb/IDBCursorRequest.java | 27 +++++++ .../org/teavm/dom/indexeddb/IDBDatabase.java | 65 +++++++++++++++++ .../org/teavm/dom/indexeddb/IDBError.java | 28 +++++++ .../org/teavm/dom/indexeddb/IDBFactory.java | 48 ++++++++++++ .../teavm/dom/indexeddb/IDBGetRequest.java | 28 +++++++ .../org/teavm/dom/indexeddb/IDBIndex.java | 26 +++++++ .../teavm/dom/indexeddb/IDBObjectStore.java | 73 +++++++++++++++++++ .../indexeddb/IDBObjectStoreParameters.java | 45 ++++++++++++ .../teavm/dom/indexeddb/IDBOpenDBRequest.java | 31 ++++++++ .../org/teavm/dom/indexeddb/IDBRequest.java | 46 ++++++++++++ .../teavm/dom/indexeddb/IDBRequestSource.java | 25 +++++++ .../teavm/dom/indexeddb/IDBTransaction.java | 26 +++++++ .../dom/indexeddb/IDBVersionChangeEvent.java | 31 ++++++++ teavm-jso/src/main/java/org/teavm/jso/JS.java | 53 ++++++++++++++ 20 files changed, 647 insertions(+), 13 deletions(-) create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/EventHandler.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCountRequest.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursor.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorRequest.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBDatabase.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBError.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBFactory.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBGetRequest.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStoreParameters.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBOpenDBRequest.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBRequest.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBRequestSource.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBTransaction.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBVersionChangeEvent.java diff --git a/teavm-dom/src/main/java/org/teavm/dom/events/EventListener.java b/teavm-dom/src/main/java/org/teavm/dom/events/EventListener.java index cc0b6c491..6dc21b923 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/events/EventListener.java +++ b/teavm-dom/src/main/java/org/teavm/dom/events/EventListener.java @@ -23,6 +23,6 @@ import org.teavm.jso.JSObject; * @author Alexey Andreev */ @JSFunctor -public interface EventListener extends JSObject { - void handleEvent(Event evt); +public interface EventListener extends JSObject { + void handleEvent(E evt); } diff --git a/teavm-dom/src/main/java/org/teavm/dom/events/EventTarget.java b/teavm-dom/src/main/java/org/teavm/dom/events/EventTarget.java index 0a6e229cf..e30a7cdad 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/events/EventTarget.java +++ b/teavm-dom/src/main/java/org/teavm/dom/events/EventTarget.java @@ -22,13 +22,13 @@ import org.teavm.jso.JSObject; * @author Alexey Andreev */ public interface EventTarget extends JSObject { - void addEventListener(String type, EventListener listener, boolean useCapture); + void addEventListener(String type, EventListener listener, boolean useCapture); - void addEventListener(String type, EventListener listener); + void addEventListener(String type, EventListener listener); - void removeEventListener(String type, EventListener listener, boolean useCapture); + void removeEventListener(String type, EventListener listener, boolean useCapture); - void removeEventListener(String type, EventListener listener); + void removeEventListener(String type, EventListener listener); boolean dispatchEvent(Event evt); } diff --git a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLBodyElement.java b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLBodyElement.java index bcd99ebff..2bc0a4b45 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/html/HTMLBodyElement.java +++ b/teavm-dom/src/main/java/org/teavm/dom/html/HTMLBodyElement.java @@ -15,6 +15,7 @@ */ package org.teavm.dom.html; +import org.teavm.dom.events.Event; import org.teavm.dom.events.EventListener; import org.teavm.jso.JSProperty; @@ -24,24 +25,24 @@ import org.teavm.jso.JSProperty; */ public interface HTMLBodyElement extends HTMLElement { @JSProperty("onbeforeunload") - void setOnBeforeUnload(EventListener listener); + void setOnBeforeUnload(EventListener listener); @JSProperty("onerror") - void setOnError(EventListener listener); + void setOnError(EventListener listener); @JSProperty("onload") - void setOnLoad(EventListener listener); + void setOnLoad(EventListener listener); @JSProperty("onmessage") - void setOnMessage(EventListener listener); + void setOnMessage(EventListener listener); @JSProperty("onoffline") - void setOnOffline(EventListener listener); + void setOnOffline(EventListener listener); @JSProperty("ononline") - void setOnOnline(EventListener listener); + void setOnOnline(EventListener listener); @JSProperty("ononunload") - void setOnUnload(EventListener listener); + void setOnUnload(EventListener listener); } diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/EventHandler.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/EventHandler.java new file mode 100644 index 000000000..19500ce4f --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/EventHandler.java @@ -0,0 +1,28 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSFunctor; +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +@JSFunctor +public interface EventHandler extends JSObject { + void handleEvent(); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCountRequest.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCountRequest.java new file mode 100644 index 000000000..c11a24bdb --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCountRequest.java @@ -0,0 +1,27 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public interface IDBCountRequest extends IDBRequest { + @JSProperty + int getResult(); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursor.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursor.java new file mode 100644 index 000000000..6eb09dfac --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursor.java @@ -0,0 +1,26 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +public interface IDBCursor extends JSObject { + +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorRequest.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorRequest.java new file mode 100644 index 000000000..4066b60e5 --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorRequest.java @@ -0,0 +1,27 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public interface IDBCursorRequest extends IDBRequest { + @JSProperty + IDBCursor getResult(); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBDatabase.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBDatabase.java new file mode 100644 index 000000000..c9fbda5d7 --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBDatabase.java @@ -0,0 +1,65 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.dom.events.EventTarget; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public interface IDBDatabase extends EventTarget { + String TRANSACTION_READONLY = "readonly"; + + String TRANSACTION_READWRITE = "readwrite"; + + String TRANSACTION_VERSIONCHANGE = "versionchange"; + + @JSProperty + String getName(); + + @JSProperty + int getVersion(); + + @JSProperty + String[] getObjectStoreNames(); + + IDBObjectStore createObjectStore(String name, IDBObjectStoreParameters optionalParameters); + + IDBObjectStore createObjectStore(String name); + + void deleteObjectStore(String name); + + IDBTransaction transaction(String storeName, String transactionMode); + + IDBTransaction transaction(String storeName); + + IDBTransaction transaction(String[] storeNames, String transactionMode); + + IDBTransaction transaction(String[] storeNames); + + void close(); + + @JSProperty("onabort") + void setOnAbort(EventHandler handler); + + @JSProperty("onerror") + void setOnError(EventHandler handler); + + @JSProperty("onversionchange") + void setOnVersionChange(EventHandler handler); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBError.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBError.java new file mode 100644 index 000000000..16fd19f2f --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBError.java @@ -0,0 +1,28 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public abstract class IDBError implements JSObject { + @JSProperty + public abstract String getName(); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBFactory.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBFactory.java new file mode 100644 index 000000000..b8e5199d4 --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBFactory.java @@ -0,0 +1,48 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JS; +import org.teavm.jso.JSBody; +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +public abstract class IDBFactory implements JSObject { + public static boolean isSupported() { + return !JS.isUndefined(getInstanceImpl()); + } + + public static IDBFactory getInstance() { + IDBFactory factory = getInstanceImpl(); + if (JS.isUndefined(factory)) { + throw new IllegalStateException("IndexedDB is not supported in this browser"); + } + return factory; + } + + @JSBody(params = {}, script = "return window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || " + + "window.msIndexedDB;") + static native IDBFactory getInstanceImpl(); + + public abstract IDBOpenDBRequest open(String name, int version); + + public abstract IDBOpenDBRequest deleteDatabase(String name); + + public abstract int cmp(JSObject a, JSObject b); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBGetRequest.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBGetRequest.java new file mode 100644 index 000000000..60ef72e62 --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBGetRequest.java @@ -0,0 +1,28 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public interface IDBGetRequest extends IDBRequest { + @JSProperty + JSObject getResult(); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java new file mode 100644 index 000000000..c2f459efe --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java @@ -0,0 +1,26 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +public interface IDBIndex extends JSObject { + +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java new file mode 100644 index 000000000..4f5ae28be --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java @@ -0,0 +1,73 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.*; + +/** + * + * @author Alexey Andreev + */ +public abstract class IDBObjectStore implements JSObject { + @JSProperty + public abstract String getName(); + + @JSProperty("keyPath") + abstract JSObject getKeyPathImpl(); + + public final String[] getKeyPath() { + JSObject result = getKeyPathImpl(); + if (JS.getType(result) == JSType.STRING) { + return new String[] { JS.unwrapString(result) }; + } else { + return JS.unwrapArray((JSStringArray)result); + } + } + + @JSProperty + public abstract String[] getIndexNames(); + + @JSProperty + public abstract boolean isAutoIncrement(); + + public abstract IDBRequest put(JSObject value, JSObject key); + + public abstract IDBRequest put(JSObject value); + + public abstract IDBRequest add(JSObject value, JSObject key); + + public abstract IDBRequest add(JSObject value); + + public abstract IDBRequest delete(JSObject key); + + public abstract IDBGetRequest get(JSObject key); + + public abstract IDBRequest clear(); + + public abstract IDBCursorRequest openCursor(); + + public abstract IDBIndex createIndex(String name, String key); + + public abstract IDBIndex createIndex(String name, String[] keys); + + public abstract IDBIndex index(String name); + + public abstract void deleteIndex(String name); + + public abstract IDBCountRequest count(); + + public abstract IDBCountRequest count(JSObject key); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStoreParameters.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStoreParameters.java new file mode 100644 index 000000000..a25ea5141 --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStoreParameters.java @@ -0,0 +1,45 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSBody; +import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public abstract class IDBObjectStoreParameters implements JSObject { + @JSBody(params = "", script = "return {};") + public static native IDBObjectStoreParameters create(); + + public final IDBObjectStoreParameters keyPath(String... keys) { + setKeyPath(keys); + return this; + } + + public final IDBObjectStoreParameters autoIncrement(boolean autoIncrement) { + setAutoIncrement(autoIncrement); + return this; + } + + @JSProperty + abstract void setKeyPath(String[] keys); + + @JSProperty + abstract void setAutoIncrement(boolean autoIncrement); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBOpenDBRequest.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBOpenDBRequest.java new file mode 100644 index 000000000..0e737d210 --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBOpenDBRequest.java @@ -0,0 +1,31 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.dom.events.EventListener; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public interface IDBOpenDBRequest extends IDBRequest { + @JSProperty + void setOnBlocked(EventHandler handler); + + @JSProperty("onupgradeneeded") + void setOnUpgradeNeeded(EventListener listener); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBRequest.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBRequest.java new file mode 100644 index 000000000..af3cd608f --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBRequest.java @@ -0,0 +1,46 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.dom.events.EventTarget; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public interface IDBRequest extends EventTarget { + String STATE_PENDING = "pending"; + String STATE_DONE = "done"; + + @JSProperty + IDBError getError(); + + @JSProperty + IDBRequestSource getSource(); + + @JSProperty + IDBTransaction getTransaction(); + + @JSProperty + String getReadyState(); + + @JSProperty("onerror") + void setOnError(EventHandler handler); + + @JSProperty("onsuccess") + void setOnSuccess(EventHandler handler); +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBRequestSource.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBRequestSource.java new file mode 100644 index 000000000..47d9d13ba --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBRequestSource.java @@ -0,0 +1,25 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +public interface IDBRequestSource extends JSObject { +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBTransaction.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBTransaction.java new file mode 100644 index 000000000..8f196f221 --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBTransaction.java @@ -0,0 +1,26 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +public interface IDBTransaction extends JSObject { + +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBVersionChangeEvent.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBVersionChangeEvent.java new file mode 100644 index 000000000..7ebfe048e --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBVersionChangeEvent.java @@ -0,0 +1,31 @@ +/* + * 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.dom.indexeddb; + +import org.teavm.dom.events.Event; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public interface IDBVersionChangeEvent extends Event { + @JSProperty + int getOldVersion(); + + @JSProperty + int getNewVersion(); +} 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 a0dc42cde..4811fe1fa 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JS.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JS.java @@ -15,6 +15,7 @@ */ package org.teavm.jso; +import java.lang.reflect.Array; import java.util.Iterator; import org.teavm.dependency.PluggableDependency; import org.teavm.javascript.spi.InjectedBy; @@ -347,6 +348,58 @@ public final class JS { @InjectedBy(JSNativeGenerator.class) public static native char unwrapCharacter(JSObject obj); + public static T[] unwrapArray(Class type, JSArray array) { + @SuppressWarnings("unchecked") + T[] result = (T[])Array.newInstance(type, array.getLength()); + for (int i = 0; i < result.length; ++i) { + result[i] = array.get(i); + } + return result; + } + + public static T[][] unwrapArray2(Class type, JSArray> array) { + @SuppressWarnings("unchecked") + T[][] result = (T[][])Array.newInstance(Array.newInstance(type, 0).getClass(), array.getLength()); + for (int i = 0; i < result.length; ++i) { + result[i] = unwrapArray(type, array.get(i)); + } + return result; + } + + public static T[][][] unwrapArray3(Class type, JSArray>> array) { + Class baseType = Array.newInstance(type, 0).getClass(); + @SuppressWarnings("unchecked") + T[][][] result = (T[][][])Array.newInstance(Array.newInstance(baseType, 0).getClass(), array.getLength()); + for (int i = 0; i < result.length; ++i) { + result[i] = unwrapArray2(type, array.get(i)); + } + return result; + } + + public static String[] unwrapArray(JSStringArray array) { + String[] result = new String[array.getLength()]; + for (int i = 0; i < result.length; ++i) { + result[i] = array.get(i); + } + return result; + } + + public static String[][] unwrapArray2(JSArray array) { + String[][] result = new String[array.getLength()][]; + for (int i = 0; i < result.length; ++i) { + result[i] = unwrapArray(array.get(i)); + } + return result; + } + + public static String[][][] unwrapArray3(JSArray> array) { + String[][][] result = new String[array.getLength()][][]; + for (int i = 0; i < result.length; ++i) { + result[i] = unwrapArray2(array.get(i)); + } + return result; + } + @InjectedBy(JSNativeGenerator.class) public static native boolean isUndefined(JSObject obj); From c3f8764bdc3e5b3e65ce41bbad14f53d2f38e204 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sat, 4 Apr 2015 00:09:25 +0300 Subject: [PATCH 2/5] More IndexedDB wrappers --- .../org/teavm/dom/indexeddb/IDBCursor.java | 32 +++++++++++++ .../teavm/dom/indexeddb/IDBCursorSource.java | 10 ++++ .../org/teavm/dom/indexeddb/IDBIndex.java | 39 ++++++++++++++- .../org/teavm/dom/indexeddb/IDBKeyRange.java | 48 +++++++++++++++++++ .../teavm/dom/indexeddb/IDBObjectStore.java | 4 +- .../teavm/dom/indexeddb/IDBOpenDBRequest.java | 3 ++ .../teavm/dom/indexeddb/IDBTransaction.java | 24 +++++++++- 7 files changed, 157 insertions(+), 3 deletions(-) create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorSource.java create mode 100644 teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBKeyRange.java diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursor.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursor.java index 6eb09dfac..572613ad3 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursor.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursor.java @@ -15,12 +15,44 @@ */ package org.teavm.dom.indexeddb; +import org.teavm.jso.JSMethod; import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; /** * * @author Alexey Andreev */ public interface IDBCursor extends JSObject { + String DIRECTION_NEXT = "next"; + String DIRECTION_NEXT_UNIQUE = "nextunique"; + + String DIRECTION_PREVIOUS = "prev"; + + String DIRECTION_PREVIOUS_UNIQUE = "prevunique"; + + @JSProperty + IDBCursorSource getSource(); + + @JSProperty + String getDirection(); + + @JSProperty + JSObject getKey(); + + @JSProperty + JSObject getValue(); + + @JSProperty + JSObject getPrimaryKey(); + + IDBRequest update(JSObject value); + + void advance(int count); + + @JSMethod("continue") + void doContinue(); + + IDBRequest delete(); } diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorSource.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorSource.java new file mode 100644 index 000000000..10cc7884b --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorSource.java @@ -0,0 +1,10 @@ +package org.teavm.dom.indexeddb; + +import org.teavm.jso.JSObject; + +/** + * + * @author Alexey Andreev + */ +public interface IDBCursorSource extends JSObject { +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java index c2f459efe..379e9ad9f 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java @@ -15,12 +15,49 @@ */ package org.teavm.dom.indexeddb; +import org.teavm.jso.JS; import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; +import org.teavm.jso.JSStringArray; +import org.teavm.jso.JSType; /** * * @author Alexey Andreev */ -public interface IDBIndex extends JSObject { +public abstract class IDBIndex implements JSObject, IDBCursorSource { + @JSProperty + public abstract String getName(); + @JSProperty("keyPath") + abstract JSObject getKeyPathImpl(); + + public final String[] getKeyPath() { + JSObject result = getKeyPathImpl(); + if (JS.getType(result) == JSType.STRING) { + return new String[] { JS.unwrapString(result) }; + } else { + return JS.unwrapArray((JSStringArray)result); + } + } + + @JSProperty + public abstract boolean isMultiEntry(); + + @JSProperty + public abstract boolean isUnique(); + + public abstract IDBCursorRequest openCursor(); + + public abstract IDBCursorRequest openCursor(IDBKeyRange range); + + public abstract IDBCursorRequest openKeyCursor(); + + public abstract IDBGetRequest get(JSObject key); + + public abstract IDBGetRequest getKey(JSObject key); + + public abstract IDBCountRequest count(JSObject key); + + public abstract IDBCountRequest count(); } diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBKeyRange.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBKeyRange.java new file mode 100644 index 000000000..cc835fb7b --- /dev/null +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBKeyRange.java @@ -0,0 +1,48 @@ +package org.teavm.dom.indexeddb; + +import org.teavm.jso.JSBody; +import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; + +/** + * + * @author Alexey Andreev + */ +public abstract class IDBKeyRange implements JSObject { + @JSProperty + public abstract JSObject getLower(); + + @JSProperty + public abstract JSObject getUpper(); + + @JSProperty + public abstract boolean isLowerOpen(); + + @JSProperty + public abstract boolean isUpperOpen(); + + @JSBody(params = "value", script = "return IDBKeyRange.only(value);") + public static native IDBKeyRange only(JSObject value); + + @JSBody(params = { "lower", "open" }, script = "return IDBKeyRange.lowerBound(lower, open);") + public static native IDBKeyRange lowerBound(JSObject lower, boolean open); + + public static IDBKeyRange lowerBound(JSObject lower) { + return lowerBound(lower, false); + } + + @JSBody(params = { "upper", "open" }, script = "return IDBKeyRange.upperBound(upper, open);") + public static native IDBKeyRange upperBound(JSObject upper, boolean open); + + public static IDBKeyRange upperBound(JSObject upper) { + return upperBound(upper, false); + } + + @JSBody(params = { "lower", "upper", "lowerOpen", "upperOpen" }, + script = "return IDBKeyRange.bound(lower, upper, lowerOpen, upperOpen);") + public static native IDBKeyRange bound(JSObject lower, JSObject upper, boolean lowerOpen, boolean upperOpen); + + public static IDBKeyRange bound(JSObject lower, JSObject upper) { + return bound(lower, upper, false, false); + } +} diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java index 4f5ae28be..6521b3613 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java @@ -21,7 +21,7 @@ import org.teavm.jso.*; * * @author Alexey Andreev */ -public abstract class IDBObjectStore implements JSObject { +public abstract class IDBObjectStore implements JSObject, IDBCursorSource { @JSProperty public abstract String getName(); @@ -59,6 +59,8 @@ public abstract class IDBObjectStore implements JSObject { public abstract IDBCursorRequest openCursor(); + public abstract IDBCursorRequest openCursor(IDBKeyRange range); + public abstract IDBIndex createIndex(String name, String key); public abstract IDBIndex createIndex(String name, String[] keys); diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBOpenDBRequest.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBOpenDBRequest.java index 0e737d210..6f0f4ad10 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBOpenDBRequest.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBOpenDBRequest.java @@ -23,6 +23,9 @@ import org.teavm.jso.JSProperty; * @author Alexey Andreev */ public interface IDBOpenDBRequest extends IDBRequest { + @JSProperty + IDBDatabase getResult(); + @JSProperty void setOnBlocked(EventHandler handler); diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBTransaction.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBTransaction.java index 8f196f221..af8192adb 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBTransaction.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBTransaction.java @@ -15,12 +15,34 @@ */ package org.teavm.dom.indexeddb; +import org.teavm.dom.events.EventTarget; import org.teavm.jso.JSObject; +import org.teavm.jso.JSProperty; /** * * @author Alexey Andreev */ -public interface IDBTransaction extends JSObject { +public interface IDBTransaction extends JSObject, EventTarget { + @JSProperty + String getMode(); + @JSProperty + IDBDatabase getDb(); + + @JSProperty + IDBError getError(); + + IDBObjectStore objectStore(String name); + + void abort(); + + @JSProperty("onabort") + void setOnAbort(EventHandler handler); + + @JSProperty("oncomplete") + void setOnComplete(EventHandler handler); + + @JSProperty("onerror") + void setOnError(EventHandler handler); } From 30d601e8076e082c7f9f15300808d771f4132599 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sat, 4 Apr 2015 18:29:18 +0300 Subject: [PATCH 3/5] Fix IndexedDB wrappers --- .../resources/org/teavm/javascript/runtime.js | 6 +- .../teavm/dom/indexeddb/IDBCursorSource.java | 15 +++ .../org/teavm/dom/indexeddb/IDBIndex.java | 2 +- .../org/teavm/dom/indexeddb/IDBKeyRange.java | 15 +++ .../teavm/dom/indexeddb/IDBObjectStore.java | 2 +- .../indexeddb/IDBObjectStoreParameters.java | 2 +- teavm-jso/src/main/java/org/teavm/jso/JS.java | 10 +- .../jso/plugin/JavascriptNativeProcessor.java | 125 ++++++++++++++++-- .../java/org/teavm/samples/hello/Client.java | 6 +- .../java/org/teavm/samples/video/Player.java | 58 ++++---- 10 files changed, 188 insertions(+), 53 deletions(-) diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index b3629bfb5..142d1cc95 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -473,7 +473,11 @@ TeaVMThread.prototype.start = function(callback) { throw new Error("Another thread is running"); } this.status = 0; - this.completeCallback = callback ? callback : function() {}; + this.completeCallback = callback ? callback : function(result) { + if (result instanceof Error) { + throw result; + } + }; this.run(); } TeaVMThread.prototype.resume = function() { diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorSource.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorSource.java index 10cc7884b..343d4b979 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorSource.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBCursorSource.java @@ -1,3 +1,18 @@ +/* + * 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.dom.indexeddb; import org.teavm.jso.JSObject; diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java index 379e9ad9f..e568074a5 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBIndex.java @@ -37,7 +37,7 @@ public abstract class IDBIndex implements JSObject, IDBCursorSource { if (JS.getType(result) == JSType.STRING) { return new String[] { JS.unwrapString(result) }; } else { - return JS.unwrapArray((JSStringArray)result); + return JS.unwrapStringArray((JSStringArray)result); } } diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBKeyRange.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBKeyRange.java index cc835fb7b..8ebbd4f69 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBKeyRange.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBKeyRange.java @@ -1,3 +1,18 @@ +/* + * 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.dom.indexeddb; import org.teavm.jso.JSBody; diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java index 6521b3613..8d6549fce 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStore.java @@ -33,7 +33,7 @@ public abstract class IDBObjectStore implements JSObject, IDBCursorSource { if (JS.getType(result) == JSType.STRING) { return new String[] { JS.unwrapString(result) }; } else { - return JS.unwrapArray((JSStringArray)result); + return JS.unwrapStringArray((JSStringArray)result); } } diff --git a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStoreParameters.java b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStoreParameters.java index a25ea5141..0761b559d 100644 --- a/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStoreParameters.java +++ b/teavm-dom/src/main/java/org/teavm/dom/indexeddb/IDBObjectStoreParameters.java @@ -24,7 +24,7 @@ import org.teavm.jso.JSProperty; * @author Alexey Andreev */ public abstract class IDBObjectStoreParameters implements JSObject { - @JSBody(params = "", script = "return {};") + @JSBody(params = {}, script = "return {};") public static native IDBObjectStoreParameters create(); public final IDBObjectStoreParameters keyPath(String... keys) { 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 4811fe1fa..fddc36eff 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/JS.java +++ b/teavm-jso/src/main/java/org/teavm/jso/JS.java @@ -376,7 +376,7 @@ public final class JS { return result; } - public static String[] unwrapArray(JSStringArray array) { + public static String[] unwrapStringArray(JSStringArray array) { String[] result = new String[array.getLength()]; for (int i = 0; i < result.length; ++i) { result[i] = array.get(i); @@ -384,18 +384,18 @@ public final class JS { return result; } - public static String[][] unwrapArray2(JSArray array) { + public static String[][] unwrapStringArray2(JSArray array) { String[][] result = new String[array.getLength()][]; for (int i = 0; i < result.length; ++i) { - result[i] = unwrapArray(array.get(i)); + result[i] = unwrapStringArray(array.get(i)); } return result; } - public static String[][][] unwrapArray3(JSArray> array) { + public static String[][][] unwrapStringArray3(JSArray> array) { String[][][] result = new String[array.getLength()][][]; for (int i = 0; i < result.length; ++i) { - result[i] = unwrapArray2(array.get(i)); + result[i] = unwrapStringArray2(array.get(i)); } return result; } diff --git a/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java b/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java index 76e04f012..f8915f76b 100644 --- a/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java +++ b/teavm-jso/src/main/java/org/teavm/jso/plugin/JavascriptNativeProcessor.java @@ -502,19 +502,26 @@ class JavascriptNativeProcessor { if (type instanceof ValueType.Primitive) { switch (((ValueType.Primitive)type).getKind()) { case BOOLEAN: - return unwrap(var, "unwrapBoolean", ValueType.BOOLEAN, location.getSourceLocation()); + return unwrap(var, "unwrapBoolean", ValueType.parse(JSObject.class), ValueType.BOOLEAN, + location.getSourceLocation()); case BYTE: - return unwrap(var, "unwrapByte", ValueType.BYTE, location.getSourceLocation()); + return unwrap(var, "unwrapByte", ValueType.parse(JSObject.class), ValueType.BYTE, + location.getSourceLocation()); case SHORT: - return unwrap(var, "unwrapShort", ValueType.SHORT, location.getSourceLocation()); + return unwrap(var, "unwrapShort", ValueType.parse(JSObject.class), ValueType.SHORT, + location.getSourceLocation()); case INTEGER: - return unwrap(var, "unwrapInt", ValueType.INTEGER, location.getSourceLocation()); + return unwrap(var, "unwrapInt", ValueType.parse(JSObject.class), ValueType.INTEGER, + location.getSourceLocation()); case CHARACTER: - return unwrap(var, "unwrapCharacter", ValueType.CHARACTER, location.getSourceLocation()); + return unwrap(var, "unwrapCharacter", ValueType.parse(JSObject.class), ValueType.CHARACTER, + location.getSourceLocation()); case DOUBLE: - return unwrap(var, "unwrapDouble", ValueType.DOUBLE, location.getSourceLocation()); + return unwrap(var, "unwrapDouble", ValueType.parse(JSObject.class), ValueType.DOUBLE, + location.getSourceLocation()); case FLOAT: - return unwrap(var, "unwrapFloat", ValueType.FLOAT, location.getSourceLocation()); + return unwrap(var, "unwrapFloat", ValueType.parse(JSObject.class), ValueType.FLOAT, + location.getSourceLocation()); case LONG: break; } @@ -523,8 +530,9 @@ class JavascriptNativeProcessor { if (className.equals(JSObject.class.getName())) { return var; } else if (className.equals("java.lang.String")) { - return unwrap(var, "unwrapString", ValueType.object("java.lang.String"), location.getSourceLocation()); - } else { + return unwrap(var, "unwrapString", ValueType.parse(JSObject.class), ValueType.parse(String.class), + location.getSourceLocation()); + } else if (isNative(className)) { Variable result = program.createVariable(); CastInstruction castInsn = new CastInstruction(); castInsn.setReceiver(result); @@ -534,16 +542,58 @@ class JavascriptNativeProcessor { replacement.add(castInsn); return result; } + } else if (type instanceof ValueType.Array) { + return unwrapArray(location, var, (ValueType.Array)type); } diagnostics.error(location, "Unsupported type: {{t0}}", type); return var; } - private Variable unwrap(Variable var, String methodName, ValueType resultType, InstructionLocation location) { + private Variable unwrapArray(CallLocation location, Variable var, ValueType.Array type) { + ValueType itemType = type; + int degree = 0; + while (itemType instanceof ValueType.Array) { + ++degree; + itemType = ((ValueType.Array)itemType).getItemType(); + } + if (degree > 3) { + diagnostics.error(location, "Unsupported type: {{t0}}", type); + return var; + } + + if (itemType instanceof ValueType.Object) { + String className = ((ValueType.Object)itemType).getClassName(); + if (className.equals("java.lang.String")) { + String methodName = "unwrapStringArray"; + if (degree > 1) { + methodName += degree; + } + ValueType argType = degree == 1 ? ValueType.parse(JSStringArray.class) : + ValueType.parse(JSArray.class); + return unwrap(var, methodName, argType, type, location.getSourceLocation()); + } else if (isNative(className)) { + return unwrapObjectArray(location, var, degree, itemType, type); + } + } + diagnostics.error(location, "Unsupported type: {{t0}}", type); + return var; + } + + private Variable unwrap(Variable var, String methodName, ValueType argType, ValueType resultType, + InstructionLocation location) { + if (!argType.isObject(JSObject.class.getName())) { + Variable castValue = program.createVariable(); + CastInstruction castInsn = new CastInstruction(); + castInsn.setValue(var); + castInsn.setReceiver(castValue); + castInsn.setLocation(location); + castInsn.setTargetType(argType); + replacement.add(castInsn); + var = castValue; + } Variable result = program.createVariable(); InvokeInstruction insn = new InvokeInstruction(); - insn.setMethod(new MethodReference(JS.class.getName(), methodName, ValueType.object(JSObject.class.getName()), - resultType)); + insn.setMethod(new MethodReference(JS.class.getName(), methodName, argType, resultType)); insn.getArguments().add(var); insn.setReceiver(result); insn.setType(InvocationType.SPECIAL); @@ -552,6 +602,57 @@ class JavascriptNativeProcessor { return result; } + private Variable unwrapObjectArray(CallLocation location, Variable var, int degree, ValueType itemType, + ValueType expectedType) { + String methodName = "unwrapArray"; + if (degree > 1) { + methodName += degree; + } + ValueType resultType = ValueType.parse(JSObject.class); + for (int i = 0; i < degree; ++i) { + resultType = ValueType.arrayOf(resultType); + } + + Variable classVar = program.createVariable(); + ClassConstantInstruction classInsn = new ClassConstantInstruction(); + classInsn.setConstant(itemType); + classInsn.setReceiver(classVar); + classInsn.setLocation(location.getSourceLocation()); + replacement.add(classInsn); + + Variable castValue = program.createVariable(); + CastInstruction castInsn = new CastInstruction(); + castInsn.setValue(var); + castInsn.setReceiver(castValue); + castInsn.setLocation(location.getSourceLocation()); + castInsn.setTargetType(ValueType.parse(JSArray.class)); + replacement.add(castInsn); + var = castValue; + + Variable result = program.createVariable(); + InvokeInstruction insn = new InvokeInstruction(); + insn.setMethod(new MethodReference(JS.class.getName(), methodName, ValueType.parse(Class.class), + ValueType.parse(JSArray.class), resultType)); + insn.getArguments().add(classVar); + insn.getArguments().add(var); + insn.setReceiver(result); + insn.setType(InvocationType.SPECIAL); + insn.setLocation(location.getSourceLocation()); + replacement.add(insn); + var = result; + + Variable castResult = program.createVariable(); + castInsn = new CastInstruction(); + castInsn.setValue(var); + castInsn.setReceiver(castResult); + castInsn.setLocation(location.getSourceLocation()); + castInsn.setTargetType(expectedType); + replacement.add(castInsn); + var = castResult; + + return var; + } + private Variable wrapArgument(CallLocation location, Variable var, ValueType type) { if (type instanceof ValueType.Object) { String className = ((ValueType.Object)type).getClassName(); diff --git a/teavm-samples/teavm-samples-hello/src/main/java/org/teavm/samples/hello/Client.java b/teavm-samples/teavm-samples-hello/src/main/java/org/teavm/samples/hello/Client.java index 425bac1b2..304d31e50 100644 --- a/teavm-samples/teavm-samples-hello/src/main/java/org/teavm/samples/hello/Client.java +++ b/teavm-samples/teavm-samples-hello/src/main/java/org/teavm/samples/hello/Client.java @@ -18,8 +18,8 @@ package org.teavm.samples.hello; import org.teavm.dom.ajax.ReadyStateChangeHandler; import org.teavm.dom.ajax.XMLHttpRequest; import org.teavm.dom.browser.Window; -import org.teavm.dom.events.Event; import org.teavm.dom.events.EventListener; +import org.teavm.dom.events.MouseEvent; import org.teavm.dom.html.HTMLButtonElement; import org.teavm.dom.html.HTMLDocument; import org.teavm.dom.html.HTMLElement; @@ -36,8 +36,8 @@ public final class Client { } public static void main(String[] args) { - helloButton.addEventListener("click", new EventListener() { - @Override public void handleEvent(Event evt) { + helloButton.addEventListener("click", new EventListener() { + @Override public void handleEvent(MouseEvent evt) { sayHello(); } }); diff --git a/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java b/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java index f6e3a45cd..dd7c37fe2 100644 --- a/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java +++ b/teavm-samples/teavm-samples-video/src/main/java/org/teavm/samples/video/Player.java @@ -16,8 +16,8 @@ package org.teavm.samples.video; import org.teavm.dom.browser.Window; -import org.teavm.dom.events.Event; import org.teavm.dom.events.EventListener; +import org.teavm.dom.events.MouseEvent; import org.teavm.dom.html.HTMLBodyElement; import org.teavm.dom.html.HTMLButtonElement; import org.teavm.dom.html.HTMLDocument; @@ -69,126 +69,126 @@ public final class Player { HTMLButtonElement loadButton = (HTMLButtonElement)document.createElement("button"); loadButton.appendChild(document.createTextNode("load()")); - loadButton.addEventListener("click", new EventListener() { + loadButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.load(); } }); HTMLButtonElement playButton = (HTMLButtonElement)document.createElement("button"); playButton.appendChild(document.createTextNode("play()")); - playButton.addEventListener("click", new EventListener() { + playButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.play(); } }); HTMLButtonElement pauseButton = (HTMLButtonElement)document.createElement("button"); pauseButton.appendChild(document.createTextNode("pause()")); - pauseButton.addEventListener("click", new EventListener() { + pauseButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.pause(); } }); HTMLButtonElement currentTimePlusButton = (HTMLButtonElement)document.createElement("button"); currentTimePlusButton.appendChild(document.createTextNode("currentTime+=10")); - currentTimePlusButton.addEventListener("click", new EventListener() { + currentTimePlusButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setCurrentTime(video.getCurrentTime() + 10); } }); HTMLButtonElement currentTimeMinusButton = (HTMLButtonElement)document.createElement("button"); currentTimeMinusButton.appendChild(document.createTextNode("currentTime-=10")); - currentTimeMinusButton.addEventListener("click", new EventListener() { + currentTimeMinusButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setCurrentTime(video.getCurrentTime() - 10); } }); HTMLButtonElement currentTime50Button = (HTMLButtonElement)document.createElement("button"); currentTime50Button.appendChild(document.createTextNode("currentTime=50")); - currentTime50Button.addEventListener("click", new EventListener() { + currentTime50Button.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setCurrentTime(50); } }); HTMLButtonElement playbackRateIncrementButton = (HTMLButtonElement)document.createElement("button"); playbackRateIncrementButton.appendChild(document.createTextNode("playbackRate++")); - playbackRateIncrementButton.addEventListener("click", new EventListener() { + playbackRateIncrementButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setPlaybackRate(video.getPlaybackRate() + 1); } }); HTMLButtonElement playbackRateDecrementButton = (HTMLButtonElement)document.createElement("button"); playbackRateDecrementButton.appendChild(document.createTextNode("playbackRate--")); - playbackRateDecrementButton.addEventListener("click", new EventListener() { + playbackRateDecrementButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setPlaybackRate(video.getPlaybackRate() - 1); } }); HTMLButtonElement playbackRatePlusButton = (HTMLButtonElement)document.createElement("button"); playbackRatePlusButton.appendChild(document.createTextNode("playbackRate+=0.1")); - playbackRatePlusButton.addEventListener("click", new EventListener() { + playbackRatePlusButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setPlaybackRate(video.getPlaybackRate() + 0.1); } }); HTMLButtonElement playbackRateMinusButton = (HTMLButtonElement)document.createElement("button"); playbackRateMinusButton.appendChild(document.createTextNode("playbackRate-=0.1")); - playbackRateMinusButton.addEventListener("click", new EventListener() { + playbackRateMinusButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setPlaybackRate(video.getPlaybackRate() - 0.1); } }); HTMLButtonElement volumePlusButton = (HTMLButtonElement)document.createElement("button"); volumePlusButton.appendChild(document.createTextNode("volume+=0.1")); - volumePlusButton.addEventListener("click", new EventListener() { + volumePlusButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setVolume(video.getVolume() + 0.1f); } }); HTMLButtonElement volumeMinusButton = (HTMLButtonElement)document.createElement("button"); volumeMinusButton.appendChild(document.createTextNode("volume-=0.1")); - volumeMinusButton.addEventListener("click", new EventListener() { + volumeMinusButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setVolume(video.getVolume() - 0.1f); } }); HTMLButtonElement muteButton = (HTMLButtonElement)document.createElement("button"); muteButton.appendChild(document.createTextNode("muted=true")); - muteButton.addEventListener("click", new EventListener() { + muteButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setMuted(true); } }); HTMLButtonElement unmuteButton = (HTMLButtonElement)document.createElement("button"); unmuteButton.appendChild(document.createTextNode("muted=false")); - unmuteButton.addEventListener("click", new EventListener() { + unmuteButton.addEventListener("click", new EventListener() { @Override - public void handleEvent(Event evt) { + public void handleEvent(MouseEvent evt) { video.setMuted(false); } }); From d66595b9c70aae834beca87c0619ecd3063a1100 Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 5 Apr 2015 16:06:15 +0300 Subject: [PATCH 4/5] Fix dependency issue with async methods --- .../platform/plugin/AsyncMethodGenerator.java | 52 ++++++++++++++++++- .../plugin/EnumDependencySupport.java | 1 - .../platform/plugin/FakeAsyncCallback.java | 32 ++++++++++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 teavm-platform/src/main/java/org/teavm/platform/plugin/FakeAsyncCallback.java diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java index f3a417540..7addb5337 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java @@ -19,6 +19,8 @@ import java.io.IOException; import org.teavm.codegen.SourceWriter; import org.teavm.dependency.DependencyAgent; import org.teavm.dependency.DependencyPlugin; +import org.teavm.dependency.DependencyType; +import org.teavm.dependency.DependencyTypeFilter; import org.teavm.dependency.MethodDependency; import org.teavm.javascript.spi.Generator; import org.teavm.javascript.spi.GeneratorContext; @@ -88,13 +90,61 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { } @Override - public void methodAchieved(DependencyAgent checker, MethodDependency method, CallLocation location) { + public void methodAchieved(final DependencyAgent checker, final MethodDependency method, CallLocation location) { MethodReference asyncRef = getAsyncReference(method.getReference()); MethodDependency asyncMethod = checker.linkMethod(asyncRef, location); int paramCount = method.getReference().parameterCount(); for (int i = 0; i <= paramCount; ++i) { method.getVariable(i).connect(asyncMethod.getVariable(i)); } + asyncMethod.getVariable(paramCount + 1).propagate(checker.getType(FakeAsyncCallback.class.getName())); + + if (method.getResult() != null) { + MethodDependency completeMethod = checker.linkMethod( + new MethodReference(FakeAsyncCallback.class, "complete", Object.class, void.class), null); + completeMethod.getVariable(1).connect(method.getResult(), new DependencyTypeFilter() { + @Override + public boolean match(DependencyType type) { + return isSubtype(checker.getClassSource(), type.getName(), method.getReference().getReturnType()); + } + }); + } + + MethodDependency errorMethod = checker.linkMethod(new MethodReference(FakeAsyncCallback.class, "error", + Throwable.class, void.class), null); + errorMethod.getVariable(1).connect(method.getThrown()); + asyncMethod.use(); } + + private boolean isSubtype(ClassReaderSource classSource, String className, ValueType returnType) { + if (returnType instanceof ValueType.Primitive) { + return false; + } else if (returnType instanceof ValueType.Array) { + return className.startsWith("["); + } else { + return isSubclass(classSource, className, ((ValueType.Object)returnType).getClassName()); + } + } + + private boolean isSubclass(ClassReaderSource classSource, String className, String baseClass) { + if (className.equals(baseClass)) { + return true; + } + ClassReader cls = classSource.get(className); + if (cls == null) { + return false; + } + if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) { + if (isSubclass(classSource, cls.getParent(), baseClass)) { + return true; + } + } + for (String iface : cls.getInterfaces()) { + if (isSubclass(classSource, iface, baseClass)) { + return true; + } + } + return false; + } } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java index d194142ad..92d7c7408 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/EnumDependencySupport.java @@ -38,7 +38,6 @@ public class EnumDependencySupport implements DependencyListener { return; } allEnums.propagate(agent.getType(className)); - } @Override diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/FakeAsyncCallback.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/FakeAsyncCallback.java new file mode 100644 index 000000000..14d1cbf5e --- /dev/null +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/FakeAsyncCallback.java @@ -0,0 +1,32 @@ +/* + * 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.platform.plugin; + +import org.teavm.platform.async.AsyncCallback; + +/** + * + * @author Alexey Andreev + */ +class FakeAsyncCallback implements AsyncCallback { + @Override + public void complete(Object result) { + } + + @Override + public void error(Throwable e) { + } +} From 33e9fca09905b853bc54096d7de4b5fe1683613a Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 5 Apr 2015 18:43:56 +0300 Subject: [PATCH 5/5] Bugfixes --- .../org/teavm/classlib/java/lang/TClass.java | 2 +- .../org/teavm/classlib/java/lang/TThread.java | 3 ++- ...Callback.java => AsyncCallbackWrapper.java} | 16 ++++++++++++++-- .../platform/plugin/AsyncMethodGenerator.java | 18 ++++++++++++++---- .../platform/plugin/PlatformGenerator.java | 3 +++ 5 files changed, 34 insertions(+), 8 deletions(-) rename teavm-platform/src/main/java/org/teavm/platform/plugin/{FakeAsyncCallback.java => AsyncCallbackWrapper.java} (61%) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java index f9056ae48..46be09ec6 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TClass.java @@ -174,7 +174,7 @@ public class TClass extends TObject { return forName(name); } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "unused" }) public T newInstance() throws TInstantiationException, TIllegalAccessException { Object instance = Platform.newInstance(platformClass); if (instance == null) { diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java index e45e65fa8..4b98842c1 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/TThread.java @@ -101,10 +101,11 @@ public class TThread extends TObject implements TRunnable { } public static void yield() { + TThread currentThread = currentThread(); if (++currentThread.yieldCount < 30) { return; } - currentThread.yieldCount = 0; + currentThread().yieldCount = 0; if (currentThread.timeSliceStart + 100 < System.currentTimeMillis()) { switchContext(currentThread); } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/FakeAsyncCallback.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncCallbackWrapper.java similarity index 61% rename from teavm-platform/src/main/java/org/teavm/platform/plugin/FakeAsyncCallback.java rename to teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncCallbackWrapper.java index 14d1cbf5e..57025fb5e 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/FakeAsyncCallback.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncCallbackWrapper.java @@ -21,12 +21,24 @@ import org.teavm.platform.async.AsyncCallback; * * @author Alexey Andreev */ -class FakeAsyncCallback implements AsyncCallback { +class AsyncCallbackWrapper implements AsyncCallback { + private AsyncCallback realAsyncCallback; + + AsyncCallbackWrapper(AsyncCallback realAsyncCallback) { + this.realAsyncCallback = realAsyncCallback; + } + + public static AsyncCallbackWrapper create(AsyncCallback realAsyncCallback) { + return new AsyncCallbackWrapper<>(realAsyncCallback); + } + @Override - public void complete(Object result) { + public void complete(T result) { + realAsyncCallback.complete(result); } @Override public void error(Throwable e) { + realAsyncCallback.error(e); } } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java index 7addb5337..0cd6acb24 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/AsyncMethodGenerator.java @@ -41,6 +41,7 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException { MethodReference asyncRef = getAsyncReference(methodRef); writer.append("var thread").ws().append('=').ws().append("$rt_nativeThread();").softNewLine(); + writer.append("var javaThread").ws().append('=').ws().append("$rt_getThread();").softNewLine(); writer.append("if").ws().append("(thread.isResuming())").ws().append("{").indent().softNewLine(); writer.append("thread.status").ws().append("=").ws().append("0;").softNewLine(); writer.append("var result").ws().append("=").ws().append("thread.attribute;").softNewLine(); @@ -54,13 +55,17 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { writer.append("callback.").appendMethod(completeMethod.getDescriptor()).ws().append("=").ws() .append("function(val)").ws().append("{").indent().softNewLine(); writer.append("thread.attribute").ws().append('=').ws().append("val;").softNewLine(); + writer.append("$rt_setThread(javaThread);").softNewLine(); writer.append("thread.resume();").softNewLine(); writer.outdent().append("};").softNewLine(); writer.append("callback.").appendMethod(errorMethod.getDescriptor()).ws().append("=").ws() .append("function(e)").ws().append("{").indent().softNewLine(); writer.append("thread.attribute").ws().append('=').ws().append("$rt_exception(e);").softNewLine(); + writer.append("$rt_setThread(javaThread);").softNewLine(); writer.append("thread.resume();").softNewLine(); writer.outdent().append("};").softNewLine(); + writer.append("callback").ws().append("=").ws().appendMethodBody(AsyncCallbackWrapper.class, "create", + AsyncCallback.class, AsyncCallbackWrapper.class).append("(callback);").softNewLine(); writer.append("return thread.suspend(function()").ws().append("{").indent().softNewLine(); writer.append("try").ws().append("{").indent().softNewLine(); writer.appendMethodBody(asyncRef).append('('); @@ -97,11 +102,11 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { for (int i = 0; i <= paramCount; ++i) { method.getVariable(i).connect(asyncMethod.getVariable(i)); } - asyncMethod.getVariable(paramCount + 1).propagate(checker.getType(FakeAsyncCallback.class.getName())); + asyncMethod.getVariable(paramCount + 1).propagate(checker.getType(AsyncCallbackWrapper.class.getName())); + MethodDependency completeMethod = checker.linkMethod( + new MethodReference(AsyncCallbackWrapper.class, "complete", Object.class, void.class), null); if (method.getResult() != null) { - MethodDependency completeMethod = checker.linkMethod( - new MethodReference(FakeAsyncCallback.class, "complete", Object.class, void.class), null); completeMethod.getVariable(1).connect(method.getResult(), new DependencyTypeFilter() { @Override public boolean match(DependencyType type) { @@ -109,10 +114,15 @@ public class AsyncMethodGenerator implements Generator, DependencyPlugin { } }); } + completeMethod.use(); - MethodDependency errorMethod = checker.linkMethod(new MethodReference(FakeAsyncCallback.class, "error", + MethodDependency errorMethod = checker.linkMethod(new MethodReference(AsyncCallbackWrapper.class, "error", Throwable.class, void.class), null); errorMethod.getVariable(1).connect(method.getThrown()); + errorMethod.use(); + + checker.linkMethod(new MethodReference(AsyncCallbackWrapper.class, "create", + AsyncCallback.class, AsyncCallbackWrapper.class), null).use(); asyncMethod.use(); } diff --git a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java index cef535e2b..cdc47f54b 100644 --- a/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java +++ b/teavm-platform/src/main/java/org/teavm/platform/plugin/PlatformGenerator.java @@ -51,6 +51,9 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin launchMethod.use(); break; } + case "getCurrentThread": + method.getResult().propagate(agent.getType("java.lang.Thread")); + break; } }