mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
JS: a better fix for wrapping/unwrapping JS objects implemented in Java
This commit is contained in:
parent
b3e889fa11
commit
067f7453fe
|
@ -35,11 +35,13 @@ class JSAliasRenderer implements RendererListener, VirtualMethodContributor {
|
|||
private static String variableChars = "abcdefghijklmnopqrstuvwxyz";
|
||||
private SourceWriter writer;
|
||||
private ListableClassReaderSource classSource;
|
||||
private JSTypeHelper typeHelper;
|
||||
|
||||
@Override
|
||||
public void begin(RenderingManager context, BuildTarget buildTarget) {
|
||||
writer = context.getWriter();
|
||||
classSource = context.getClassSource();
|
||||
typeHelper = new JSTypeHelper(context.getClassSource());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -48,6 +50,8 @@ class JSAliasRenderer implements RendererListener, VirtualMethodContributor {
|
|||
return;
|
||||
}
|
||||
|
||||
writer.append("let ").appendFunction("$rt_jso_marker").ws().append("=").ws()
|
||||
.appendGlobal("Symbol").append("('jsoClass');").newLine();
|
||||
writer.append("(function()").ws().append("{").softNewLine().indent();
|
||||
writer.append("var c;").softNewLine();
|
||||
for (String className : classSource.getClassNames()) {
|
||||
|
@ -74,20 +78,23 @@ class JSAliasRenderer implements RendererListener, VirtualMethodContributor {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (methods.isEmpty() && properties.isEmpty()) {
|
||||
|
||||
var isJsClassImpl = typeHelper.isJavaScriptImplementation(className);
|
||||
if (methods.isEmpty() && properties.isEmpty() && !isJsClassImpl) {
|
||||
continue;
|
||||
}
|
||||
|
||||
boolean first = true;
|
||||
writer.append("c").ws().append("=").ws().appendClass(className).append(".prototype;")
|
||||
.softNewLine();
|
||||
if (isJsClassImpl) {
|
||||
writer.append("c[").appendFunction("$rt_jso_marker").append("]").ws().append("=").ws().append("true;")
|
||||
.softNewLine();
|
||||
}
|
||||
|
||||
for (var aliasEntry : methods.entrySet()) {
|
||||
if (classReader.getMethod(aliasEntry.getValue()) == null) {
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
writer.append("c").ws().append("=").ws().appendClass(className).append(".prototype;")
|
||||
.softNewLine();
|
||||
first = false;
|
||||
}
|
||||
if (isKeyword(aliasEntry.getKey())) {
|
||||
writer.append("c[\"").append(aliasEntry.getKey()).append("\"]");
|
||||
} else {
|
||||
|
@ -101,11 +108,6 @@ class JSAliasRenderer implements RendererListener, VirtualMethodContributor {
|
|||
if (propInfo.getter == null || classReader.getMethod(propInfo.getter) == null) {
|
||||
continue;
|
||||
}
|
||||
if (first) {
|
||||
writer.append("c").ws().append("=").ws().appendClass(className).append(".prototype;")
|
||||
.softNewLine();
|
||||
first = false;
|
||||
}
|
||||
writer.append("Object.defineProperty(c,")
|
||||
.ws().append("\"").append(aliasEntry.getKey()).append("\",")
|
||||
.ws().append("{").indent().softNewLine();
|
||||
|
@ -128,7 +130,8 @@ class JSAliasRenderer implements RendererListener, VirtualMethodContributor {
|
|||
private boolean hasClassesToExpose() {
|
||||
for (String className : classSource.getClassNames()) {
|
||||
ClassReader cls = classSource.get(className);
|
||||
if (cls.getMethods().stream().anyMatch(method -> getPublicAlias(method) != null)) {
|
||||
if (cls.getMethods().stream().anyMatch(method -> getPublicAlias(method) != null)
|
||||
|| typeHelper.isJavaScriptImplementation(className)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ public class JSOPlugin implements TeaVMPlugin {
|
|||
wrapperGenerator);
|
||||
jsHost.add(new MethodReference(JSWrapper.class, "jsToWrapper", JSObject.class, JSWrapper.class),
|
||||
wrapperGenerator);
|
||||
jsHost.add(new MethodReference(JSWrapper.class, "isJSImplementation", Object.class, boolean.class),
|
||||
wrapperGenerator);
|
||||
|
||||
host.add(new MethodReference(JSWrapper.class, "jsToWrapper", JSObject.class, JSWrapper.class),
|
||||
wrapperGenerator);
|
||||
|
|
|
@ -59,6 +59,9 @@ public final class JSWrapper {
|
|||
return null;
|
||||
}
|
||||
var js = directJavaToJs(o);
|
||||
if (isJSImplementation(o)) {
|
||||
return o;
|
||||
}
|
||||
if (wrappers != null) {
|
||||
var type = JSObjects.typeOf(js);
|
||||
if (type.equals("object") || type.equals("function")) {
|
||||
|
@ -161,18 +164,21 @@ public final class JSWrapper {
|
|||
@NoSideEffects
|
||||
public static native boolean isJava(JSObject obj);
|
||||
|
||||
@NoSideEffects
|
||||
private static native boolean isJSImplementation(Object obj);
|
||||
|
||||
public static JSObject unwrap(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return o instanceof JSWrapper ? ((JSWrapper) o).js : directJavaToJs(o);
|
||||
return isJSImplementation(o) ? directJavaToJs(o) : ((JSWrapper) o).js;
|
||||
}
|
||||
|
||||
public static JSObject maybeUnwrap(Object o) {
|
||||
if (o == null) {
|
||||
return null;
|
||||
}
|
||||
return o instanceof JSWrapper ? unwrap(o) : directJavaToJs(o);
|
||||
return isJava(o) ? unwrap(o) : directJavaToJs(o);
|
||||
}
|
||||
|
||||
public static JSObject javaToJs(Object o) {
|
||||
|
|
|
@ -48,6 +48,17 @@ public class JSWrapperGenerator implements Injector, DependencyPlugin {
|
|||
context.getWriter().append(")");
|
||||
}
|
||||
break;
|
||||
case "isJSImplementation":
|
||||
if (context.getPrecedence().ordinal() >= Precedence.EQUALITY.ordinal()) {
|
||||
context.getWriter().append("(");
|
||||
}
|
||||
context.writeExpr(context.getArgument(0), Precedence.MEMBER_ACCESS);
|
||||
context.getWriter().append("[").appendFunction("$rt_jso_marker").append("]")
|
||||
.ws().append("===").ws().append("true");
|
||||
if (context.getPrecedence().ordinal() >= Precedence.EQUALITY.ordinal()) {
|
||||
context.getWriter().append(")");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user