From b3fe2f6a293194475371dd2c35837d764014964e Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Tue, 3 Dec 2013 19:07:53 +0400 Subject: [PATCH] Fixes a bug with Object.getClass() behaviour. Improves JUnit emulation --- ...nerator.java => ArrayNativeGenerator.java} | 4 +- .../classlib/java/lang/reflect/TArray.java | 4 +- .../classlibgen/ClasslibTestGenerator.java | 6 +- .../org/teavm/classlib/junit-support.js | 56 +++++++++++++++++++ .../java/org/teavm/javascript/Renderer.java | 2 + .../resources/org/teavm/javascript/runtime.js | 27 ++++++--- 6 files changed, 86 insertions(+), 13 deletions(-) rename teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/{TArrayNativeGenerator.java => ArrayNativeGenerator.java} (95%) diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/TArrayNativeGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java similarity index 95% rename from teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/TArrayNativeGenerator.java rename to teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java index 1d518251d..4b283ec0b 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/TArrayNativeGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/ArrayNativeGenerator.java @@ -15,7 +15,7 @@ import org.teavm.model.ValueType; * * @author Alexey Andreev */ -public class TArrayNativeGenerator implements Generator, DependencyPlugin { +public class ArrayNativeGenerator implements Generator, DependencyPlugin { @Override public void methodAchieved(DependencyChecker checker, MethodReference method) { if (method.getName().equals("getLength")) { @@ -34,7 +34,7 @@ public class TArrayNativeGenerator implements Generator, DependencyPlugin { private void generateGetLength(GeneratorContext context, SourceWriter writer) { String array = context.getParameterName(1); - writer.append("if (" + array + " === null || " + array + " .$cls.$meta.item === undefined) {") + writer.append("if (" + array + " === null || " + array + " .$class.$meta.item === undefined) {") .newLine().indent(); String clsName = "java.lang.IllegalArgumentException"; MethodReference cons = new MethodReference(clsName, new MethodDescriptor("", ValueType.VOID)); diff --git a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/TArray.java b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/TArray.java index 86fd2ffb2..bd874e9ad 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/TArray.java +++ b/teavm-classlib/src/main/java/org/teavm/classlib/java/lang/reflect/TArray.java @@ -10,7 +10,7 @@ import org.teavm.javascript.ni.GeneratedBy; * @author Alexey Andreev */ public final class TArray extends TObject { - @GeneratedBy(TArrayNativeGenerator.class) - @PluggableDependency(TArrayNativeGenerator.class) + @GeneratedBy(ArrayNativeGenerator.class) + @PluggableDependency(ArrayNativeGenerator.class) public static native int getLength(TObject array) throws TIllegalArgumentException; } diff --git a/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java b/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java index 5bd8397e8..8b592cad5 100644 --- a/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java +++ b/teavm-classlib/src/main/java/org/teavm/classlibgen/ClasslibTestGenerator.java @@ -99,8 +99,12 @@ public class ClasslibTestGenerator { out.println(" border: 2px solid black;"); out.println(" margin: 2em 1em 2em 1em;"); out.println(" }"); - out.println(" table td {"); + out.println(" table td, table th {"); out.println(" border: 1px solid gray;"); + out.println(" padding: 0.1em 0.5em 0.2em 0.5em;"); + out.println(" }"); + out.println(" table thead, table tfoot {"); + out.println(" border: 2px solid black;"); out.println(" }"); out.println(" "); out.println(" "); diff --git a/teavm-classlib/src/main/resources/org/teavm/classlib/junit-support.js b/teavm-classlib/src/main/resources/org/teavm/classlib/junit-support.js index 873dc434d..5e16bc9a1 100644 --- a/teavm-classlib/src/main/resources/org/teavm/classlib/junit-support.js +++ b/teavm-classlib/src/main/resources/org/teavm/classlib/junit-support.js @@ -1,4 +1,7 @@ currentTestReportBody = null; +currentTimeSpent = 0; +totalTimeSpent = 0; +currentMethodCount = 0; runTestCase = function(instance, methodName, realMethodName, expectedExceptions) { var row = document.createElement("tr"); @@ -10,23 +13,37 @@ runTestCase = function(instance, methodName, realMethodName, expectedExceptions) row.appendChild(statusCell); var exceptionCell = document.createElement("td"); row.appendChild(exceptionCell); + var timeCell = document.createElement("td"); + row.appendChild(timeCell); + var startTime = new Date().getTime(); + var endTime; try { instance[realMethodName](); + endTime = new Date().getTime(); if (expectedExceptions.length > 0) { statusCell.appendChild(document.createTextNode("expected exception not thrown")); + statusCell.style.color = 'yellow'; } else { statusCell.appendChild(document.createTextNode("ok")); + statusCell.style.color = 'green'; } } catch (e) { + endTime = new Date().getTime(); if (isExpectedException(e, expectedExceptions)) { statusCell.appendChild(document.createTextNode("ok")); + statusCell.style.color = 'green'; } else { statusCell.appendChild(document.createTextNode("unexpected exception")); var exceptionText = document.createElement("pre"); exceptionText.appendChild(document.createTextNode(e.stack)); exceptionCell.appendChild(exceptionText); + statusCell.style.color = 'red'; } } + ++currentMethodCount; + var timeSpent = (endTime - startTime) / 1000; + currentTimeSpent += timeSpent; + timeCell.appendChild(document.createTextNode(timeSpent.toFixed(3))); } isExpectedException = function(e, expectedExceptions) { @@ -41,14 +58,53 @@ isExpectedException = function(e, expectedExceptions) { } testClass = function(className, classTests) { + currentTimeSpent = 0; + currentMethodCount = 0; var table = document.createElement("table"); document.body.appendChild(table); var caption = document.createElement("caption"); table.appendChild(caption); caption.appendChild(document.createTextNode(className)); + + var head = document.createElement("thead"); + table.appendChild(head); + var headRow = document.createElement("tr"); + head.appendChild(headRow); + var headCell = document.createElement("th"); + headRow.appendChild(headCell); + headCell.appendChild(document.createTextNode("Method")); + headCell = document.createElement("th"); + headRow.appendChild(headCell); + headCell.appendChild(document.createTextNode("Result")); + headCell = document.createElement("th"); + headRow.appendChild(headCell); + headCell.appendChild(document.createTextNode("Exception")); + headCell = document.createElement("th"); + headRow.appendChild(headCell); + headCell.appendChild(document.createTextNode("Time spent, s")); + var tbody = document.createElement("tbody"); table.appendChild(tbody); currentTestReportBody = tbody; classTests(); + + var foot = document.createElement("tfoot"); + table.appendChild(foot); + var footRow = document.createElement("tr"); + foot.appendChild(footRow); + var footName = document.createElement("td"); + footRow.appendChild(footName); + footName.appendChild(document.createTextNode("---")); + var footMethods = document.createElement("td"); + footRow.appendChild(footMethods); + footMethods.appendChild(document.createTextNode(currentMethodCount)); + var footSpace = document.createElement("td"); + footRow.appendChild(footSpace); + footSpace.appendChild(document.createTextNode("---")); + var footTime = document.createElement("td"); + footRow.appendChild(footTime); + footTime.appendChild(document.createTextNode(currentTimeSpent.toFixed(3))); + totalTimeSpent += currentTimeSpent; + currentTestReportBody = null; } \ No newline at end of file diff --git a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java index 36f4821c4..5772bc1ca 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Renderer.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Renderer.java @@ -119,6 +119,8 @@ public class Renderer implements ExprVisitor, StatementVisitor { .append(cls.getParentName() != null ? naming.getNameFor(cls.getParentName()) : "Object").append("();").newLine(); writer.appendClass(cls.getName()).append(".$meta = { "); + writer.append("name : \"").append(cls.getName()).append("\", "); + writer.append("primitive : false, "); writer.append("supertypes : ["); boolean first = true; if (cls.getParentName() != null) { diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 537e74268..44cf0a2c1 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -47,7 +47,7 @@ $rt_arraycls = function(cls) { if (cls.$array == undefined) { var arraycls = function(data) { this.data = data; - this.$cls = arraycls; + this.$class = arraycls; }; arraycls.prototype = new ($rt_objcls())(); arraycls.$meta = { item : cls, supertypes : [$rt_objcls()] }; @@ -66,13 +66,8 @@ $rt_booleanclsCache = null; $rt_booleancls = function() { if ($rt_booleanclsCache == null) { $rt_booleanclsCache = $rt_createcls(); - } - return $rt_booleanclsCache; -} -$rt_booleanclsCache = null; -$rt_booleancls = function() { - if ($rt_booleanclsCache == null) { - $rt_booleanclsCache = $rt_createcls(); + $rt_booleanclsCache.primitive = true; + $rt_booleanclsCache.name = "boolean"; } return $rt_booleanclsCache; } @@ -80,6 +75,8 @@ $rt_charclsCache = null; $rt_charcls = function() { if ($rt_charclsCache == null) { $rt_charclsCache = $rt_createcls(); + $rt_charclsCache.primitive = true; + $rt_charclsCache.name = "char"; } return $rt_charclsCache; } @@ -87,6 +84,8 @@ $rt_byteclsCache = null; $rt_bytecls = function() { if ($rt_byteclsCache == null) { $rt_byteclsCache = $rt_createcls(); + $rt_byteclsCache.primitive = true; + $rt_byteclsCache.name = "byte"; } return $rt_byteclsCache; } @@ -94,6 +93,8 @@ $rt_shortclsCache = null; $rt_shortcls = function() { if ($rt_shortclsCache == null) { $rt_shortclsCache = $rt_createcls(); + $rt_shortclsCache.primitive = true; + $rt_shortclsCache.name = "short"; } return $rt_shortclsCache; } @@ -101,6 +102,8 @@ $rt_intclsCache = null; $rt_intcls = function() { if ($rt_intclsCache == null) { $rt_intclsCache = $rt_createcls(); + $rt_intclsCache.primitive = true; + $rt_intclsCache.name = "int"; } return $rt_intclsCache; } @@ -108,6 +111,8 @@ $rt_longclsCache = null; $rt_longcls = function() { if ($rt_longclsCache == null) { $rt_longclsCache = $rt_createcls(); + $rt_longclsCache.primitive = true; + $rt_longclsCache.name = "long"; } return $rt_longclsCache; } @@ -115,6 +120,8 @@ $rt_floatclsCache = null; $rt_floatcls = function() { if ($rt_floatclsCache == null) { $rt_floatclsCache = $rt_createcls(); + $rt_floatclsCache.primitive = true; + $rt_floatclsCache.name = "float"; } return $rt_floatclsCache; } @@ -122,6 +129,8 @@ $rt_doubleclsCache = null; $rt_doublecls = function() { if ($rt_doubleclsCache == null) { $rt_doubleclsCache = $rt_createcls(); + $rt_doubleclsCache.primitive = true; + $rt_doubleclsCache.name = "double"; } return $rt_doubleclsCache; } @@ -129,6 +138,8 @@ $rt_voidclsCache = null; $rt_voidcls = function() { if ($rt_voidclsCache == null) { $rt_voidclsCache = $rt_createcls(); + $rt_voidclsCache.primitive = true; + $rt_voidclsCache.name = "void"; } return $rt_voidclsCache; }