mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Automatically make all JSObject implementors' methods as @Sync
This commit is contained in:
parent
4908293e50
commit
0c5fb8d9b0
|
@ -28,12 +28,17 @@ public class JSObjectClassTransformer implements ClassHolderTransformer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) {
|
public void transformClass(ClassHolder cls, ClassReaderSource innerSource, Diagnostics diagnostics) {
|
||||||
|
if (processor == null || processor.getClassSource() != innerSource) {
|
||||||
processor = new JavascriptNativeProcessor(innerSource);
|
processor = new JavascriptNativeProcessor(innerSource);
|
||||||
|
}
|
||||||
processor.setDiagnostics(diagnostics);
|
processor.setDiagnostics(diagnostics);
|
||||||
processor.processClass(cls);
|
processor.processClass(cls);
|
||||||
if (processor.isNative(cls.getName())) {
|
if (processor.isNative(cls.getName())) {
|
||||||
processor.processFinalMethods(cls);
|
processor.processFinalMethods(cls);
|
||||||
}
|
}
|
||||||
|
if (processor.isNativeImplementation(cls.getName())) {
|
||||||
|
processor.makeSync(cls);
|
||||||
|
}
|
||||||
for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) {
|
for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) {
|
||||||
if (method.getAnnotations().get(JSBody.class.getName()) != null) {
|
if (method.getAnnotations().get(JSBody.class.getName()) != null) {
|
||||||
processor.processJSBody(cls, method);
|
processor.processJSBody(cls, method);
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.teavm.jso.plugin;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.javascript.spi.GeneratedBy;
|
import org.teavm.javascript.spi.GeneratedBy;
|
||||||
|
import org.teavm.javascript.spi.Sync;
|
||||||
import org.teavm.jso.*;
|
import org.teavm.jso.*;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.instructions.*;
|
import org.teavm.model.instructions.*;
|
||||||
|
@ -41,10 +42,18 @@ class JavascriptNativeProcessor {
|
||||||
nativeRepos = new NativeJavascriptClassRepository(classSource);
|
nativeRepos = new NativeJavascriptClassRepository(classSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ClassReaderSource getClassSource() {
|
||||||
|
return classSource;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isNative(String className) {
|
public boolean isNative(String className) {
|
||||||
return nativeRepos.isJavaScriptClass(className);
|
return nativeRepos.isJavaScriptClass(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isNativeImplementation(String className) {
|
||||||
|
return nativeRepos.isJavaScriptImplementation(className);
|
||||||
|
}
|
||||||
|
|
||||||
public void setDiagnostics(Diagnostics diagnostics) {
|
public void setDiagnostics(Diagnostics diagnostics) {
|
||||||
this.diagnostics = diagnostics;
|
this.diagnostics = diagnostics;
|
||||||
}
|
}
|
||||||
|
@ -111,6 +120,44 @@ class JavascriptNativeProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void makeSync(ClassHolder cls) {
|
||||||
|
Set<MethodDescriptor> methods = new HashSet<>();
|
||||||
|
findInheritedMethods(cls, methods, new HashSet<String>());
|
||||||
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
|
if (methods.contains(method.getDescriptor()) && method.getAnnotations().get(Sync.class.getName()) == null) {
|
||||||
|
AnnotationHolder annot = new AnnotationHolder(Sync.class.getName());
|
||||||
|
method.getAnnotations().add(annot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void findInheritedMethods(ClassReader cls, Set<MethodDescriptor> methods, Set<String> visited) {
|
||||||
|
if (!visited.add(cls.getName())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isNative(cls.getName())) {
|
||||||
|
for (MethodReader method : cls.getMethods()) {
|
||||||
|
if (!method.hasModifier(ElementModifier.STATIC) && !method.hasModifier(ElementModifier.FINAL) &&
|
||||||
|
method.getLevel() != AccessLevel.PRIVATE) {
|
||||||
|
methods.add(method.getDescriptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (isNativeImplementation(cls.getName())) {
|
||||||
|
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
|
||||||
|
ClassReader parentCls = classSource.get(cls.getParent());
|
||||||
|
if (parentCls != null) {
|
||||||
|
findInheritedMethods(parentCls, methods, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String iface : cls.getInterfaces()) {
|
||||||
|
ClassReader parentCls = classSource.get(iface);
|
||||||
|
if (parentCls != null) {
|
||||||
|
findInheritedMethods(parentCls, methods, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static ValueType[] getStaticSignature(MethodReference method) {
|
private static ValueType[] getStaticSignature(MethodReference method) {
|
||||||
ValueType[] signature = method.getSignature();
|
ValueType[] signature = method.getSignature();
|
||||||
ValueType[] staticSignature = new ValueType[signature.length + 1];
|
ValueType[] staticSignature = new ValueType[signature.length + 1];
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.teavm.model.ElementModifier;
|
||||||
class NativeJavascriptClassRepository {
|
class NativeJavascriptClassRepository {
|
||||||
private ClassReaderSource classSource;
|
private ClassReaderSource classSource;
|
||||||
private Map<String, Boolean> knownJavaScriptClasses = new HashMap<>();
|
private Map<String, Boolean> knownJavaScriptClasses = new HashMap<>();
|
||||||
|
private Map<String, Boolean> knownJavaScriptImplementations = new HashMap<>();
|
||||||
|
|
||||||
public NativeJavascriptClassRepository(ClassReaderSource classSource) {
|
public NativeJavascriptClassRepository(ClassReaderSource classSource) {
|
||||||
this.classSource = classSource;
|
this.classSource = classSource;
|
||||||
|
@ -38,13 +39,22 @@ class NativeJavascriptClassRepository {
|
||||||
public boolean isJavaScriptClass(String className) {
|
public boolean isJavaScriptClass(String className) {
|
||||||
Boolean known = knownJavaScriptClasses.get(className);
|
Boolean known = knownJavaScriptClasses.get(className);
|
||||||
if (known == null) {
|
if (known == null) {
|
||||||
known = figureOutIfJavaScriptClass(className);
|
known = examineIfJavaScriptClass(className);
|
||||||
knownJavaScriptClasses.put(className, known);
|
knownJavaScriptClasses.put(className, known);
|
||||||
}
|
}
|
||||||
return known;
|
return known;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean figureOutIfJavaScriptClass(String className) {
|
public boolean isJavaScriptImplementation(String className) {
|
||||||
|
Boolean known = knownJavaScriptImplementations.get(className);
|
||||||
|
if (known == null) {
|
||||||
|
known = examineIfJavaScriptImplementation(className);
|
||||||
|
knownJavaScriptImplementations.put(className, known);
|
||||||
|
}
|
||||||
|
return known;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean examineIfJavaScriptClass(String className) {
|
||||||
ClassReader cls = classSource.get(className);
|
ClassReader cls = classSource.get(className);
|
||||||
if (cls == null || !(cls.hasModifier(ElementModifier.INTERFACE) || cls.hasModifier(ElementModifier.ABSTRACT))) {
|
if (cls == null || !(cls.hasModifier(ElementModifier.INTERFACE) || cls.hasModifier(ElementModifier.ABSTRACT))) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -56,4 +66,25 @@ class NativeJavascriptClassRepository {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean examineIfJavaScriptImplementation(String className) {
|
||||||
|
if (isJavaScriptClass(className)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
ClassReader cls = classSource.get(className);
|
||||||
|
if (cls == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (cls.getParent() != null && !cls.getParent().equals(cls.getName())) {
|
||||||
|
if (isJavaScriptClass(cls.getParent())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (String iface : cls.getInterfaces()) {
|
||||||
|
if (isJavaScriptClass(iface)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user