JS: generate code in UMD wrapper (to be compatible with node.js, webpack, etc).

This commit is contained in:
Alexey Andreev 2023-08-01 20:11:32 +02:00
parent a1ed797d73
commit a97e0ef45c
3 changed files with 53 additions and 16 deletions

View File

@ -102,7 +102,6 @@ import org.teavm.model.util.AsyncMethodFinder;
import org.teavm.model.util.ProgramUtils; import org.teavm.model.util.ProgramUtils;
import org.teavm.vm.BuildTarget; import org.teavm.vm.BuildTarget;
import org.teavm.vm.RenderingException; import org.teavm.vm.RenderingException;
import org.teavm.vm.TeaVMEntryPoint;
import org.teavm.vm.TeaVMTarget; import org.teavm.vm.TeaVMTarget;
import org.teavm.vm.TeaVMTargetController; import org.teavm.vm.TeaVMTargetController;
import org.teavm.vm.spi.RendererListener; import org.teavm.vm.spi.RendererListener;
@ -378,8 +377,7 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
if (debugEmitterToUse == null) { if (debugEmitterToUse == null) {
debugEmitterToUse = new DummyDebugInformationEmitter(); debugEmitterToUse = new DummyDebugInformationEmitter();
} }
VirtualMethodContributorContext virtualMethodContributorContext = new VirtualMethodContributorContextImpl( var virtualMethodContributorContext = new VirtualMethodContributorContextImpl(classes);
classes);
RenderingContext renderingContext = new RenderingContext(debugEmitterToUse, RenderingContext renderingContext = new RenderingContext(debugEmitterToUse,
controller.getUnprocessedClassSource(), classes, controller.getUnprocessedClassSource(), classes,
controller.getClassLoader(), controller.getServices(), controller.getProperties(), naming, controller.getClassLoader(), controller.getServices(), controller.getProperties(), naming,
@ -439,17 +437,16 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
runtimeRenderer.renderHandWrittenRuntime("simpleThread.js"); runtimeRenderer.renderHandWrittenRuntime("simpleThread.js");
} }
for (Map.Entry<? extends String, ? extends TeaVMEntryPoint> entry for (var entry : controller.getEntryPoints().entrySet()) {
: controller.getEntryPoints().entrySet()) { sourceWriter.append("$rt_exports.").append(entry.getKey()).ws().append("=").ws();
sourceWriter.append(entry.getKey()).ws().append("=").ws(); var ref = entry.getValue().getMethod();
MethodReference ref = entry.getValue().getMethod();
sourceWriter.append("$rt_mainStarter(").appendMethodBody(ref); sourceWriter.append("$rt_mainStarter(").appendMethodBody(ref);
sourceWriter.append(");").newLine(); sourceWriter.append(");").newLine();
sourceWriter.append(entry.getKey()).append(".").append("javaException").ws().append("=").ws() sourceWriter.append("$rt_exports.").append(entry.getKey()).append(".").append("javaException")
.append("$rt_javaException;").newLine(); .ws().append("=").ws().append("$rt_javaException;").newLine();
} }
for (RendererListener listener : rendererListeners) { for (var listener : rendererListeners) {
listener.complete(); listener.complete();
} }
@ -464,14 +461,34 @@ public class JavaScriptTarget implements TeaVMTarget, TeaVMJavaScriptHost {
private void printWrapperStart(SourceWriter writer) throws IOException { private void printWrapperStart(SourceWriter writer) throws IOException {
writer.append("\"use strict\";").newLine(); writer.append("\"use strict\";").newLine();
for (String key : controller.getEntryPoints().keySet()) { printUmdStart(writer);
writer.append("var ").append(key).append(";").softNewLine(); writer.append("function($rt_globals,").ws().append("$rt_exports)").appendBlockStart();
} }
writer.append("(function($rt_globals)").ws().append("{").newLine();
private void printUmdStart(SourceWriter writer) throws IOException {
writer.append("(function(root,").ws().append("module)").appendBlockStart();
writer.appendIf().append("typeof define").ws().append("===").ws().append("'function'")
.ws().append("&&").ws().append("define.amd)").appendBlockStart();
writer.append("define(['exports'],").ws().append("function(exports)").ws().appendBlockStart();
writer.append("module(root,").ws().append("exports);").softNewLine();
writer.outdent().append("});").softNewLine();
writer.appendElseIf().append("typeof exports").ws()
.append("===").ws().append("'object'").ws().append("&&").ws()
.append("typeof exports.nodeName").ws().append("!==").ws().append("'string')").appendBlockStart();
writer.append("module(global,").ws().append("exports);").softNewLine();
writer.appendElse();
writer.append("module(root,").ws().append("root);").softNewLine();
writer.appendBlockEnd();
writer.outdent().append("}(typeof self").ws().append("!==").ws().append("'undefined'")
.ws().append("?").ws().append("self")
.ws().append(":").ws().append("this,")
.ws();
} }
private void printWrapperEnd(SourceWriter writer) throws IOException { private void printWrapperEnd(SourceWriter writer) throws IOException {
writer.append("})(this);").newLine(); writer.outdent().append("}));").newLine();
} }
private void printStats(Renderer renderer, int totalSize) { private void printStats(Renderer renderer, int totalSize) {

View File

@ -47,6 +47,26 @@ public class SourceWriter implements Appendable, LocationProvider {
return this; return this;
} }
public SourceWriter appendBlockStart() throws IOException {
return ws().append("{").indent().softNewLine();
}
public SourceWriter appendBlockEnd() throws IOException {
return outdent().append("}").softNewLine();
}
public SourceWriter appendIf() throws IOException {
return append("if").ws().append("(");
}
public SourceWriter appendElseIf() throws IOException {
return outdent().append("}").ws().append("else ").appendIf();
}
public SourceWriter appendElse() throws IOException {
return outdent().append("}").ws().append("else").appendBlockStart();
}
public SourceWriter append(int value) throws IOException { public SourceWriter append(int value) throws IOException {
return append(String.valueOf(value)); return append(String.valueOf(value));
} }

View File

@ -52,6 +52,6 @@ final class TestJsEntryPoint {
} }
} }
@JSBody(params = "e", script = "window.teavmException = e") @JSBody(params = "e", script = "teavmException = e")
private static native void saveJavaException(String e); private static native void saveJavaException(String e);
} }