mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
js: add JSTopLevel annotation that allows to import top-level declarations
This commit is contained in:
parent
9b41e3e814
commit
6a09f181c7
|
@ -109,3 +109,5 @@ let $rt_setThread = t => {
|
||||||
}
|
}
|
||||||
|
|
||||||
let $rt_apply = (instance, method, args) => instance[method].apply(instance, args);
|
let $rt_apply = (instance, method, args) => instance[method].apply(instance, args);
|
||||||
|
|
||||||
|
let $rt_apply_topLevel = (method, args) => method.apply(null, args);
|
|
@ -15,9 +15,9 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.jso.browser;
|
package org.teavm.jso.browser;
|
||||||
|
|
||||||
import org.teavm.jso.JSBody;
|
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
import org.teavm.jso.JSProperty;
|
import org.teavm.jso.JSProperty;
|
||||||
|
import org.teavm.jso.JSTopLevel;
|
||||||
import org.teavm.jso.core.JSArray;
|
import org.teavm.jso.core.JSArray;
|
||||||
import org.teavm.jso.core.JSArrayReader;
|
import org.teavm.jso.core.JSArrayReader;
|
||||||
import org.teavm.jso.dom.html.HTMLDocument;
|
import org.teavm.jso.dom.html.HTMLDocument;
|
||||||
|
@ -81,47 +81,47 @@ public abstract class Window implements JSObject, WindowEventTarget, StorageProv
|
||||||
@JSProperty
|
@JSProperty
|
||||||
public abstract Window getTop();
|
public abstract Window getTop();
|
||||||
|
|
||||||
@JSBody(params = "message", script = "alert(message);")
|
@JSTopLevel
|
||||||
public static native void alert(JSObject message);
|
public static native void alert(JSObject message);
|
||||||
|
|
||||||
@JSBody(params = "message", script = "alert(message);")
|
@JSTopLevel
|
||||||
public static native void alert(String message);
|
public static native void alert(String message);
|
||||||
|
|
||||||
@JSBody(params = "message", script = "return confirm(message);")
|
@JSTopLevel
|
||||||
public static native boolean confirm(JSObject message);
|
public static native boolean confirm(JSObject message);
|
||||||
|
|
||||||
@JSBody(params = "message", script = "return confirm(message);")
|
@JSTopLevel
|
||||||
public static native boolean confirm(String message);
|
public static native boolean confirm(String message);
|
||||||
|
|
||||||
public static String prompt(String message) {
|
public static String prompt(String message) {
|
||||||
return prompt(message, "");
|
return prompt(message, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSBody(params = { "message", "defaultValue" }, script = "return prompt(message, defaultValue);")
|
@JSTopLevel
|
||||||
public static native String prompt(String message, String defaultValue);
|
public static native String prompt(String message, String defaultValue);
|
||||||
|
|
||||||
@JSBody(params = { "handler", "delay" }, script = "return setTimeout(handler, delay);")
|
@JSTopLevel
|
||||||
public static native int setTimeout(TimerHandler handler, int delay);
|
public static native int setTimeout(TimerHandler handler, int delay);
|
||||||
|
|
||||||
@JSBody(params = { "handler", "delay" }, script = "return setTimeout(handler, delay);")
|
@JSTopLevel
|
||||||
public static native int setTimeout(TimerHandler handler, double delay);
|
public static native int setTimeout(TimerHandler handler, double delay);
|
||||||
|
|
||||||
@JSBody(params = "timeoutId", script = "clearTimeout(timeoutId);")
|
@JSTopLevel
|
||||||
public static native void clearTimeout(int timeoutId);
|
public static native void clearTimeout(int timeoutId);
|
||||||
|
|
||||||
@JSBody(params = { "handler", "delay" }, script = "return setInterval(handler, delay);")
|
@JSTopLevel
|
||||||
public static native int setInterval(TimerHandler handler, int delay);
|
public static native int setInterval(TimerHandler handler, int delay);
|
||||||
|
|
||||||
@JSBody(params = { "handler", "delay" }, script = "return setInterval(handler, delay);")
|
@JSTopLevel
|
||||||
public static native int setInterval(TimerHandler handler, double delay);
|
public static native int setInterval(TimerHandler handler, double delay);
|
||||||
|
|
||||||
@JSBody(params = "timeoutId", script = "clearInterval(timeoutId);")
|
@JSTopLevel
|
||||||
public static native void clearInterval(int timeoutId);
|
public static native void clearInterval(int timeoutId);
|
||||||
|
|
||||||
@JSBody(params = "callback", script = "return requestAnimationFrame(callback);")
|
@JSTopLevel
|
||||||
public static native int requestAnimationFrame(AnimationFrameCallback callback);
|
public static native int requestAnimationFrame(AnimationFrameCallback callback);
|
||||||
|
|
||||||
@JSBody(params = "requestId", script = "cancelAnimationFrame(requestId);")
|
@JSTopLevel
|
||||||
public static native void cancelAnimationFrame(int requestId);
|
public static native void cancelAnimationFrame(int requestId);
|
||||||
|
|
||||||
public abstract void blur();
|
public abstract void blur();
|
||||||
|
@ -170,30 +170,32 @@ public abstract class Window implements JSObject, WindowEventTarget, StorageProv
|
||||||
postMessage(message, JSArray.of(transfer));
|
postMessage(message, JSArray.of(transfer));
|
||||||
}
|
}
|
||||||
|
|
||||||
@JSBody(script = "return window;")
|
@JSTopLevel
|
||||||
|
@JSProperty("window")
|
||||||
public static native Window current();
|
public static native Window current();
|
||||||
|
|
||||||
@JSBody(script = "return self;")
|
@JSTopLevel
|
||||||
|
@JSProperty("self")
|
||||||
public static native Window worker();
|
public static native Window worker();
|
||||||
|
|
||||||
@JSBody(params = "uri", script = "return encodeURI(uri);")
|
@JSTopLevel
|
||||||
public static native String encodeURI(String uri);
|
public static native String encodeURI(String uri);
|
||||||
|
|
||||||
@JSBody(params = "uri", script = "return encodeURIComponent(uri);")
|
@JSTopLevel
|
||||||
public static native String encodeURIComponent(String uri);
|
public static native String encodeURIComponent(String uri);
|
||||||
|
|
||||||
@JSBody(params = "uri", script = "return decodeURI(uri);")
|
@JSTopLevel
|
||||||
public static native String decodeURI(String uri);
|
public static native String decodeURI(String uri);
|
||||||
|
|
||||||
@JSBody(params = "uri", script = "return decodeURIComponent(uri);")
|
@JSTopLevel
|
||||||
public static native String decodeURIComponent(String uri);
|
public static native String decodeURIComponent(String uri);
|
||||||
|
|
||||||
@JSProperty
|
@JSProperty
|
||||||
public abstract double getDevicePixelRatio();
|
public abstract double getDevicePixelRatio();
|
||||||
|
|
||||||
@JSBody(params = "s", script = "return atob(s);")
|
@JSTopLevel
|
||||||
public static native String atob(String s);
|
public static native String atob(String s);
|
||||||
|
|
||||||
@JSBody(params = "s", script = "return btoa(s);")
|
@JSTopLevel
|
||||||
public static native String btoa(String s);
|
public static native String btoa(String s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.TYPE)
|
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||||
public @interface JSModule {
|
public @interface JSModule {
|
||||||
String value();
|
String value();
|
||||||
}
|
}
|
||||||
|
|
26
jso/core/src/main/java/org/teavm/jso/JSTopLevel.java
Normal file
26
jso/core/src/main/java/org/teavm/jso/JSTopLevel.java
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 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;
|
||||||
|
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ ElementType.METHOD, ElementType.TYPE })
|
||||||
|
public @interface JSTopLevel {
|
||||||
|
}
|
|
@ -39,6 +39,7 @@ import org.teavm.jso.JSClass;
|
||||||
import org.teavm.jso.JSFunctor;
|
import org.teavm.jso.JSFunctor;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
import org.teavm.jso.JSPrimitiveType;
|
import org.teavm.jso.JSPrimitiveType;
|
||||||
|
import org.teavm.jso.JSTopLevel;
|
||||||
import org.teavm.model.AnnotationContainerReader;
|
import org.teavm.model.AnnotationContainerReader;
|
||||||
import org.teavm.model.AnnotationHolder;
|
import org.teavm.model.AnnotationHolder;
|
||||||
import org.teavm.model.AnnotationReader;
|
import org.teavm.model.AnnotationReader;
|
||||||
|
@ -991,9 +992,19 @@ class JSClassProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Variable getCallTarget(InvokeInstruction invoke) {
|
private Variable getCallTarget(InvokeInstruction invoke) {
|
||||||
return invoke.getInstance() != null
|
if (invoke.getInstance() != null) {
|
||||||
? invoke.getInstance()
|
return invoke.getInstance();
|
||||||
: marshaller.classRef(invoke.getMethod().getClassName(), invoke.getLocation());
|
}
|
||||||
|
var cls = classSource.get(invoke.getMethod().getClassName());
|
||||||
|
var method = cls != null ? cls.getMethod(invoke.getMethod().getDescriptor()) : null;
|
||||||
|
var isTopLevel = (cls != null && cls.getAnnotations().get(JSTopLevel.class.getName()) != null)
|
||||||
|
|| (method != null && method.getAnnotations().get(JSTopLevel.class.getName()) != null);
|
||||||
|
if (isTopLevel) {
|
||||||
|
var methodAnnotations = method != null ? method.getAnnotations() : null;
|
||||||
|
return marshaller.moduleRef(invoke.getMethod().getClassName(), methodAnnotations, invoke.getLocation());
|
||||||
|
} else {
|
||||||
|
return marshaller.classRef(invoke.getMethod().getClassName(), invoke.getLocation());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean processConstructor(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) {
|
private boolean processConstructor(MethodReader method, CallLocation callLocation, InvokeInstruction invoke) {
|
||||||
|
|
|
@ -63,19 +63,31 @@ public class JSNativeInjector implements Injector, DependencyPlugin {
|
||||||
break;
|
break;
|
||||||
case "get":
|
case "get":
|
||||||
case "getPure":
|
case "getPure":
|
||||||
|
if (isNull(context.getArgument(0))) {
|
||||||
|
writer.append(extractPropertyName(context.getArgument(1)));
|
||||||
|
} else {
|
||||||
context.writeExpr(context.getArgument(0), Precedence.MEMBER_ACCESS);
|
context.writeExpr(context.getArgument(0), Precedence.MEMBER_ACCESS);
|
||||||
renderProperty(context.getArgument(1), context);
|
renderProperty(context.getArgument(1), context);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "set":
|
case "set":
|
||||||
case "setPure":
|
case "setPure":
|
||||||
context.writeExpr(context.getArgument(0), Precedence.ASSIGNMENT.next());
|
if (isNull(context.getArgument(0))) {
|
||||||
|
writer.append(extractPropertyName(context.getArgument(1)));
|
||||||
|
} else {
|
||||||
|
context.writeExpr(context.getArgument(0), Precedence.MEMBER_ACCESS.next());
|
||||||
renderProperty(context.getArgument(1), context);
|
renderProperty(context.getArgument(1), context);
|
||||||
|
}
|
||||||
writer.ws().append('=').ws();
|
writer.ws().append('=').ws();
|
||||||
context.writeExpr(context.getArgument(2), Precedence.ASSIGNMENT.next());
|
context.writeExpr(context.getArgument(2), Precedence.ASSIGNMENT.next());
|
||||||
break;
|
break;
|
||||||
case "invoke":
|
case "invoke":
|
||||||
|
if (isNull(context.getArgument(0))) {
|
||||||
|
writer.append(extractPropertyName(context.getArgument(1)));
|
||||||
|
} else {
|
||||||
context.writeExpr(context.getArgument(0), Precedence.GROUPING);
|
context.writeExpr(context.getArgument(0), Precedence.GROUPING);
|
||||||
renderProperty(context.getArgument(1), context);
|
renderProperty(context.getArgument(1), context);
|
||||||
|
}
|
||||||
writer.append('(');
|
writer.append('(');
|
||||||
for (int i = 2; i < context.argumentCount(); ++i) {
|
for (int i = 2; i < context.argumentCount(); ++i) {
|
||||||
if (i > 2) {
|
if (i > 2) {
|
||||||
|
@ -234,15 +246,30 @@ public class JSNativeInjector implements Injector, DependencyPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isNull(Expr expr) {
|
||||||
|
if (expr instanceof ConstantExpr) {
|
||||||
|
var constantExpr = (ConstantExpr) expr;
|
||||||
|
if (constantExpr.getValue() == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void applyFunction(InjectorContext context) {
|
private void applyFunction(InjectorContext context) {
|
||||||
if (tryApplyFunctionOptimized(context)) {
|
if (tryApplyFunctionOptimized(context)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var writer = context.getWriter();
|
var writer = context.getWriter();
|
||||||
|
if (isNull(context.getArgument(0))) {
|
||||||
|
writer.appendFunction("$rt_apply_topLevel").append("(");
|
||||||
|
writer.append(extractPropertyName(context.getArgument(1)));
|
||||||
|
} else {
|
||||||
writer.appendFunction("$rt_apply").append("(");
|
writer.appendFunction("$rt_apply").append("(");
|
||||||
context.writeExpr(context.getArgument(0), Precedence.ASSIGNMENT);
|
context.writeExpr(context.getArgument(0), Precedence.ASSIGNMENT);
|
||||||
writer.append(",").ws();
|
writer.append(",").ws();
|
||||||
context.writeExpr(context.getArgument(1), Precedence.ASSIGNMENT);
|
context.writeExpr(context.getArgument(1), Precedence.ASSIGNMENT);
|
||||||
|
}
|
||||||
writer.append(",").ws();
|
writer.append(",").ws();
|
||||||
context.writeExpr(context.getArgument(2), Precedence.ASSIGNMENT);
|
context.writeExpr(context.getArgument(2), Precedence.ASSIGNMENT);
|
||||||
writer.append(")");
|
writer.append(")");
|
||||||
|
@ -323,8 +350,12 @@ public class JSNativeInjector implements Injector, DependencyPlugin {
|
||||||
|
|
||||||
private void applyFunctionOptimized(InjectorContext context, List<Expr> paramList) {
|
private void applyFunctionOptimized(InjectorContext context, List<Expr> paramList) {
|
||||||
var writer = context.getWriter();
|
var writer = context.getWriter();
|
||||||
|
if (isNull(context.getArgument(0))) {
|
||||||
|
writer.append(extractPropertyName(context.getArgument(1)));
|
||||||
|
} else {
|
||||||
context.writeExpr(context.getArgument(0), Precedence.GROUPING);
|
context.writeExpr(context.getArgument(0), Precedence.GROUPING);
|
||||||
renderProperty(context.getArgument(1), context);
|
renderProperty(context.getArgument(1), context);
|
||||||
|
}
|
||||||
writer.append('(');
|
writer.append('(');
|
||||||
for (int i = 0; i < paramList.size(); ++i) {
|
for (int i = 0; i < paramList.size(); ++i) {
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import org.teavm.jso.JSClass;
|
||||||
import org.teavm.jso.JSFunctor;
|
import org.teavm.jso.JSFunctor;
|
||||||
import org.teavm.jso.JSModule;
|
import org.teavm.jso.JSModule;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.model.AnnotationContainerReader;
|
||||||
import org.teavm.model.CallLocation;
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ClassReaderSource;
|
import org.teavm.model.ClassReaderSource;
|
||||||
|
@ -36,6 +37,7 @@ import org.teavm.model.Variable;
|
||||||
import org.teavm.model.instructions.ClassConstantInstruction;
|
import org.teavm.model.instructions.ClassConstantInstruction;
|
||||||
import org.teavm.model.instructions.InvocationType;
|
import org.teavm.model.instructions.InvocationType;
|
||||||
import org.teavm.model.instructions.InvokeInstruction;
|
import org.teavm.model.instructions.InvokeInstruction;
|
||||||
|
import org.teavm.model.instructions.NullConstantInstruction;
|
||||||
import org.teavm.model.instructions.StringConstantInstruction;
|
import org.teavm.model.instructions.StringConstantInstruction;
|
||||||
|
|
||||||
class JSValueMarshaller {
|
class JSValueMarshaller {
|
||||||
|
@ -563,6 +565,10 @@ class JSValueMarshaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable classRef(String className, TextLocation location) {
|
Variable classRef(String className, TextLocation location) {
|
||||||
|
return classRef(className, null, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable classRef(String className, AnnotationContainerReader annotations, TextLocation location) {
|
||||||
String name = null;
|
String name = null;
|
||||||
String module = null;
|
String module = null;
|
||||||
var cls = classSource.get(className);
|
var cls = classSource.get(className);
|
||||||
|
@ -578,17 +584,37 @@ class JSValueMarshaller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var jsModule = cls.getAnnotations().get(JSModule.class.getName());
|
module = moduleName(cls.getAnnotations());
|
||||||
if (jsModule != null) {
|
|
||||||
module = jsModule.getValue("value").getString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
name = cls.getName().substring(cls.getName().lastIndexOf('.') + 1);
|
name = cls.getName().substring(cls.getName().lastIndexOf('.') + 1);
|
||||||
}
|
}
|
||||||
|
if (module == null && annotations != null) {
|
||||||
|
module = moduleName(annotations);
|
||||||
|
}
|
||||||
return module != null ? moduleRef(module, name, location) : globalRef(name, location);
|
return module != null ? moduleRef(module, name, location) : globalRef(name, location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variable moduleRef(String className, AnnotationContainerReader annotations, TextLocation location) {
|
||||||
|
String module = null;
|
||||||
|
var cls = classSource.get(className);
|
||||||
|
if (cls != null) {
|
||||||
|
module = moduleName(cls.getAnnotations());
|
||||||
|
}
|
||||||
|
if (module == null && annotations != null) {
|
||||||
|
module = moduleName(annotations);
|
||||||
|
}
|
||||||
|
return module != null ? moduleRef(module, location) : nullInstance(location);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String moduleName(AnnotationContainerReader annotations) {
|
||||||
|
var jsModule = annotations.get(JSModule.class.getName());
|
||||||
|
if (jsModule != null) {
|
||||||
|
return jsModule.getValue("value").getString();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
Variable globalRef(String name, TextLocation location) {
|
Variable globalRef(String name, TextLocation location) {
|
||||||
var invoke = new InvokeInstruction();
|
var invoke = new InvokeInstruction();
|
||||||
invoke.setType(InvocationType.SPECIAL);
|
invoke.setType(InvocationType.SPECIAL);
|
||||||
|
@ -602,6 +628,10 @@ class JSValueMarshaller {
|
||||||
}
|
}
|
||||||
|
|
||||||
Variable moduleRef(String module, String name, TextLocation location) {
|
Variable moduleRef(String module, String name, TextLocation location) {
|
||||||
|
return dot(moduleRef(module, location), name, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable moduleRef(String module, TextLocation location) {
|
||||||
var moduleNameInsn = new StringConstantInstruction();
|
var moduleNameInsn = new StringConstantInstruction();
|
||||||
moduleNameInsn.setReceiver(program.createVariable());
|
moduleNameInsn.setReceiver(program.createVariable());
|
||||||
moduleNameInsn.setConstant(module);
|
moduleNameInsn.setConstant(module);
|
||||||
|
@ -616,14 +646,26 @@ class JSValueMarshaller {
|
||||||
invoke.setLocation(location);
|
invoke.setLocation(location);
|
||||||
replacement.add(invoke);
|
replacement.add(invoke);
|
||||||
|
|
||||||
|
return invoke.getReceiver();
|
||||||
|
}
|
||||||
|
|
||||||
|
Variable dot(Variable instance, String name, TextLocation location) {
|
||||||
var get = new InvokeInstruction();
|
var get = new InvokeInstruction();
|
||||||
get.setType(InvocationType.SPECIAL);
|
get.setType(InvocationType.SPECIAL);
|
||||||
get.setMethod(JSMethods.GET_PURE);
|
get.setMethod(JSMethods.GET_PURE);
|
||||||
get.setReceiver(program.createVariable());
|
get.setReceiver(program.createVariable());
|
||||||
get.setArguments(invoke.getReceiver(), addJsString(name, location));
|
get.setArguments(instance, addJsString(name, location));
|
||||||
get.setLocation(location);
|
get.setLocation(location);
|
||||||
replacement.add(get);
|
replacement.add(get);
|
||||||
|
|
||||||
return get.getReceiver();
|
return get.getReceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Variable nullInstance(TextLocation location) {
|
||||||
|
var nullConstant = new NullConstantInstruction();
|
||||||
|
nullConstant.setReceiver(program.createVariable());
|
||||||
|
nullConstant.setLocation(location);
|
||||||
|
replacement.add(nullConstant);
|
||||||
|
return nullConstant.getReceiver();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ import org.junit.runner.RunWith;
|
||||||
import org.teavm.jso.JSClass;
|
import org.teavm.jso.JSClass;
|
||||||
import org.teavm.jso.JSMethod;
|
import org.teavm.jso.JSMethod;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSTopLevel;
|
||||||
import org.teavm.junit.AttachJavaScript;
|
import org.teavm.junit.AttachJavaScript;
|
||||||
import org.teavm.junit.EachTestCompiledSeparately;
|
import org.teavm.junit.EachTestCompiledSeparately;
|
||||||
import org.teavm.junit.OnlyPlatform;
|
import org.teavm.junit.OnlyPlatform;
|
||||||
|
@ -77,6 +78,28 @@ public class CallTest {
|
||||||
assertEquals("a:23,b:q,va:6:7:8", TestClass.restVararg(23, "q", intArray));
|
assertEquals("a:23,b:q,va:6:7:8", TestClass.restVararg(23, "q", intArray));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@AttachJavaScript("org/teavm/jso/test/vararg.js")
|
||||||
|
public void topLevelVararg() {
|
||||||
|
assertEquals("tva:q:w", TestClass.topLevelVararg("q", "w"));
|
||||||
|
assertEquals("tva:23:42", TestClass.topLevelVarargInt(23, 42));
|
||||||
|
|
||||||
|
var array = new String[3];
|
||||||
|
for (var i = 0; i < array.length; ++i) {
|
||||||
|
array[i] = String.valueOf((char) ('A' + i));
|
||||||
|
}
|
||||||
|
assertEquals("tva:A:B:C", TestClass.topLevelVararg(array));
|
||||||
|
|
||||||
|
var intArray = new int[3];
|
||||||
|
for (var i = 0; i < array.length; ++i) {
|
||||||
|
intArray[i] = 6 + i;
|
||||||
|
}
|
||||||
|
assertEquals("tva:6:7:8", TestClass.topLevelVarargInt(intArray));
|
||||||
|
|
||||||
|
assertEquals("tva", TestClass.topLevelVararg());
|
||||||
|
assertEquals("tva", TestClass.topLevelVarargInt());
|
||||||
|
}
|
||||||
|
|
||||||
@JSClass
|
@JSClass
|
||||||
public static class TestClass implements JSObject {
|
public static class TestClass implements JSObject {
|
||||||
public static native String allVararg(String... args);
|
public static native String allVararg(String... args);
|
||||||
|
@ -87,5 +110,12 @@ public class CallTest {
|
||||||
public static native String restVararg(String a, int b, String... args);
|
public static native String restVararg(String a, int b, String... args);
|
||||||
|
|
||||||
public static native String restVararg(int a, String b, int... args);
|
public static native String restVararg(int a, String b, int... args);
|
||||||
|
|
||||||
|
@JSTopLevel
|
||||||
|
public static native String topLevelVararg(String... args);
|
||||||
|
|
||||||
|
@JSTopLevel
|
||||||
|
@JSMethod("topLevelVararg")
|
||||||
|
public static native String topLevelVarargInt(int... args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.jso.test;
|
||||||
import org.teavm.jso.JSClass;
|
import org.teavm.jso.JSClass;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
import org.teavm.jso.JSProperty;
|
import org.teavm.jso.JSProperty;
|
||||||
|
import org.teavm.jso.JSTopLevel;
|
||||||
|
|
||||||
@JSClass
|
@JSClass
|
||||||
public class ClassWithConstructor implements JSObject {
|
public class ClassWithConstructor implements JSObject {
|
||||||
|
@ -33,4 +34,15 @@ public class ClassWithConstructor implements JSObject {
|
||||||
public native String bar();
|
public native String bar();
|
||||||
|
|
||||||
public static native String staticMethod();
|
public static native String staticMethod();
|
||||||
|
|
||||||
|
@JSTopLevel
|
||||||
|
public static native String topLevelFunction();
|
||||||
|
|
||||||
|
@JSTopLevel
|
||||||
|
@JSProperty
|
||||||
|
public static native String getTopLevelProperty();
|
||||||
|
|
||||||
|
@JSTopLevel
|
||||||
|
@JSProperty
|
||||||
|
public static native void setTopLevelProperty(String value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import org.teavm.jso.JSClass;
|
||||||
import org.teavm.jso.JSModule;
|
import org.teavm.jso.JSModule;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
import org.teavm.jso.JSProperty;
|
import org.teavm.jso.JSProperty;
|
||||||
|
import org.teavm.jso.JSTopLevel;
|
||||||
|
|
||||||
@JSClass(name = "ClassWithConstructor")
|
@JSClass(name = "ClassWithConstructor")
|
||||||
@JSModule("./testModule.js")
|
@JSModule("./testModule.js")
|
||||||
|
@ -33,4 +34,11 @@ public class ClassWithConstructorInModule implements JSObject {
|
||||||
public native int getFoo();
|
public native int getFoo();
|
||||||
|
|
||||||
public native String bar();
|
public native String bar();
|
||||||
|
|
||||||
|
@JSTopLevel
|
||||||
|
public static native String topLevelFunction();
|
||||||
|
|
||||||
|
@JSTopLevel
|
||||||
|
@JSProperty
|
||||||
|
public static native String getTopLevelProperty();
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,22 @@ public class ImportClassTest {
|
||||||
assertEquals("static method called", ClassWithConstructor.staticMethod());
|
assertEquals("static method called", ClassWithConstructor.staticMethod());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@AttachJavaScript("org/teavm/jso/test/classWithConstructor.js")
|
||||||
|
public void topLevel() {
|
||||||
|
assertEquals("top level", ClassWithConstructor.topLevelFunction());
|
||||||
|
assertEquals("top level prop", ClassWithConstructor.getTopLevelProperty());
|
||||||
|
|
||||||
|
ClassWithConstructor.setTopLevelProperty("update");
|
||||||
|
assertEquals("update", ClassWithConstructor.getTopLevelProperty());
|
||||||
|
|
||||||
|
assertEquals("top level", TopLevelDeclarations.topLevelFunction());
|
||||||
|
assertEquals("update", TopLevelDeclarations.getTopLevelProperty());
|
||||||
|
|
||||||
|
TopLevelDeclarations.setTopLevelProperty("update2");
|
||||||
|
assertEquals("update2", ClassWithConstructor.getTopLevelProperty());
|
||||||
|
}
|
||||||
|
|
||||||
@JSBody(script = "return {};")
|
@JSBody(script = "return {};")
|
||||||
private static native O create();
|
private static native O create();
|
||||||
|
|
||||||
|
|
|
@ -68,6 +68,14 @@ public class ImportModuleTest {
|
||||||
assertEquals(23, o.getFoo());
|
assertEquals(23, o.getFoo());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@JsModuleTest
|
||||||
|
@ServeJS(from = "org/teavm/jso/test/classWithConstructorInModule.js", as = "testModule.js")
|
||||||
|
public void topLevel() {
|
||||||
|
assertEquals("top level", ClassWithConstructorInModule.topLevelFunction());
|
||||||
|
assertEquals("top level prop", ClassWithConstructorInModule.getTopLevelProperty());
|
||||||
|
}
|
||||||
|
|
||||||
@JSBody(
|
@JSBody(
|
||||||
script = "return testModule.foo();",
|
script = "return testModule.foo();",
|
||||||
imports = @JSBodyImport(alias = "testModule", fromModule = "./testModule.js")
|
imports = @JSBodyImport(alias = "testModule", fromModule = "./testModule.js")
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 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 org.teavm.jso.JSClass;
|
||||||
|
import org.teavm.jso.JSObject;
|
||||||
|
import org.teavm.jso.JSProperty;
|
||||||
|
import org.teavm.jso.JSTopLevel;
|
||||||
|
|
||||||
|
@JSClass
|
||||||
|
@JSTopLevel
|
||||||
|
public class TopLevelDeclarations implements JSObject {
|
||||||
|
private TopLevelDeclarations() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static native String topLevelFunction();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
public static native String getTopLevelProperty();
|
||||||
|
|
||||||
|
@JSProperty
|
||||||
|
public static native void setTopLevelProperty(String value);
|
||||||
|
}
|
|
@ -31,3 +31,9 @@ class ClassWithConstructor {
|
||||||
return "static method called";
|
return "static method called";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function topLevelFunction() {
|
||||||
|
return "top level";
|
||||||
|
}
|
||||||
|
|
||||||
|
let topLevelProperty = "top level prop";
|
|
@ -27,3 +27,9 @@ export class ClassWithConstructor {
|
||||||
return "bar called";
|
return "bar called";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function topLevelFunction() {
|
||||||
|
return "top level";
|
||||||
|
}
|
||||||
|
|
||||||
|
export let topLevelProperty = "top level prop";
|
|
@ -31,3 +31,11 @@ class TestClass {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function topLevelVararg(...args) {
|
||||||
|
let result = "tva";
|
||||||
|
for (const arg of args) {
|
||||||
|
result += ":" + arg;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user