mirror of
https://github.com/konsoletyper/teavm.git
synced 2024-11-27 01:30:35 +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_topLevel = (method, args) => method.apply(null, args);
|
@ -15,9 +15,9 @@
|
||||
*/
|
||||
package org.teavm.jso.browser;
|
||||
|
||||
import org.teavm.jso.JSBody;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
import org.teavm.jso.JSTopLevel;
|
||||
import org.teavm.jso.core.JSArray;
|
||||
import org.teavm.jso.core.JSArrayReader;
|
||||
import org.teavm.jso.dom.html.HTMLDocument;
|
||||
@ -81,47 +81,47 @@ public abstract class Window implements JSObject, WindowEventTarget, StorageProv
|
||||
@JSProperty
|
||||
public abstract Window getTop();
|
||||
|
||||
@JSBody(params = "message", script = "alert(message);")
|
||||
@JSTopLevel
|
||||
public static native void alert(JSObject message);
|
||||
|
||||
@JSBody(params = "message", script = "alert(message);")
|
||||
@JSTopLevel
|
||||
public static native void alert(String message);
|
||||
|
||||
@JSBody(params = "message", script = "return confirm(message);")
|
||||
@JSTopLevel
|
||||
public static native boolean confirm(JSObject message);
|
||||
|
||||
@JSBody(params = "message", script = "return confirm(message);")
|
||||
@JSTopLevel
|
||||
public static native boolean confirm(String message);
|
||||
|
||||
public static String prompt(String message) {
|
||||
return prompt(message, "");
|
||||
}
|
||||
|
||||
@JSBody(params = { "message", "defaultValue" }, script = "return prompt(message, defaultValue);")
|
||||
@JSTopLevel
|
||||
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);
|
||||
|
||||
@JSBody(params = { "handler", "delay" }, script = "return setTimeout(handler, delay);")
|
||||
@JSTopLevel
|
||||
public static native int setTimeout(TimerHandler handler, double delay);
|
||||
|
||||
@JSBody(params = "timeoutId", script = "clearTimeout(timeoutId);")
|
||||
@JSTopLevel
|
||||
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);
|
||||
|
||||
@JSBody(params = { "handler", "delay" }, script = "return setInterval(handler, delay);")
|
||||
@JSTopLevel
|
||||
public static native int setInterval(TimerHandler handler, double delay);
|
||||
|
||||
@JSBody(params = "timeoutId", script = "clearInterval(timeoutId);")
|
||||
@JSTopLevel
|
||||
public static native void clearInterval(int timeoutId);
|
||||
|
||||
@JSBody(params = "callback", script = "return requestAnimationFrame(callback);")
|
||||
@JSTopLevel
|
||||
public static native int requestAnimationFrame(AnimationFrameCallback callback);
|
||||
|
||||
@JSBody(params = "requestId", script = "cancelAnimationFrame(requestId);")
|
||||
@JSTopLevel
|
||||
public static native void cancelAnimationFrame(int requestId);
|
||||
|
||||
public abstract void blur();
|
||||
@ -170,30 +170,32 @@ public abstract class Window implements JSObject, WindowEventTarget, StorageProv
|
||||
postMessage(message, JSArray.of(transfer));
|
||||
}
|
||||
|
||||
@JSBody(script = "return window;")
|
||||
@JSTopLevel
|
||||
@JSProperty("window")
|
||||
public static native Window current();
|
||||
|
||||
@JSBody(script = "return self;")
|
||||
@JSTopLevel
|
||||
@JSProperty("self")
|
||||
public static native Window worker();
|
||||
|
||||
@JSBody(params = "uri", script = "return encodeURI(uri);")
|
||||
@JSTopLevel
|
||||
public static native String encodeURI(String uri);
|
||||
|
||||
@JSBody(params = "uri", script = "return encodeURIComponent(uri);")
|
||||
@JSTopLevel
|
||||
public static native String encodeURIComponent(String uri);
|
||||
|
||||
@JSBody(params = "uri", script = "return decodeURI(uri);")
|
||||
@JSTopLevel
|
||||
public static native String decodeURI(String uri);
|
||||
|
||||
@JSBody(params = "uri", script = "return decodeURIComponent(uri);")
|
||||
@JSTopLevel
|
||||
public static native String decodeURIComponent(String uri);
|
||||
|
||||
@JSProperty
|
||||
public abstract double getDevicePixelRatio();
|
||||
|
||||
@JSBody(params = "s", script = "return atob(s);")
|
||||
@JSTopLevel
|
||||
public static native String atob(String s);
|
||||
|
||||
@JSBody(params = "s", script = "return btoa(s);")
|
||||
@JSTopLevel
|
||||
public static native String btoa(String s);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Target({ ElementType.TYPE, ElementType.METHOD })
|
||||
public @interface JSModule {
|
||||
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.JSObject;
|
||||
import org.teavm.jso.JSPrimitiveType;
|
||||
import org.teavm.jso.JSTopLevel;
|
||||
import org.teavm.model.AnnotationContainerReader;
|
||||
import org.teavm.model.AnnotationHolder;
|
||||
import org.teavm.model.AnnotationReader;
|
||||
@ -991,9 +992,19 @@ class JSClassProcessor {
|
||||
}
|
||||
|
||||
private Variable getCallTarget(InvokeInstruction invoke) {
|
||||
return invoke.getInstance() != null
|
||||
? invoke.getInstance()
|
||||
: marshaller.classRef(invoke.getMethod().getClassName(), invoke.getLocation());
|
||||
if (invoke.getInstance() != null) {
|
||||
return invoke.getInstance();
|
||||
}
|
||||
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) {
|
||||
|
@ -63,19 +63,31 @@ public class JSNativeInjector implements Injector, DependencyPlugin {
|
||||
break;
|
||||
case "get":
|
||||
case "getPure":
|
||||
if (isNull(context.getArgument(0))) {
|
||||
writer.append(extractPropertyName(context.getArgument(1)));
|
||||
} else {
|
||||
context.writeExpr(context.getArgument(0), Precedence.MEMBER_ACCESS);
|
||||
renderProperty(context.getArgument(1), context);
|
||||
}
|
||||
break;
|
||||
case "set":
|
||||
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);
|
||||
}
|
||||
writer.ws().append('=').ws();
|
||||
context.writeExpr(context.getArgument(2), Precedence.ASSIGNMENT.next());
|
||||
break;
|
||||
case "invoke":
|
||||
if (isNull(context.getArgument(0))) {
|
||||
writer.append(extractPropertyName(context.getArgument(1)));
|
||||
} else {
|
||||
context.writeExpr(context.getArgument(0), Precedence.GROUPING);
|
||||
renderProperty(context.getArgument(1), context);
|
||||
}
|
||||
writer.append('(');
|
||||
for (int i = 2; i < context.argumentCount(); ++i) {
|
||||
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) {
|
||||
if (tryApplyFunctionOptimized(context)) {
|
||||
return;
|
||||
}
|
||||
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("(");
|
||||
context.writeExpr(context.getArgument(0), Precedence.ASSIGNMENT);
|
||||
writer.append(",").ws();
|
||||
context.writeExpr(context.getArgument(1), Precedence.ASSIGNMENT);
|
||||
}
|
||||
writer.append(",").ws();
|
||||
context.writeExpr(context.getArgument(2), Precedence.ASSIGNMENT);
|
||||
writer.append(")");
|
||||
@ -323,8 +350,12 @@ public class JSNativeInjector implements Injector, DependencyPlugin {
|
||||
|
||||
private void applyFunctionOptimized(InjectorContext context, List<Expr> paramList) {
|
||||
var writer = context.getWriter();
|
||||
if (isNull(context.getArgument(0))) {
|
||||
writer.append(extractPropertyName(context.getArgument(1)));
|
||||
} else {
|
||||
context.writeExpr(context.getArgument(0), Precedence.GROUPING);
|
||||
renderProperty(context.getArgument(1), context);
|
||||
}
|
||||
writer.append('(');
|
||||
for (int i = 0; i < paramList.size(); ++i) {
|
||||
if (i > 0) {
|
||||
|
@ -22,6 +22,7 @@ import org.teavm.jso.JSClass;
|
||||
import org.teavm.jso.JSFunctor;
|
||||
import org.teavm.jso.JSModule;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.model.AnnotationContainerReader;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassReader;
|
||||
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.InvocationType;
|
||||
import org.teavm.model.instructions.InvokeInstruction;
|
||||
import org.teavm.model.instructions.NullConstantInstruction;
|
||||
import org.teavm.model.instructions.StringConstantInstruction;
|
||||
|
||||
class JSValueMarshaller {
|
||||
@ -563,6 +565,10 @@ class JSValueMarshaller {
|
||||
}
|
||||
|
||||
Variable classRef(String className, TextLocation location) {
|
||||
return classRef(className, null, location);
|
||||
}
|
||||
|
||||
Variable classRef(String className, AnnotationContainerReader annotations, TextLocation location) {
|
||||
String name = null;
|
||||
String module = null;
|
||||
var cls = classSource.get(className);
|
||||
@ -578,17 +584,37 @@ class JSValueMarshaller {
|
||||
}
|
||||
}
|
||||
}
|
||||
var jsModule = cls.getAnnotations().get(JSModule.class.getName());
|
||||
if (jsModule != null) {
|
||||
module = jsModule.getValue("value").getString();
|
||||
}
|
||||
module = moduleName(cls.getAnnotations());
|
||||
}
|
||||
if (name == null) {
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
var invoke = new InvokeInstruction();
|
||||
invoke.setType(InvocationType.SPECIAL);
|
||||
@ -602,6 +628,10 @@ class JSValueMarshaller {
|
||||
}
|
||||
|
||||
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();
|
||||
moduleNameInsn.setReceiver(program.createVariable());
|
||||
moduleNameInsn.setConstant(module);
|
||||
@ -616,14 +646,26 @@ class JSValueMarshaller {
|
||||
invoke.setLocation(location);
|
||||
replacement.add(invoke);
|
||||
|
||||
return invoke.getReceiver();
|
||||
}
|
||||
|
||||
Variable dot(Variable instance, String name, TextLocation location) {
|
||||
var get = new InvokeInstruction();
|
||||
get.setType(InvocationType.SPECIAL);
|
||||
get.setMethod(JSMethods.GET_PURE);
|
||||
get.setReceiver(program.createVariable());
|
||||
get.setArguments(invoke.getReceiver(), addJsString(name, location));
|
||||
get.setArguments(instance, addJsString(name, location));
|
||||
get.setLocation(location);
|
||||
replacement.add(get);
|
||||
|
||||
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.JSMethod;
|
||||
import org.teavm.jso.JSObject;
|
||||
import org.teavm.jso.JSTopLevel;
|
||||
import org.teavm.junit.AttachJavaScript;
|
||||
import org.teavm.junit.EachTestCompiledSeparately;
|
||||
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));
|
||||
}
|
||||
|
||||
@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
|
||||
public static class TestClass implements JSObject {
|
||||
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(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.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
import org.teavm.jso.JSTopLevel;
|
||||
|
||||
@JSClass
|
||||
public class ClassWithConstructor implements JSObject {
|
||||
@ -33,4 +34,15 @@ public class ClassWithConstructor implements JSObject {
|
||||
public native String bar();
|
||||
|
||||
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.JSObject;
|
||||
import org.teavm.jso.JSProperty;
|
||||
import org.teavm.jso.JSTopLevel;
|
||||
|
||||
@JSClass(name = "ClassWithConstructor")
|
||||
@JSModule("./testModule.js")
|
||||
@ -33,4 +34,11 @@ public class ClassWithConstructorInModule implements JSObject {
|
||||
public native int getFoo();
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
@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 {};")
|
||||
private static native O create();
|
||||
|
||||
|
@ -68,6 +68,14 @@ public class ImportModuleTest {
|
||||
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(
|
||||
script = "return testModule.foo();",
|
||||
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";
|
||||
}
|
||||
}
|
||||
|
||||
function topLevelFunction() {
|
||||
return "top level";
|
||||
}
|
||||
|
||||
let topLevelProperty = "top level prop";
|
@ -27,3 +27,9 @@ export class ClassWithConstructor {
|
||||
return "bar called";
|
||||
}
|
||||
}
|
||||
|
||||
export function topLevelFunction() {
|
||||
return "top level";
|
||||
}
|
||||
|
||||
export let topLevelProperty = "top level prop";
|
@ -31,3 +31,11 @@ class TestClass {
|
||||
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