mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
93798a335c
|
@ -16,5 +16,10 @@
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.11</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
|
@ -15,7 +15,7 @@ public class ObjectNativeGenerator implements Generator {
|
||||||
@Override
|
@Override
|
||||||
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
|
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) {
|
||||||
switch (methodRef.getDescriptor().getName()) {
|
switch (methodRef.getDescriptor().getName()) {
|
||||||
case "init":
|
case "<init>":
|
||||||
generateInit(context, writer);
|
generateInit(context, writer);
|
||||||
break;
|
break;
|
||||||
case "getClass":
|
case "getClass":
|
||||||
|
|
|
@ -2,17 +2,20 @@ package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
import org.teavm.javascript.ni.GeneratedBy;
|
import org.teavm.javascript.ni.GeneratedBy;
|
||||||
import org.teavm.javascript.ni.Rename;
|
import org.teavm.javascript.ni.Rename;
|
||||||
|
import org.teavm.javascript.ni.Superclass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
|
@Superclass("")
|
||||||
public class TObject {
|
public class TObject {
|
||||||
|
@Rename("fakeInit")
|
||||||
public TObject() {
|
public TObject() {
|
||||||
init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GeneratedBy(ObjectNativeGenerator.class)
|
@GeneratedBy(ObjectNativeGenerator.class)
|
||||||
|
@Rename("<init>")
|
||||||
private native void init();
|
private native void init();
|
||||||
|
|
||||||
@GeneratedBy(ObjectNativeGenerator.class)
|
@GeneratedBy(ObjectNativeGenerator.class)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package org.teavm.classlib.java.lang;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
class TObjectTests {
|
||||||
|
@Test
|
||||||
|
public void objectCreated() {
|
||||||
|
Object a = new Object();
|
||||||
|
assertNotNull(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void differentInstancesNotEqual() {
|
||||||
|
Object a = new Object();
|
||||||
|
Object b = new Object();
|
||||||
|
assertNotEquals(a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sameInstancesAreEqual() {
|
||||||
|
Object a = new Object();
|
||||||
|
Object b = a;
|
||||||
|
assertEquals(a, b);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
package org.teavm.classlib.java.lang.annotation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public @interface TAnnotation {
|
||||||
|
}
|
|
@ -1,12 +1,15 @@
|
||||||
package org.teavm.classlibgen;
|
package org.teavm.classlibgen;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.teavm.codegen.DefaultAliasProvider;
|
import org.teavm.codegen.DefaultAliasProvider;
|
||||||
import org.teavm.codegen.DefaultNamingStrategy;
|
import org.teavm.codegen.DefaultNamingStrategy;
|
||||||
import org.teavm.codegen.SourceWriter;
|
import org.teavm.codegen.SourceWriter;
|
||||||
import org.teavm.javascript.Decompiler;
|
import org.teavm.javascript.Decompiler;
|
||||||
import org.teavm.javascript.Renderer;
|
import org.teavm.javascript.Renderer;
|
||||||
import org.teavm.javascript.ast.ClassNode;
|
import org.teavm.javascript.ast.ClassNode;
|
||||||
import org.teavm.model.ClassHolder;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.resource.ClasspathClassHolderSource;
|
import org.teavm.model.resource.ClasspathClassHolderSource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,16 +17,77 @@ import org.teavm.model.resource.ClasspathClassHolderSource;
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
public class ClasslibTestGenerator {
|
public class ClasslibTestGenerator {
|
||||||
public static void main(String[] args) {
|
private static ClasspathClassHolderSource classSource;
|
||||||
ClasspathClassHolderSource source = new ClasspathClassHolderSource();
|
private static Decompiler decompiler;
|
||||||
Decompiler decompiler = new Decompiler(source);
|
private static DefaultAliasProvider aliasProvider;
|
||||||
ClassHolder cls = source.getClassHolder("java.lang.Object");
|
private static DefaultNamingStrategy naming;
|
||||||
ClassNode clsNode = decompiler.decompile(cls);
|
private static SourceWriter writer;
|
||||||
DefaultAliasProvider aliasProvider = new DefaultAliasProvider();
|
private static Renderer renderer;
|
||||||
DefaultNamingStrategy naming = new DefaultNamingStrategy(aliasProvider, source);
|
|
||||||
SourceWriter writer = new SourceWriter(naming);
|
public static void main(String[] args) throws IOException {
|
||||||
Renderer renderer = new Renderer(writer, source);
|
classSource = new ClasspathClassHolderSource();
|
||||||
renderer.render(clsNode);
|
decompiler = new Decompiler(classSource);
|
||||||
|
aliasProvider = new DefaultAliasProvider();
|
||||||
|
naming = new DefaultNamingStrategy(aliasProvider, classSource);
|
||||||
|
writer = new SourceWriter(naming);
|
||||||
|
renderer = new Renderer(writer, classSource);
|
||||||
|
decompileClass("java.lang.Object");
|
||||||
|
decompileClass("java.lang.ObjectTests");
|
||||||
|
decompileClass("java.lang.Class");
|
||||||
|
decompileClass("java.lang.annotation.Annotation");
|
||||||
|
decompileClass("org.junit.Assert");
|
||||||
|
decompileClass("org.junit.Test");
|
||||||
|
renderHead();
|
||||||
|
ClassLoader classLoader = ClasslibTestGenerator.class.getClassLoader();
|
||||||
|
try (InputStream input = classLoader.getResourceAsStream(
|
||||||
|
"org/teavm/classlib/junit-support.js")) {
|
||||||
|
System.out.println(IOUtils.toString(input));
|
||||||
|
}
|
||||||
|
try (InputStream input = classLoader.getResourceAsStream(
|
||||||
|
"org/teavm/javascript/runtime.js")) {
|
||||||
|
System.out.println(IOUtils.toString(input));
|
||||||
|
}
|
||||||
|
renderClassTest(classSource.getClassHolder("java.lang.ObjectTests"));
|
||||||
System.out.println(writer);
|
System.out.println(writer);
|
||||||
|
renderFoot();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void decompileClass(String className) {
|
||||||
|
ClassHolder cls = classSource.getClassHolder(className);
|
||||||
|
ClassNode clsNode = decompiler.decompile(cls);
|
||||||
|
renderer.render(clsNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void renderHead() {
|
||||||
|
System.out.println("<!DOCTYPE html>");
|
||||||
|
System.out.println("<html>");
|
||||||
|
System.out.println(" <head>");
|
||||||
|
System.out.println(" <title>TeaVM JUnit tests</title>");
|
||||||
|
System.out.println(" <meta http-equiv=\"Content-Type\" " +
|
||||||
|
"content=\"text/html;charset=UTF-8\"/>");
|
||||||
|
System.out.println(" <title>TeaVM JUnit tests</title>");
|
||||||
|
System.out.println(" </head>");
|
||||||
|
System.out.println(" <body>");
|
||||||
|
System.out.println(" <script type=\"text/javascript\">");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void renderFoot() {
|
||||||
|
System.out.println(" </script>");
|
||||||
|
System.out.println(" </body>");
|
||||||
|
System.out.println("</html>");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void renderClassTest(ClassHolder cls) {
|
||||||
|
writer.append("testClass(\"" + cls.getName() + "\", function() {").newLine().indent();
|
||||||
|
MethodReference cons = new MethodReference(cls.getName(),
|
||||||
|
new MethodDescriptor("<init>", ValueType.VOID));
|
||||||
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
|
if (method.getAnnotations().get("org.junit.Test") != null) {
|
||||||
|
MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor());
|
||||||
|
writer.append("runTestCase(").appendClass(cls.getName()).append(".").appendMethod(cons)
|
||||||
|
.append("(), \"" + method.getName() + "\", \"").appendMethod(ref).append("\");").newLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
writer.outdent().append("})").newLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
JUnitAssertionFailure = function() {}
|
||||||
|
JUnitAssertionFailure.prototype = new Error();
|
||||||
|
|
||||||
|
currentTestReportBody = null;
|
||||||
|
|
||||||
|
runTestCase = function(instance, methodName, realMethodName) {
|
||||||
|
var row = document.createElement("tr");
|
||||||
|
currentTestReportBody.appendChild(row);
|
||||||
|
var nameCell = document.createElement("td");
|
||||||
|
row.appendChild(nameCell);
|
||||||
|
nameCell.appendChild(document.createTextNode(methodName));
|
||||||
|
var statusCell = document.createElement("td");
|
||||||
|
row.appendChild(statusCell);
|
||||||
|
var exceptionCell = document.createElement("td");
|
||||||
|
row.appendChild(exceptionCell);
|
||||||
|
try {
|
||||||
|
instance[realMethodName]();
|
||||||
|
statusCell.appendChild(document.createTextNode("ok"));
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof JUnitAssertionFailure) {
|
||||||
|
statusCell.appendChild(document.createTextNode("assertion failed"));
|
||||||
|
exceptionCell.appendChild(document.createTextNode(e.stack));
|
||||||
|
} else {
|
||||||
|
statusCell.appendChild(document.createTextNode("unexpected exception"));
|
||||||
|
exceptionCell.appendChild(document.createTextNode(e.stack));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
testClass = function(className, classTests) {
|
||||||
|
var table = document.createElement("table");
|
||||||
|
document.body.appendChild(table);
|
||||||
|
var caption = document.createElement("caption");
|
||||||
|
table.appendChild(caption);
|
||||||
|
caption.appendChild(document.createTextNode(className));
|
||||||
|
var tbody = document.createElement("tbody");
|
||||||
|
table.appendChild(tbody);
|
||||||
|
currentTestReportBody = tbody;
|
||||||
|
classTests();
|
||||||
|
currentTestReportBody = null;
|
||||||
|
}
|
|
@ -153,7 +153,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
}
|
}
|
||||||
renderWorkingMethod(method);
|
renderWorkingMethod(method);
|
||||||
int startParam = 0;
|
int startParam = 0;
|
||||||
if (method.getModifiers().contains(ElementModifier.STATIC)) {
|
if (method.getModifiers().contains(NodeModifier.STATIC)) {
|
||||||
startParam = 1;
|
startParam = 1;
|
||||||
}
|
}
|
||||||
writer.appendClass(ref.getClassName()).append('.');
|
writer.appendClass(ref.getClassName()).append('.');
|
||||||
|
@ -186,7 +186,7 @@ public class Renderer implements ExprVisitor, StatementVisitor {
|
||||||
MethodReference ref = method.getReference();
|
MethodReference ref = method.getReference();
|
||||||
writer.append("function ").appendClass(ref.getClassName()).append('_').appendMethod(ref).append('(');
|
writer.append("function ").appendClass(ref.getClassName()).append('_').appendMethod(ref).append('(');
|
||||||
int startParam = 0;
|
int startParam = 0;
|
||||||
if (method.getModifiers().contains(ElementModifier.STATIC)) {
|
if (method.getModifiers().contains(NodeModifier.STATIC)) {
|
||||||
startParam = 1;
|
startParam = 1;
|
||||||
}
|
}
|
||||||
for (int i = startParam; i <= ref.parameterCount(); ++i) {
|
for (int i = startParam; i <= ref.parameterCount(); ++i) {
|
||||||
|
|
|
@ -302,11 +302,11 @@ public class StatementGenerator implements InstructionVisitor {
|
||||||
insn.getAlternative());
|
insn.getAlternative());
|
||||||
break;
|
break;
|
||||||
case NOT_NULL:
|
case NOT_NULL:
|
||||||
branch(Expr.binary(BinaryOperation.STRICT_EQUALS, Expr.var(insn.getOperand().getIndex()),
|
branch(Expr.binary(BinaryOperation.STRICT_NOT_EQUALS, Expr.var(insn.getOperand().getIndex()),
|
||||||
Expr.constant(null)), insn.getConsequent(), insn.getAlternative());
|
Expr.constant(null)), insn.getConsequent(), insn.getAlternative());
|
||||||
break;
|
break;
|
||||||
case NULL:
|
case NULL:
|
||||||
branch(Expr.binary(BinaryOperation.STRICT_NOT_EQUALS, Expr.var(insn.getOperand().getIndex()),
|
branch(Expr.binary(BinaryOperation.STRICT_EQUALS, Expr.var(insn.getOperand().getIndex()),
|
||||||
Expr.constant(null)), insn.getConsequent(), insn.getAlternative());
|
Expr.constant(null)), insn.getConsequent(), insn.getAlternative());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -489,7 +489,7 @@ public class StatementGenerator implements InstructionVisitor {
|
||||||
public String findDeclaringClass(String className, MethodDescriptor method) {
|
public String findDeclaringClass(String className, MethodDescriptor method) {
|
||||||
ClassHolder cls = classSource.getClassHolder(className);
|
ClassHolder cls = classSource.getClassHolder(className);
|
||||||
while (cls != null && cls.getMethod(method) == null) {
|
while (cls != null && cls.getMethod(method) == null) {
|
||||||
cls = classSource.getClassHolder(cls.getParent());
|
cls = cls.getParent() != null ? classSource.getClassHolder(cls.getParent()) : null;
|
||||||
}
|
}
|
||||||
return cls != null ? cls.getName() : null;
|
return cls != null ? cls.getName() : null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import java.lang.annotation.Target;
|
||||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target({ ElementType.METHOD, ElementType.CONSTRUCTOR })
|
||||||
public @interface Rename {
|
public @interface Rename {
|
||||||
String value();
|
String value();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.teavm.javascript.ni;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
public @interface Superclass {
|
||||||
|
String value();
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package org.teavm.model.resource;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import org.teavm.codegen.Mapper;
|
import org.teavm.codegen.Mapper;
|
||||||
import org.teavm.javascript.ni.Rename;
|
import org.teavm.javascript.ni.Rename;
|
||||||
|
import org.teavm.javascript.ni.Superclass;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.instructions.*;
|
import org.teavm.model.instructions.*;
|
||||||
|
|
||||||
|
@ -21,9 +22,15 @@ class ClassRefsRenamer implements InstructionVisitor {
|
||||||
ClassHolder renamedCls = new ClassHolder(classNameMapper.map(cls.getName()));
|
ClassHolder renamedCls = new ClassHolder(classNameMapper.map(cls.getName()));
|
||||||
renamedCls.getModifiers().addAll(cls.getModifiers());
|
renamedCls.getModifiers().addAll(cls.getModifiers());
|
||||||
renamedCls.setLevel(cls.getLevel());
|
renamedCls.setLevel(cls.getLevel());
|
||||||
if (cls.getParent() != null) {
|
String parent = cls.getParent();
|
||||||
renamedCls.setParent(classNameMapper.map(cls.getParent()));
|
AnnotationHolder superclassAnnot = cls.getAnnotations().get(Superclass.class.getName());
|
||||||
|
if (superclassAnnot != null) {
|
||||||
|
parent = superclassAnnot.getValues().get("value").getString();
|
||||||
|
if (parent.isEmpty()) {
|
||||||
|
parent = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
renamedCls.setParent(parent != null ? classNameMapper.map(parent) : null);
|
||||||
for (MethodHolder method : cls.getMethods()) {
|
for (MethodHolder method : cls.getMethods()) {
|
||||||
renamedCls.addMethod(rename(method));
|
renamedCls.addMethod(rename(method));
|
||||||
}
|
}
|
||||||
|
@ -71,7 +78,8 @@ class ClassRefsRenamer implements InstructionVisitor {
|
||||||
|
|
||||||
private void rename(AnnotationContainer source, AnnotationContainer target) {
|
private void rename(AnnotationContainer source, AnnotationContainer target) {
|
||||||
for (AnnotationHolder annot : source.all()) {
|
for (AnnotationHolder annot : source.all()) {
|
||||||
if (!annot.getType().equals(Rename.class.getName())) {
|
if (!annot.getType().equals(Rename.class.getName()) &&
|
||||||
|
!annot.getType().equals(Superclass.class.getName())) {
|
||||||
target.add(rename(annot));
|
target.add(rename(annot));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,10 @@ public class ClasspathResourceMapper implements Mapper<String, ClassHolder> {
|
||||||
String packageName = name.substring(0, index);
|
String packageName = name.substring(0, index);
|
||||||
ClassHolder classHolder = innerMapper.map(transformation.packagePrefix + "." + packageName +
|
ClassHolder classHolder = innerMapper.map(transformation.packagePrefix + "." + packageName +
|
||||||
"." + transformation.classPrefix + className);
|
"." + transformation.classPrefix + className);
|
||||||
return renamer.rename(classHolder);
|
if (classHolder != null) {
|
||||||
|
classHolder = renamer.rename(classHolder);
|
||||||
|
}
|
||||||
|
return classHolder;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return innerMapper.map(name);
|
return innerMapper.map(name);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user