diff --git a/html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java b/html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java
index 5b676ba9e..f9fe62c5f 100644
--- a/html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java
+++ b/html4j/src/main/java/org/teavm/html4j/HTML4JPlugin.java
@@ -25,10 +25,13 @@ public class HTML4JPlugin implements TeaVMPlugin {
if (host.getExtension(TeaVMJavaScriptHost.class) == null) {
return;
}
- host.add(new JavaScriptBodyDependency());
+
+ JavaScriptBodyDependency bodyDependency = new JavaScriptBodyDependency();
+ host.add(bodyDependency);
host.add(new JavaScriptBodyTransformer());
host.add(new JCLHacks());
host.getExtension(TeaVMJavaScriptHost.class).add(new JavaScriptResourceInterceptor());
+ host.getExtension(TeaVMJavaScriptHost.class).add(new JavaScriptObjectEnhancer(bodyDependency));
}
}
diff --git a/html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java b/html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java
index 4ac433212..e58bb6fe5 100644
--- a/html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java
+++ b/html4j/src/main/java/org/teavm/html4j/JavaScriptBodyDependency.java
@@ -35,14 +35,11 @@ import org.teavm.model.ElementModifier;
import org.teavm.model.MethodDescriptor;
import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference;
+import org.teavm.model.ValueType;
-/**
- *
- * @author Alexey Andreev
- */
public class JavaScriptBodyDependency extends AbstractDependencyListener {
private DependencyNode allClassesNode;
- private Map> achievedMethods = new HashMap<>();
+ private Map> reachedMethods = new HashMap<>();
@Override
public void started(DependencyAgent agent) {
@@ -50,9 +47,13 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
allClassesNode.setTag("JavaScriptBody:global");
}
- private static class OneDirectionalConnection implements DependencyConsumer {
+ public String[] getClassesPassedToJavaScript() {
+ return allClassesNode.getTypes();
+ }
+
+ static class OneDirectionalConnection implements DependencyConsumer {
private DependencyNode target;
- public OneDirectionalConnection(DependencyNode target) {
+ OneDirectionalConnection(DependencyNode target) {
this.target = target;
}
@Override public void consume(DependencyType type) {
@@ -71,14 +72,14 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
@Override
public void methodReached(DependencyAgent agent, MethodDependency method, CallLocation location) {
- Set methodsToAchieve = achievedMethods.get(method.getReference());
- if (methodsToAchieve != null) {
- for (MethodReference methodToAchieve : methodsToAchieve) {
- agent.linkMethod(methodToAchieve, location);
+ Set methodsToReach = reachedMethods.get(method.getReference());
+ if (methodsToReach != null) {
+ for (MethodReference methodToReach : methodsToReach) {
+ agent.linkMethod(methodToReach, location);
}
return;
}
- achievedMethods.put(method.getReference(), new HashSet());
+ reachedMethods.put(method.getReference(), new HashSet<>());
if (method.isMissing()) {
return;
}
@@ -94,6 +95,15 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
}
for (int i = 0; i < method.getParameterCount(); ++i) {
method.getVariable(i).connect(allClassesNode);
+ method.getVariable(i).addConsumer(type -> {
+ if (agent.getClassSource().isSuperType("java.lang.Enum", type.getName()).orElse(false)) {
+ MethodReference toStringMethod = new MethodReference(type.getName(), "toString",
+ ValueType.parse(String.class));
+ MethodDependency dependency = agent.linkMethod(toStringMethod, location);
+ dependency.getVariable(0).propagate(type);
+ dependency.use();
+ }
+ });
allClassesNode.addConsumer(new OneDirectionalConnection(method.getVariable(i).getArrayItem()));
allClassesNode.addConsumer(new OneDirectionalConnection(method.getVariable(i).getArrayItem()
.getArrayItem()));
@@ -157,11 +167,11 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
return true;
}
- private class GeneratorJsCallback extends JsCallback {
+ class GeneratorJsCallback extends JsCallback {
private DependencyAgent agent;
private MethodDependency caller;
private CallLocation location;
- public GeneratorJsCallback(DependencyAgent agent, MethodDependency caller, CallLocation location) {
+ GeneratorJsCallback(DependencyAgent agent, MethodDependency caller, CallLocation location) {
this.agent = agent;
this.caller = caller;
this.location = location;
@@ -171,7 +181,7 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
MethodReader reader = findMethod(agent.getClassSource(), fqn, desc);
MethodReference ref = reader != null ? reader.getReference() : new MethodReference(fqn, desc);
MethodDependency methodDep = agent.linkMethod(ref, location);
- achievedMethods.get(caller.getReference()).add(ref);
+ reachedMethods.get(caller.getReference()).add(ref);
if (!methodDep.isMissing()) {
if (reader.hasModifier(ElementModifier.STATIC) || reader.hasModifier(ElementModifier.FINAL)) {
methodDep.use();
@@ -186,12 +196,12 @@ public class JavaScriptBodyDependency extends AbstractDependencyListener {
}
}
- private class VirtualCallbackConsumer implements DependencyConsumer {
+ class VirtualCallbackConsumer implements DependencyConsumer {
private DependencyAgent agent;
private MethodReader superMethod;
private ClassReader superClass;
private MethodDependency caller;
- public VirtualCallbackConsumer(DependencyAgent agent, MethodReader superMethod, MethodDependency caller) {
+ VirtualCallbackConsumer(DependencyAgent agent, MethodReader superMethod, MethodDependency caller) {
this.agent = agent;
this.superMethod = superMethod;
this.caller = caller;
diff --git a/html4j/src/main/java/org/teavm/html4j/JavaScriptObjectEnhancer.java b/html4j/src/main/java/org/teavm/html4j/JavaScriptObjectEnhancer.java
new file mode 100644
index 000000000..534d66269
--- /dev/null
+++ b/html4j/src/main/java/org/teavm/html4j/JavaScriptObjectEnhancer.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2017 Alexey Andreev.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.teavm.html4j;
+
+import java.io.IOException;
+import org.teavm.backend.javascript.codegen.SourceWriter;
+import org.teavm.backend.javascript.rendering.RenderingManager;
+import org.teavm.model.ClassReaderSource;
+import org.teavm.model.MethodReference;
+import org.teavm.model.ValueType;
+import org.teavm.vm.BuildTarget;
+import org.teavm.vm.spi.RendererListener;
+
+public class JavaScriptObjectEnhancer implements RendererListener {
+ private ClassReaderSource classSource;
+ private SourceWriter writer;
+ private JavaScriptBodyDependency dependencyListener;
+
+ public JavaScriptObjectEnhancer(JavaScriptBodyDependency dependencyListener) {
+ this.dependencyListener = dependencyListener;
+ }
+
+ @Override
+ public void begin(RenderingManager context, BuildTarget buildTarget) throws IOException {
+ classSource = context.getClassSource();
+ writer = context.getWriter();
+ }
+
+ @Override
+ public void complete() throws IOException {
+ for (String className : dependencyListener.getClassesPassedToJavaScript()) {
+ if (classSource.isSuperType("java.lang.Enum", className).orElse(false)) {
+ MethodReference toStringMethod = new MethodReference(className, "toString",
+ ValueType.parse(String.class));
+ writer.appendClass(className).append(".prototype.toString").ws().append("=").ws()
+ .append("function()").ws().append("{").indent().newLine();
+ writer.append("return $rt_ustr(").appendMethodBody(toStringMethod).append("(this));").softNewLine();
+ writer.outdent().append("};").softNewLine();
+ }
+ }
+ }
+}
diff --git a/html4j/src/test/java/org/teavm/html4j/test/JavaScriptTCKTest.java b/html4j/src/test/java/org/teavm/html4j/test/JavaScriptTCKTest.java
index 48022a357..9cd965d88 100644
--- a/html4j/src/test/java/org/teavm/html4j/test/JavaScriptTCKTest.java
+++ b/html4j/src/test/java/org/teavm/html4j/test/JavaScriptTCKTest.java
@@ -236,7 +236,7 @@ public class JavaScriptTCKTest extends JavaScriptBodyTest {
@Test @Override
public void toStringOfAnEnum() {
- //super.toStringOfAnEnum();
+ super.toStringOfAnEnum();
}
@Test @Override