mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds some more support of reflection
This commit is contained in:
parent
b3fe2f6a29
commit
620d2cef62
|
@ -19,6 +19,9 @@ public class ClassNativeGenerator implements Generator {
|
||||||
case "isAssignable":
|
case "isAssignable":
|
||||||
generateIsAssignableFrom(context, writer);
|
generateIsAssignableFrom(context, writer);
|
||||||
break;
|
break;
|
||||||
|
case "getComponentType":
|
||||||
|
generateGetComponentType(context, writer);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,4 +34,10 @@ public class ClassNativeGenerator implements Generator {
|
||||||
writer.append("return $rt_isAssignable(").append(context.getParameterName(1)).append(".$data, ")
|
writer.append("return $rt_isAssignable(").append(context.getParameterName(1)).append(".$data, ")
|
||||||
.append(context.getParameterName(0)).append(".$data;").newLine();
|
.append(context.getParameterName(0)).append(".$data;").newLine();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateGetComponentType(GeneratorContext context, SourceWriter writer) {
|
||||||
|
String thisArg = context.getParameterName(0);
|
||||||
|
writer.append("var item = " + thisArg + ".$data.$meta.item;").newLine();
|
||||||
|
writer.append("return item != null ? $rt_cls(item) : null;").newLine();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,17 +57,7 @@ public class ObjectNativeGenerator implements Generator, DependencyPlugin {
|
||||||
|
|
||||||
private void generateGetClass(GeneratorContext context, SourceWriter writer) {
|
private void generateGetClass(GeneratorContext context, SourceWriter writer) {
|
||||||
String thisArg = context.getParameterName(0);
|
String thisArg = context.getParameterName(0);
|
||||||
String classClass = "java.lang.Class";
|
writer.append("return $rt_cls(").append(thisArg).append(".$class);").newLine();
|
||||||
writer.append("var cls = ").append(thisArg).append(".$class.classObject;").newLine();
|
|
||||||
writer.append("if (cls === undefined) {").newLine().indent();
|
|
||||||
MethodReference createMethodRef = new MethodReference(classClass, new MethodDescriptor("createNew",
|
|
||||||
ValueType.object(classClass)));
|
|
||||||
writer.append("cls = ").appendClass(classClass).append('.').appendMethod(createMethodRef)
|
|
||||||
.append("();").newLine();
|
|
||||||
writer.append("cls.$data = ").append(thisArg).append(".$class;").newLine();
|
|
||||||
writer.append(thisArg).append(".$class.classObject = cls;").newLine();
|
|
||||||
writer.outdent().append("}").newLine();
|
|
||||||
writer.append("return cls;").newLine();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void achieveGetClass(DependencyChecker checker) {
|
private void achieveGetClass(DependencyChecker checker) {
|
||||||
|
|
|
@ -7,10 +7,39 @@ import org.teavm.javascript.ni.GeneratedBy;
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class TClass<T> extends TObject {
|
public class TClass<T> extends TObject {
|
||||||
|
String name;
|
||||||
|
boolean primitive;
|
||||||
|
boolean array;
|
||||||
|
private TClass<?> componentType;
|
||||||
|
private boolean componentTypeDirty = true;
|
||||||
|
|
||||||
static TClass<?> createNew() {
|
static TClass<?> createNew() {
|
||||||
return new TClass<>();
|
return new TClass<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(ClassNativeGenerator.class)
|
@GeneratedBy(ClassNativeGenerator.class)
|
||||||
public native boolean isInstance(TObject obj);
|
public native boolean isInstance(TObject obj);
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPrimitive() {
|
||||||
|
return primitive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isArray() {
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TClass<?> getComponentType() {
|
||||||
|
if (componentTypeDirty) {
|
||||||
|
componentType = getComponentType0();
|
||||||
|
componentTypeDirty = false;
|
||||||
|
}
|
||||||
|
return componentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GeneratedBy(ClassNativeGenerator.class)
|
||||||
|
private native TClass<?> getComponentType0();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
class TClassTests {
|
||||||
|
@Test
|
||||||
|
public void classNameEvaluated() {
|
||||||
|
assertEquals("java.lang.Object", Object.class.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void objectClassNameEvaluated() {
|
||||||
|
assertEquals("java.lang.Object", new Object().getClass().getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void objectClassConsideredNotArray() {
|
||||||
|
assertFalse(Object.class.isArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void arrayClassConsideredArray() {
|
||||||
|
assertFalse(Object[].class.isArray());
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,7 +32,7 @@ public class ClasslibTestGenerator {
|
||||||
private static List<MethodReference> testMethods = new ArrayList<>();
|
private static List<MethodReference> testMethods = new ArrayList<>();
|
||||||
private static Map<String, List<MethodReference>> groupedMethods = new HashMap<>();
|
private static Map<String, List<MethodReference>> groupedMethods = new HashMap<>();
|
||||||
private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests",
|
private static String[] testClasses = { "java.lang.ObjectTests", "java.lang.SystemTests",
|
||||||
"java.lang.StringBuilderTests" };
|
"java.lang.StringBuilderTests", "java.lang.ClassTests" };
|
||||||
|
|
||||||
public static void main(String[] args) throws IOException {
|
public static void main(String[] args) throws IOException {
|
||||||
out = System.out;
|
out = System.out;
|
||||||
|
|
|
@ -52,16 +52,28 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderRuntimeCls() {
|
private void renderRuntimeCls() {
|
||||||
writer.append("$rt_cls = function(cls) {").indent().newLine();
|
writer.append("$rt_cls = function(clsProto) {").indent().newLine();
|
||||||
String classClass = "java.lang.Class";
|
String classClass = "java.lang.Class";
|
||||||
writer.append("var cls = cls.classObject;").newLine();
|
writer.append("var cls = clsProto.classObject;").newLine();
|
||||||
writer.append("if (cls === undefined) {").newLine().indent();
|
writer.append("if (cls === undefined) {").newLine().indent();
|
||||||
MethodReference createMethodRef = new MethodReference(classClass, new MethodDescriptor("createNew",
|
MethodReference createMethodRef = new MethodReference(classClass, new MethodDescriptor("createNew",
|
||||||
ValueType.object(classClass)));
|
ValueType.object(classClass)));
|
||||||
writer.append("cls = ").appendClass(classClass).append('.').appendMethod(createMethodRef)
|
writer.append("cls = ").appendClass(classClass).append('.').appendMethod(createMethodRef)
|
||||||
.append("();").newLine();
|
.append("();").newLine();
|
||||||
writer.append("cls.$data = cls;").newLine();
|
writer.append("cls.$data = clsProto;").newLine();
|
||||||
writer.append("cls.classObject = cls;").newLine();
|
if (classSource.getClassHolder(classClass).getField("name") != null) {
|
||||||
|
writer.append("cls.").appendField(new FieldReference(classClass, "name"))
|
||||||
|
.append(" = clsProto.$meta.name !== undefined ? $rt_str(clsProto.$meta.name) : null;").newLine();
|
||||||
|
}
|
||||||
|
if (classSource.getClassHolder(classClass).getField("primitive") != null) {
|
||||||
|
writer.append("cls.").appendField(new FieldReference(classClass, "primitive"))
|
||||||
|
.append(" = clsProto.$meta.primitive ? 1 : 0;").newLine();
|
||||||
|
}
|
||||||
|
if (classSource.getClassHolder(classClass).getField("array") != null) {
|
||||||
|
writer.append("cls.").appendField(new FieldReference(classClass, "array"))
|
||||||
|
.append(" = clsProto.$meta.item ? 1 : 0;").newLine();
|
||||||
|
}
|
||||||
|
writer.append("clsProto.classObject = cls;").newLine();
|
||||||
writer.outdent().append("}").newLine();
|
writer.outdent().append("}").newLine();
|
||||||
writer.append("return cls;").newLine();
|
writer.append("return cls;").newLine();
|
||||||
writer.outdent().append("}").newLine();
|
writer.outdent().append("}").newLine();
|
||||||
|
|
|
@ -50,7 +50,7 @@ $rt_arraycls = function(cls) {
|
||||||
this.$class = arraycls;
|
this.$class = arraycls;
|
||||||
};
|
};
|
||||||
arraycls.prototype = new ($rt_objcls())();
|
arraycls.prototype = new ($rt_objcls())();
|
||||||
arraycls.$meta = { item : cls, supertypes : [$rt_objcls()] };
|
arraycls.$meta = { item : cls, supertypes : [$rt_objcls()], primitive : false };
|
||||||
cls.$array = arraycls;
|
cls.$array = arraycls;
|
||||||
}
|
}
|
||||||
return cls.$array;
|
return cls.$array;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user