mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -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 static String variableChars = "abcdefghijklmnopqrstuvwxyz";
|
||||||
private SourceWriter writer;
|
private SourceWriter writer;
|
||||||
private ListableClassReaderSource classSource;
|
private ListableClassReaderSource classSource;
|
||||||
|
private JSTypeHelper typeHelper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void begin(RenderingManager context, BuildTarget buildTarget) {
|
public void begin(RenderingManager context, BuildTarget buildTarget) {
|
||||||
writer = context.getWriter();
|
writer = context.getWriter();
|
||||||
classSource = context.getClassSource();
|
classSource = context.getClassSource();
|
||||||
|
typeHelper = new JSTypeHelper(context.getClassSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -48,6 +50,8 @@ class JSAliasRenderer implements RendererListener, VirtualMethodContributor {
|
||||||
return;
|
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("(function()").ws().append("{").softNewLine().indent();
|
||||||
writer.append("var c;").softNewLine();
|
writer.append("var c;").softNewLine();
|
||||||
for (String className : classSource.getClassNames()) {
|
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;
|
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()) {
|
for (var aliasEntry : methods.entrySet()) {
|
||||||
if (classReader.getMethod(aliasEntry.getValue()) == null) {
|
if (classReader.getMethod(aliasEntry.getValue()) == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (first) {
|
|
||||||
writer.append("c").ws().append("=").ws().appendClass(className).append(".prototype;")
|
|
||||||
.softNewLine();
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
if (isKeyword(aliasEntry.getKey())) {
|
if (isKeyword(aliasEntry.getKey())) {
|
||||||
writer.append("c[\"").append(aliasEntry.getKey()).append("\"]");
|
writer.append("c[\"").append(aliasEntry.getKey()).append("\"]");
|
||||||
} else {
|
} else {
|
||||||
|
@ -101,11 +108,6 @@ class JSAliasRenderer implements RendererListener, VirtualMethodContributor {
|
||||||
if (propInfo.getter == null || classReader.getMethod(propInfo.getter) == null) {
|
if (propInfo.getter == null || classReader.getMethod(propInfo.getter) == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (first) {
|
|
||||||
writer.append("c").ws().append("=").ws().appendClass(className).append(".prototype;")
|
|
||||||
.softNewLine();
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
writer.append("Object.defineProperty(c,")
|
writer.append("Object.defineProperty(c,")
|
||||||
.ws().append("\"").append(aliasEntry.getKey()).append("\",")
|
.ws().append("\"").append(aliasEntry.getKey()).append("\",")
|
||||||
.ws().append("{").indent().softNewLine();
|
.ws().append("{").indent().softNewLine();
|
||||||
|
@ -128,7 +130,8 @@ class JSAliasRenderer implements RendererListener, VirtualMethodContributor {
|
||||||
private boolean hasClassesToExpose() {
|
private boolean hasClassesToExpose() {
|
||||||
for (String className : classSource.getClassNames()) {
|
for (String className : classSource.getClassNames()) {
|
||||||
ClassReader cls = classSource.get(className);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,8 @@ public class JSOPlugin implements TeaVMPlugin {
|
||||||
wrapperGenerator);
|
wrapperGenerator);
|
||||||
jsHost.add(new MethodReference(JSWrapper.class, "jsToWrapper", JSObject.class, JSWrapper.class),
|
jsHost.add(new MethodReference(JSWrapper.class, "jsToWrapper", JSObject.class, JSWrapper.class),
|
||||||
wrapperGenerator);
|
wrapperGenerator);
|
||||||
|
jsHost.add(new MethodReference(JSWrapper.class, "isJSImplementation", Object.class, boolean.class),
|
||||||
|
wrapperGenerator);
|
||||||
|
|
||||||
host.add(new MethodReference(JSWrapper.class, "jsToWrapper", JSObject.class, JSWrapper.class),
|
host.add(new MethodReference(JSWrapper.class, "jsToWrapper", JSObject.class, JSWrapper.class),
|
||||||
wrapperGenerator);
|
wrapperGenerator);
|
||||||
|
|
|
@ -59,6 +59,9 @@ public final class JSWrapper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var js = directJavaToJs(o);
|
var js = directJavaToJs(o);
|
||||||
|
if (isJSImplementation(o)) {
|
||||||
|
return o;
|
||||||
|
}
|
||||||
if (wrappers != null) {
|
if (wrappers != null) {
|
||||||
var type = JSObjects.typeOf(js);
|
var type = JSObjects.typeOf(js);
|
||||||
if (type.equals("object") || type.equals("function")) {
|
if (type.equals("object") || type.equals("function")) {
|
||||||
|
@ -161,18 +164,21 @@ public final class JSWrapper {
|
||||||
@NoSideEffects
|
@NoSideEffects
|
||||||
public static native boolean isJava(JSObject obj);
|
public static native boolean isJava(JSObject obj);
|
||||||
|
|
||||||
|
@NoSideEffects
|
||||||
|
private static native boolean isJSImplementation(Object obj);
|
||||||
|
|
||||||
public static JSObject unwrap(Object o) {
|
public static JSObject unwrap(Object o) {
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
return 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) {
|
public static JSObject maybeUnwrap(Object o) {
|
||||||
if (o == null) {
|
if (o == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return o instanceof JSWrapper ? unwrap(o) : directJavaToJs(o);
|
return isJava(o) ? unwrap(o) : directJavaToJs(o);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JSObject javaToJs(Object o) {
|
public static JSObject javaToJs(Object o) {
|
||||||
|
|
|
@ -48,6 +48,17 @@ public class JSWrapperGenerator implements Injector, DependencyPlugin {
|
||||||
context.getWriter().append(")");
|
context.getWriter().append(")");
|
||||||
}
|
}
|
||||||
break;
|
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